autobrr / autobrr

Modern, easy to use download automation for torrents and usenet.
https://autobrr.com/introduction
GNU General Public License v2.0
1.43k stars 127 forks source link

500 Internal Server Error when using it behind Authentik #979

Closed chriexpe closed 2 months ago

chriexpe commented 1 year ago

Version Docker running on Unraid, latest flag

Describe the bug After using Authentik's custom NGINX PM config AutoBrr page loads but with this error:

Error: <html> <head><title>500 Internal Server Error</title></head> <body> <center><h1>500 Internal Server Error</h1></center> <hr><center>openresty</center> </body> </html> 

at Ol/<  assets/index-eb9afc7c.js:260  */Wm=VS,function(){var e={}.hasOwnProperty;function t(){for(var r=[],n=0;n<arguments.length;n++){var a=arguments[n];if(a){var s=typeof a;if(s==="string"||s==="number")r.push(a);else if(Array.isArray(a)){if(a.length){var o=t.apply(null,a);o&&r.push(o)}}else if(s==="object"){if(a.toString!==Object.prototype.toString&&!a.toString.toString().includes("[native code]")){r.push(a.toStrin…

What is Authentik Authentik is an identity provider, basically it locks any self hosted service like in my case Home Assistant, Filerun, Deluge etc. behind a more secure login page, the setup is straight foward, you add on Authetik just the service name, login provider that you want to use (in my case proxy provider) and the final https URL of that service (Ex: https://autobrr.example.com/), and on NGINX you paste the config below into "Advanced" > "Custom Nginx Configuration" and it's working. It's pretty generic and most of the time it's the exact setup and code.

Custom Nginx Configuration:

# Increase buffer size for large headers
# This is needed only if you get 'upstream sent too big header while reading response
# header from upstream' error when trying to access an application protected by goauthentik
proxy_buffers 8 16k;
proxy_buffer_size 32k;

# Make sure not to redirect traffic to a port 4443
port_in_redirect off;

location / {
    # Put your proxy_pass to your application here
    proxy_pass          $forward_scheme://$server:$port;
    # Set any other headers your application might need
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection “upgrade”;

    ##############################
    # authentik-specific config
    ##############################
    auth_request     /outpost.goauthentik.io/auth/nginx;
    error_page       401 = @goauthentik_proxy_signin;
    auth_request_set $auth_cookie $upstream_http_set_cookie;
    add_header       Set-Cookie $auth_cookie;

    # translate headers from the outposts back to the actual upstream
    auth_request_set $authentik_username $upstream_http_x_authentik_username;
    auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
    auth_request_set $authentik_email $upstream_http_x_authentik_email;
    auth_request_set $authentik_name $upstream_http_x_authentik_name;
    auth_request_set $authentik_uid $upstream_http_x_authentik_uid;

    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Protocol $scheme;    
    proxy_set_header X-authentik-username $authentik_username;
    proxy_set_header X-authentik-groups $authentik_groups;
    proxy_set_header X-authentik-email $authentik_email;
    proxy_set_header X-authentik-name $authentik_name;
    proxy_set_header X-authentik-uid $authentik_uid;
}

# all requests to /outpost.goauthentik.io must be accessible without authentication
location /outpost.goauthentik.io {
    proxy_pass              https://192.168.0.200:9443/outpost.goauthentik.io;
    # ensure the host of this vserver matches your external URL you've configured
    # in authentik
    proxy_set_header        Host $host;
    proxy_set_header        X-Original-URL $scheme://$http_host$request_uri;
    add_header              Set-Cookie $auth_cookie;
    auth_request_set        $auth_cookie $upstream_http_set_cookie;
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
}

# Special location for when the /auth endpoint returns a 401,
# redirect to the /start URL which initiates SSO
location @goauthentik_proxy_signin {
    internal;
    add_header Set-Cookie $auth_cookie;
    return 302 /outpost.goauthentik.io/start?rd=$request_uri;
    # For domain level, use the below error_page to redirect to your authentik server with the full redirect path
    # return 302 https://192.168.0.200/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
}

Screenshots image

ghost commented 1 year ago

Please paste the error string from the devtools console. Also, look at the server responses in the Network tab. What do they say?

Additionally, have you tried asking in Discord? I think I remember someone saying they used Authelia, might be useful asking them if they noticed any quirks.

chriexpe commented 1 year ago

Thanks, but later I realized this was an issue with browser cache because I was able to access it from another computer... Cleaning the cache solved it and it's working fine now!

zze0s commented 1 year ago

Thanks, but later I realized this was an issue with browser cache because I was able to access it from another computer... Cleaning the cache solved it and it's working fine now!

Then I'll close this as resolved. There's plans to be able to use external auth with autobrr and disable built in auth, but we have a lot of concerns with building a solution that is too easy to disable, which would expose autobrr to the world without auth.

Gylesie commented 1 year ago

Hi, I would like to chime in and confirm that indeed this is still an issue.

I have tracked down that it is most likely caused because of a service worker caching wrong responses and is probably connected to an open issue over at authentik's repo: https://github.com/goauthentik/authentik/issues/5603

Unregistering the service worker and refreshing the page makes autobrr work again.

chriexpe commented 1 year ago

Hi, I would like to chime in and confirm that indeed this is still an issue.

I have tracked down that it is most likely caused because of a service worker caching wrong responses and is probably connected to an open issue over at authentik's repo: goauthentik/authentik#5603

Unregistering the service worker and refreshing the page makes autobrr work again.

Yeah apparently clearing cache only works temporarily, this error always comes back

KyleSanderson commented 1 year ago

Is this still an issue on 1.27.1? I fixed the api route in 1.27 which impacted many other things before that fix. We're still begging for an offline modal for the PWA.

chriexpe commented 1 year ago

Thanks, but later I realized this was an issue with browser cache because I was able to access it from another computer... Cleaning the cache solved it and it's working fine now!

Then I'll close this as resolved. There's plans to be able to use external auth with autobrr and disable built in auth, but we have a lot of concerns with building a solution that is too easy to disable, which would expose autobrr to the world without auth.

You can implement something like this BeryJu/hass-auth-header, if the user on HASSIO is the same as the Authentik's one it bypass login page, if not you have to manually login there too. I use it and works great.

chriexpe commented 1 year ago

Is this still an issue on 1.27.1? I fixed the api route in 1.27 which impacted many other things before that fix. We're still begging for an offline modal for the PWA.

The error code changed, but it's kinda like the issue described by Gylesie, once Authentik's token expires this error happens. image

chriexpe commented 1 year ago

If I open the browser debug, on console there are a bunch of 302 error code like this one: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https:// .com/application/o/authorize/?client_id= &redirect_uri=https%3A%2F%2F .com%2Foutpost.goauthentik.io%2Fcallback%3FX-authentik-auth-callback%3Dtrue&response_type=code&scope=email+ak_proxy+openid+profile&state= . (Reason: CORS request did not succeed). Status code: (null).

On that Authentik code that I pasted on top it mentions this 302 code.

ghost commented 1 year ago

Self-signed cert? CA?

Gylesie commented 1 year ago

I have just noticed that the /outpost.goauthentik.io/start responsible for getting new tokens is also getting cached. It should return a 302 to authentik's instance in order to get a new token. But autobrr service worker just returns 200 page with a title: Oops, looks like there was a little too much brr!

Is the service worker caching 3xx responses as well? Is is feasible to cache only 2xx responses?

After the token expires, essentially any request to autobrr gets 302'd to authentik, to a different domain to get a new token - that requires the Authentik user to be logged in, otherwise they are shown a login form. After that the user should get redirected back to the original page that triggered the 302, however this seems to be kind of broken as per the linked issue.

Is there anything that autobrr can do to handle this? Maybe a way to disable service worker caching altogether?

chriexpe commented 1 year ago

Self-signed cert? CA?

It's CA (you add on SSL Certificates tab on NGINX), but as Gylesie commented, it has something to do on how Autobrr handles session token (because I've never had this issue before with other services behind Authentik).

dmptrluke commented 1 year ago

I can confirm that this issue still occurs when using Authentik with Traefik Forward Auth.

martylukyy commented 1 year ago

Hi everyone!

We opened a pull request with a speculative fix for this problem. It would be very much appreciated, if those who ran into that problem could test our fix.

Be careful when updating to this PR! Your database will receive a schema update so we advise you to stop autobrr first and make a backup of your database, before updating to this PR. https://autobrr.com/installation/transfer-installation#backing-up-your-current-installation

@dmptrluke @Gylesie @chriexpe

Gylesie commented 1 year ago

Hey @martylukyy ! Is there a published docker image with the changes that we could use?

martylukyy commented 1 year ago

Yes sir. Docker tag pr-1088

Gylesie commented 1 year ago

Yes sir. Docker tag pr-1088

Thank you! I can confirm that this in fact fixed the issue. However, to make background fetch requests work after authentik's proxy token expires, I had to make a compromise and disable authentik for API paths that begin with: \/api(?!\/auth).

martylukyy commented 1 year ago

Thank you for testing and for providing the information about the background fetch requests!