Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2FA support #232

Open
RaphMad opened this issue May 30, 2022 · 8 comments
Open

2FA support #232

RaphMad opened this issue May 30, 2022 · 8 comments

Comments

@RaphMad
Copy link

RaphMad commented May 30, 2022

In a ticket for gotify server it was stated that 2FA should be added via external services: gotify/server#461

This works well for the WebUI (I'm personally using traefik + authelia for 2FA in front of gotify).

Unfortunately this is a problem for the Android client application, which is not able to follow the redirect workflow imposed by 2FA.
This seems to be a general problem I've seen for many other selfhosted projects that provide a WebUI + client - when adding external 2FA, usually the client application breaks.

So it seems there are 3 "solutions" to this dilemma:

  • Try to make the client "redirect / 2FA aware" (is this even possible in a good way? since all 2FA stuff happens on the initial http requests and therefore "outside" the API level)
  • Re-think the decision not to have "native" 2FA built into the server (which I guess would be easier to follow/implement client-side)
  • "Just accept" / maybe somewhere document that 2FA + Client app is not supported

Any thoughts on this / am I missing something?

@jmattheis
Copy link
Member

This sounds about right. Like said in the linked issue, I think that adding support for external auth providers should be the simplest solution (in comparison to natively implementing this).

@LeVraiRoiDHyrule
Copy link

Hi, I'm quite new to Gotify but I've used a lot of Authentik lately. Is there news on the subject ? I would love to be able to use Authentik to secure Gotify.

@Sarnog
Copy link

Sarnog commented Feb 15, 2023

In a ticket for gotify server it was stated that 2FA should be added via external services: gotify/server#461

This works well for the WebUI (I'm personally using traefik + authelia for 2FA in front of gotify).

Unfortunately this is a problem for the Android client application, which is not able to follow the redirect workflow imposed by 2FA. This seems to be a general problem I've seen for many other selfhosted projects that provide a WebUI + client - when adding external 2FA, usually the client application breaks.

So it seems there are 3 "solutions" to this dilemma:

  • Try to make the client "redirect / 2FA aware" (is this even possible in a good way? since all 2FA stuff happens on the initial http requests and therefore "outside" the API level)
  • Re-think the decision not to have "native" 2FA built into the server (which I guess would be easier to follow/implement client-side)
  • "Just accept" / maybe somewhere document that 2FA + Client app is not supported

Any thoughts on this / am I missing something?

RaphMad, i have a question. Did you managed to get Gotify working with authelia 2FA in front of it? I'm trying to get it to work, but i can't get any messages to my mobile phone. I use nginx proxy manager with Authelia, the code that i put in advance is:

location /authelia {
    internal;
    set $upstream_authelia http://192.168.1.55:9091/api/verify; #ADD YOUR IP AND PORT OF AUTHELIA
    proxy_pass_request_body off;
    proxy_pass $upstream_authelia;    
    proxy_set_header Content-Length "";
 
    # Timeout if the real server is dead
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
    client_body_buffer_size 128k;
    proxy_set_header Host $host;
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr; 
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Uri $request_uri;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_redirect  http://  $scheme://;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
    proxy_buffers 4 32k;
 
    send_timeout 5m;
    proxy_read_timeout 240;
    proxy_send_timeout 240;
    proxy_connect_timeout 240;
}
 
    location / {
        set $upstream_gotify http://192.168.1.57:3001;  #CHANGE NAME AND IP AND PORT
        proxy_pass $upstream_gotify;  #change name of the service
 
		auth_request /authelia;
		auth_request_set $target_url $scheme://$http_host$request_uri;
		auth_request_set $user $upstream_http_remote_user;
		auth_request_set $groups $upstream_http_remote_groups;
		proxy_set_header Remote-User $user;
		proxy_set_header Remote-Groups $groups;
		error_page 401 =302 https://auth.YOURDOMAIN.COM/?rd=$target_url; #change YOURDOMAIN.COM to your domain
 
		client_body_buffer_size 128k;
 
		proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
 
		send_timeout 5m;
		proxy_read_timeout 360;
		proxy_send_timeout 360;
		proxy_connect_timeout 360;
 
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Forwarded-Host $http_host;
		proxy_set_header X-Forwarded-Uri $request_uri;
		proxy_set_header X-Forwarded-Ssl on;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
		proxy_redirect  http://  $scheme://;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_cache_bypass $cookie_session;
		proxy_no_cache $cookie_session;
		proxy_buffers 64 256k;
 
		set_real_ip_from 192.168.1.0/16;
		real_ip_header X-Forwarded-For;
		real_ip_recursive on;
 
    }

Can you help me out?

@RaphMad
Copy link
Author

RaphMad commented Feb 15, 2023

No, as far as I understood the mobile app needs to be able to understand/support the initial HTTP redirect any 2FA solution implies (browsers are built for this and have no problems) - so no real chance to solve this with authelia config.

Basically still waiting for app support, and its unfortunately one of those topics that can easily be seen as "out of scope" on that side either, so I don't blame the devs if it takes long / they decide to not support this use-case.

@Sarnog
Copy link

Sarnog commented Feb 15, 2023

I just got it working!

In the authelia config:

access_control:

  default_policy: deny
  rules:
    ## bypass rule
    - domain:
        - "gotify.YOURDOMAIN.COM" 
      policy: bypass
      resources:
      - '^/api([/?].*)?$'
    - domain: "gotify.YOURDOMAIN.COM"
      policy: two_factor

And in NginX Proxy Manager under the advance tab:

location /authelia {
    internal;
    set $upstream_authelia http://192.168.1.55:9091/api/verify; #ADD YOUR IP AND PORT OF AUTHELIA
    proxy_pass_request_body off;
    proxy_pass $upstream_authelia;    
    proxy_set_header Content-Length "";
 
    # Timeout if the real server is dead
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
    client_body_buffer_size 128k;
    proxy_set_header Host $host;
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr; 
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Uri $request_uri;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_redirect  http://  $scheme://;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
    proxy_buffers 4 32k;
 
    send_timeout 5m;
    proxy_read_timeout 240;
    proxy_send_timeout 240;
    proxy_connect_timeout 240;
}
 
    location / {
        set $upstream_gotify http://192.168.1.57:3001;  #CHANGE NAME AND IP AND PORT
        proxy_pass $upstream_gotify;  #change name of the service
 
		auth_request /authelia;
		auth_request_set $target_url $scheme://$http_host$request_uri;
		auth_request_set $user $upstream_http_remote_user;
		auth_request_set $groups $upstream_http_remote_groups;
		proxy_set_header Remote-User $user;
		proxy_set_header Remote-Groups $groups;
		error_page 401 =302 https://auth.YOURDOMAIN.COM/?rd=$target_url; #change YOURDOMAIN.COM to your domain
 
		client_body_buffer_size 128k;
 
		proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
 
		send_timeout 5m;
		proxy_read_timeout 360;
		proxy_send_timeout 360;
		proxy_connect_timeout 360;
 
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Forwarded-Host $http_host;
		proxy_set_header X-Forwarded-Uri $request_uri;
		proxy_set_header X-Forwarded-Ssl on;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
		proxy_redirect  http://  $scheme://;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_cache_bypass $cookie_session;
		proxy_no_cache $cookie_session;
		proxy_buffers 64 256k;
 
		set_real_ip_from 192.168.1.0/16;
		real_ip_header X-Forwarded-For;
		real_ip_recursive on;
 
    }

Rebooted authelia and when i want to login to the web GUI, i got 2FA from authelia, and when i sended a message to my android mobile phone, i received it. I'm not home, so i got it externally.

Was searching for this solution for months, so i thought i'll share it with you guys!

@RaphMad
Copy link
Author

RaphMad commented Feb 15, 2023

Ah thats cool, I'll also try it!

@RaphMad
Copy link
Author

RaphMad commented Feb 16, 2023

Hm I think it is still kind of an "out of band" solution - so you logged in on the web GUI (on your phone?) first, and then the app started working?

So it seems the app can handle the case where you are already logged in on the 2FA/Authelia level and you get forwarded to the actual gotify page without intervention.
But did you also test the unauthenticated case where 2FA is required? (I'm asking because this would require the app to somehow render a frame that displays the web page containing the authelia login prompt, which seems very unlikely to already be implemented).

But I'm purely speculating here, haven't had the time to try anything by myself!

@Sarnog
Copy link

Sarnog commented Feb 16, 2023

I noticed that not all messages where working. I couldn't login to the android app neighter, i tried to figure it out and i think i got it completly working now.

I can login to the app as well and all the messages are comming through. If i open the webinterface from gotify in https://gotify.YOURDOMAIN.COM i get authelia 2FA first.

In the authelia config:

access_control:

  default_policy: deny
  rules:
    ## bypass rule
    - domain:
        - "gotify.YOURDOMAIN.COM" 
      policy: bypass
      resources:
      - '^/api([/?].*)?$'
      - '/message'
      - '/health'
      - '/static/'
      - '/favicon.ico'
      - '/'
    - domain: "gotify.YOURDOMAIN.COM"
      policy: two_factor

And in NginX Proxy Manager under the advance tab:

location /authelia {
    internal;
    set $upstream_authelia http://192.168.1.55:9091/api/verify; #ADD YOUR IP AND PORT OF AUTHELIA
    proxy_pass_request_body off;
    proxy_pass $upstream_authelia;    
    proxy_set_header Content-Length "";
 
    # Timeout if the real server is dead
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
    client_body_buffer_size 128k;
    proxy_set_header Host $host;
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr; 
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Uri $request_uri;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_redirect  http://  $scheme://;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
    proxy_buffers 4 32k;
 
    send_timeout 5m;
    proxy_read_timeout 240;
    proxy_send_timeout 240;
    proxy_connect_timeout 240;
}
 
    location / {
        set $upstream_gotify http://192.168.1.57:3001;  #CHANGE NAME AND IP AND PORT
        proxy_pass $upstream_gotify;  #change name of the service
 
		auth_request /authelia;
		auth_request_set $target_url $scheme://$http_host$request_uri;
		auth_request_set $user $upstream_http_remote_user;
		auth_request_set $groups $upstream_http_remote_groups;
		proxy_set_header Remote-User $user;
		proxy_set_header Remote-Groups $groups;
		error_page 401 =302 https://auth.YOURDOMAIN.COM/?rd=$target_url; #change YOURDOMAIN.COM to your domain
 
		client_body_buffer_size 128k;
 
		proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
 
		send_timeout 5m;
		proxy_read_timeout 360;
		proxy_send_timeout 360;
		proxy_connect_timeout 360;
 
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Forwarded-Host $http_host;
		proxy_set_header X-Forwarded-Uri $request_uri;
		proxy_set_header X-Forwarded-Ssl on;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
		proxy_redirect  http://  $scheme://;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_cache_bypass $cookie_session;
		proxy_no_cache $cookie_session;
		proxy_buffers 64 256k;
 
		set_real_ip_from 192.168.1.0/16;
		real_ip_header X-Forwarded-For;
		real_ip_recursive on;
 
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants