Reverse Proxy Apache2

Hey,

So I have enabled --webservice-enable-forever-token=true and generate the issue-forever-token and I have added it to the header:


SSLProxyEngine On
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes On

# Add Authorization header
<IfModule mod_headers.c>
    RequestHeader set Authorization "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXAiOiJBY2Nlc3NUb2tlbiIsInNpZCI6ImZvcmV2ZXItdG9rZW4iLCJmYW0iOiJ0ZW1wb3JhcnkiLCJJhdWQiOiJodHRwczovL2R1cGxpY2F0aSJ9.m_5g4z-odWqozmndCwK-teGMx5V0nzC_n-GuevNm6X0"
</IfModule>

ProxyPass "/api" "http://localhost:8200/api"
ProxyPass "/customized" "http://localhost:8200/customized"
ProxyPass "/img" "http://localhost:8200/img"
ProxyPass "/ngax" "http://localhost:8200/ngax"
ProxyPass "/oem" "http://localhost:8200/oem"
ProxyPass "/package" "http://localhost:8200/package"
ProxyPassReverse "/api" "http://localhost:8200/api"
ProxyPassReverse "/ngax" "http://localhost:8200/ngax"
ProxyPass "/notifications" "ws://localhost:8200/notifications"

Until here everything is fine… I did removed then --webservice-enable-forever-token=true and started the server manually. So on the IP which is not proxied I can login normally but on the domain which is behind the proxy it gives me this error:

{Error: "Authorization failed due to missing cookie.", Code: 401}
Code
: 
401
Error
: 
"Authorization failed due to missing cookie."

What to do and what do you suggest? it is the latest canary version of Duplicati: duplicati-2.1.0.107_canary_2025-01-17-linux-x64-gui.deb

Debian 12 bookworm.

Thanks.

Not an expert in apache, but can you try this?

ProxyPassReverseCookieDomain localhost:8200  externaldomain.com
ProxyPassReverseCookiePath / /

https://httpd.apache.org/docs/2.4/mod/mod_proxy.html

1 Like

That is a problem with the UI then. Since it assumes it needs to authenticate, it will do so, even if it is not required. There is no good way to work around this, but I will add it to the list of issues for the new UI.

Thanks for you reply, no luck with this actually.

Thanks, how long do you think this will take to find a solution to this?

I would think we can get login sequence sorted this week, and then hopefully also get a new canary build out this week as well.

Actually… I was thinking that it is possible to hack this if you want.

The problem is that the client wants to send:

POST /api/v1/auth/refresh

So if you proxy that call to a file so it returns 200 and this content:

{
    "AccessToken": "bogus-token"
}

This should make it work. A bit of a duct-tape solution :fearful:

I tried this as well and it failed. it does return the

{
    "AccessToken": "bogus-token"
}

But, it fails to create cookies and that way am still getting the login dialog:

Connection to server was rejected due to invalid authentication.

Log in again, or re-open the page from the TrayIcon (if applicable)

The cookies are not readable by the script. The cookie is only sent/set via the /api/v1/auth/refresh endpoint. No other endpoint relies on cookies.

You should see in the browser, that after the call to /api/v1/auth/refresh it will call /api/v1/systeminfo with the header Authorization: Bearer bogus-token.

The proxy should then replace the header with the forever token header, and this will cause the call to be authorized by the server.

Can you trace it further with Developer Tools in the browser?

I’m sorry for the late reply tho.

I can share with you the server link, Do you want to see? In DM.

Just tho, the /api/vi/systeminfo return data fine and everything seems fine with that part but still getting that login dialog.

Actually it worked but I needed to give it a fake token instead of writing down bogus-token lol, I missed that.

Okay final update is we have to return the actual Token or the forever-token instead of a bogus-token in /api/v1/auth/refresh. Returning the forever token worked fine but using a fake generated one didn’t work.

Another update on this:

SSLProxyEngine On
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes On

# Add Authorization header
<IfModule mod_headers.c>
    RequestHeader set Authorization "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXV"
</IfModule>
ProxyPass "/api" "http://localhost:8200/api"
ProxyPass "/customized" "http://localhost:8200/customized"
ProxyPass "/img" "http://localhost:8200/img"
ProxyPass "/ngax" "http://localhost:8200/ngax"
ProxyPass "/oem" "http://localhost:8200/oem"
ProxyPass "/package" "http://localhost:8200/package"
ProxyPassReverse "/api" "http://localhost:8200/api"
ProxyPassReverse "/ngax" "http://localhost:8200/ngax"
ProxyPass "/notifications" "ws://localhost:8200/notifications"
ProxyPassReverseCookieDomain localhost:8200  example.domain.com
ProxyPassReverseCookiePath / /

# Enable mod_rewrite
RewriteEngine On

# Match POST requests to /api/v1/auth/refresh and intercept
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} ^/api/v1/auth/refresh$
RewriteRule ^ - [L,R=200]

# Serve static JSON response only for /api/v1/auth/refresh
<Location "/api/v1/auth/refresh">
    Header always set Content-Type "application/json"
    SetEnvIf Request_URI "^/api/v1/auth/refresh$" STATIC_RESPONSE
    ErrorDocument 200 "{\"AccessToken\":\"eyJhbGciOiJIUzI1\"}"

</Location>

This works perfectly but the only issue am currently facing is the authentication not from Duplicati as we already bypassed that one but the Password Protected folders from Apache2.

If I password protect the root folder, then I can access ngax folder without any issue and the password dialog doesn’t show for me.

Manually setting a password-protected dir:

<Location "/">
    AuthType Basic
    AuthName "Restricted Area"
    AuthUserFile /var/.htpasswd
    Require valid-user
</Location>

That will also fail into a loop of requesting me to sign in , I do sign in using the admin/password but still keep requesting more and more so end up in a loop of passwording-protection.

Maybe am wrong?

I think there is perhaps some configuration issue then. The downside of sending the token to the client is that it can be intercepted. Since the forever-token has a long lifetime, that would essentially break security.

It sounds like either the attachment of the token in the proxy config is not working, or the proxy avoids overwriting the bogus token, such that the Duplicati server gets the bogus token and rejects it.

That sounds like a general Apache/Browser issue. Could it be caused by the API being called by XHR requests and this does not use the Basic Auth headers?
In other words, the first page (most likely index.html) asks for credentials, you enter them, and this allows the static pages to load. Then the javascript will call the API, but this does not carry the authentication and fails, asking you for the password again?

To test your scenario, I replaced the forever-token with a fake one and all API Calls failed, But using the forever-token in the header, made the API Calls work again. The only issue is that I did generate a fake token similar to the forever-token through ChatGPT so they have minimal difference, returned it in the Refresh file and tested it to find out the Refresh keeps failing. I’m not sure why is this happening but most likely it is being overridden and rejected by the Duplicati server.

As for this I couldn’t find an explanation could be the one you mentioned… As for anyone else who want to have the same setup, Using SSO (Single Sign-On) with Google bypassed that issue for me :slight_smile:

Only, the refresh without returning the forever-token it doesn’t work. The token seems to expire in a short time and the refresh function just refreshes and renew it, but the forever-token is created to not expire after login. So basically you have to always return that token no matter what.

We are building the logic for handling the proxy situation into the new UI.

1 Like

Yup, I was following that issue on Github, thanks for your effort. May I know when it will be released?

It will be part of the next canary build. Release for that is planned for end of this week, or start of next week depending on the time taken to resolve some minor issues.