diff --git a/machines/gerd/services/authelia/authelia-nginx.nix b/machines/gerd/services/authelia/authelia-nginx.nix index 6c3e6b3..9a13625 100644 --- a/machines/gerd/services/authelia/authelia-nginx.nix +++ b/machines/gerd/services/authelia/authelia-nginx.nix @@ -1,81 +1,95 @@ -{ pkgs, ... }: +{ config, lib, pkgs, ... }: # most is taken from this discussion https://www.reddit.com/r/NixOS/comments/15trmac/how_would_you_do_a_nginx_snippets_in_nixos/ # with the following gist https://gist.github.com/aswan89/ee554406c39eb2eeb3126f73f74ab61c +# updated from the following page, with inspiration from the gist +# https://www.authelia.com/integration/proxies/nginx/ let AUTHELIA_HOST = "http://localhost:9091"; autheliaLocation = pkgs.writeText "authelia-location.conf" '' - ## Essential Proxy Configuration - internal; - proxy_pass ${AUTHELIA_HOST}/api/verify; - ## Headers - ## The headers starting with X-* are required. - proxy_set_header X-Original-URL $scheme://$http_host$request_uri; - proxy_set_header X-Original-Method $request_method; - proxy_set_header X-Forwarded-Method $request_method; - 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-For $remote_addr; - proxy_set_header Content-Length ""; - proxy_set_header Connection ""; - ## Basic Proxy Configuration - proxy_pass_request_body off; - proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Timeout if the real server is dead - proxy_redirect http:// $scheme://; - proxy_http_version 1.1; - proxy_cache_bypass $cookie_session; - proxy_no_cache $cookie_session; - proxy_buffers 4 32k; - client_body_buffer_size 128k; - ## Advanced Proxy Configuration - send_timeout 5m; - proxy_read_timeout 240; - proxy_send_timeout 240; - proxy_connect_timeout 240; + ## Virtual endpoint created by nginx to forward auth requests. + location /authelia { + ## Essential Proxy Configuration + internal; + proxy_pass ${AUTHELIA_HOST}/api/verify; + + ## Headers + ## The headers starting with X-* are required. + proxy_set_header X-Original-Method $request_method; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Content-Length ""; + proxy_set_header Connection ""; + + ## Basic Proxy Configuration + proxy_pass_request_body off; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Timeout if the real server is dead + proxy_redirect http:// $scheme://; + proxy_http_version 1.1; + proxy_cache_bypass $cookie_session; + proxy_no_cache $cookie_session; + proxy_buffers 4 32k; + client_body_buffer_size 128k; + + ## Advanced Proxy Configuration + send_timeout 5m; + proxy_read_timeout 240; + proxy_send_timeout 240; + proxy_connect_timeout 240; + } ''; + autheliaRequest = pkgs.writeText "authelia-authrequest.conf" '' - ### goes inside a location block to make the request to authelia ## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource. auth_request /authelia; - ## Set the $target_url variable based on the original request. - ## Comment this line if you're using nginx without the http_set_misc module. - #set_escape_uri $target_url $scheme://$http_host$request_uri; - ## Uncomment this line if you're using NGINX without the http_set_misc module. - set $target_url $scheme://$http_host$request_uri; - ## Save the upstream response headers from Authelia to variables. + + ## Save the upstream metadata response headers from Authelia to variables. auth_request_set $user $upstream_http_remote_user; auth_request_set $groups $upstream_http_remote_groups; auth_request_set $name $upstream_http_remote_name; auth_request_set $email $upstream_http_remote_email; - ## Inject the response headers from the variables into the request made to the backend. + + ## Inject the metadata response headers from the variables into the request made to the backend. proxy_set_header Remote-User $user; proxy_set_header Remote-Groups $groups; - proxy_set_header Remote-Name $name; proxy_set_header Remote-Email $email; - ## If the subreqest returns 200 pass to the backend, if the subrequest returns 401 redirect to the portal. + proxy_set_header Remote-Name $name; + + ## Configure the redirection when the authz failure occurs. Lines starting with 'Modern Method' and 'Legacy Method' + ## should be commented / uncommented as pairs. The modern method uses the session cookies configuration's authelia_url + ## value to determine the redirection URL here. It's much simpler and compatible with the mutli-cookie domain easily. + + ## Modern Method: Set the $redirection_url to the Location header of the response to the Authz endpoint. + # auth_request_set $redirection_url $upstream_http_location; + + ## Modern Method: When there is a 401 response code from the authz endpoint redirect to the $redirection_url. + # error_page 401 =302 $redirection_url; + + ## Legacy Method: Set $target_url to the original requested URL. + ## This requires http_set_misc module, replace 'set_escape_uri' with 'set' if you don't have this module. + # set_escape_uri $target_url $scheme://$http_host$request_uri; + set $target_url $scheme://$http_host$request_uri; + + ## Legacy Method: When there is a 401 response code from the authz endpoint redirect to the portal with the 'rd' + ## URL parameter set to $target_url. This requires users update 'auth.example.com/' with their external authelia URL. error_page 401 =302 https://auth.fricloud.dk/?rd=$target_url; ''; in { - services.nginx.virtualHosts."test.fricloud.dk" = { + mine.shared.lib.authelia.mkProtectedWebsite = virtualHostConfig: lib.recursiveUpdate { forceSSL = true; enableACME = true; - locations."/authelia" = { - recommendedProxySettings = false; - extraConfig = '' - include ${autheliaLocation}; - ''; - }; - locations."/" = { - root = pkgs.writeTextDir "index.html" '' - ACCESS GRANTED! - ''; + extraConfig = "include ${autheliaLocation};"; - extraConfig = '' - include ${autheliaRequest}; - ''; + locations."/" = { + extraConfig = "include ${autheliaRequest};"; }; + } virtualHostConfig; + + services.nginx.virtualHosts."test.fricloud.dk" = config.mine.shared.lib.authelia.mkProtectedWebsite { + locations."/".root = pkgs.writeTextDir "index.html" '' + ACCESS GRANTED! + ''; }; } diff --git a/machines/gerd/services/authelia/default.nix b/machines/gerd/services/authelia/default.nix index eaf3b4f..2576964 100644 --- a/machines/gerd/services/authelia/default.nix +++ b/machines/gerd/services/authelia/default.nix @@ -1,6 +1,6 @@ { imports = [ ./authelia.nix - # ./authelia-nginx.nix + ./authelia-nginx.nix ]; }