diff --git a/sys/srv/authelia/authelia-authrequest.conf b/sys/srv/authelia/authelia-authrequest.conf new file mode 100644 index 0000000..858815e --- /dev/null +++ b/sys/srv/authelia/authelia-authrequest.conf @@ -0,0 +1,32 @@ +## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource. +auth_request /internal/authelia/authz; + +## 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 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-Email $email; +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; + +## 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.posixlycorrect.com/' with their external authelia URL. +# error_page 401 =302 https://auth.posixlycorrect.com/?rd=$target_url; \ No newline at end of file diff --git a/sys/srv/authelia/authelia-location.conf b/sys/srv/authelia/authelia-location.conf new file mode 100644 index 0000000..e8052c4 --- /dev/null +++ b/sys/srv/authelia/authelia-location.conf @@ -0,0 +1,20 @@ +## Virtual endpoint created by nginx to forward auth requests. +location /internal/authelia/authz { + ## Essential Proxy Configuration + internal; + proxy_pass http://localhost:9091/api/authz/auth-request; + + ## 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; + + ## Advanced Proxy Configuration TODO: maybe reducir estos timeouts? + send_timeout 5m; +} \ No newline at end of file diff --git a/sys/srv/authelia/default.nix b/sys/srv/authelia/default.nix new file mode 100644 index 0000000..f30386e --- /dev/null +++ b/sys/srv/authelia/default.nix @@ -0,0 +1,169 @@ +{ + lib, + pkgs, + ... +}: +with lib; { + options = { + services.nginx.virtualHosts = mkOption { + type = with lib.types; + attrsOf ( + submodule + ( + {config, ...}: { + options = { + enableAuthelia = mkOption { + default = false; + type = bool; + }; + }; + config = mkIf config.enableAuthelia { + extraConfig = '' + include ${./authelia-authrequest.conf}; + include ${./authelia-location.conf}; + ''; + }; + } + ) + ); + }; + }; + + config = { + systemd.services.authelia-main.before = ["nginx.service"]; + + services = { + nginx = { + recommendedProxySettings = true; + recommendedTlsSettings = true; + commonHttpConfig = '' + ## Headers + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Forwarded-URI $request_uri; + proxy_set_header X-Forwarded-Ssl on; + + ## Basic Proxy Configuration + client_body_buffer_size 128k; + 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_cache_bypass $cookie_session; + proxy_no_cache $cookie_session; + proxy_buffers 64 256k; + + ## Trusted Proxies Configuration + ## Please read the following documentation before configuring this: + ## https://www.authelia.com/integration/proxies/nginx/#trusted-proxies + # set_real_ip_from 10.0.0.0/8; + # set_real_ip_from 172.16.0.0/12; + # set_real_ip_from 192.168.0.0/16; + # set_real_ip_from fc00::/7; + real_ip_header X-Forwarded-For; + real_ip_recursive on; + ''; + virtualHosts."auth.posixlycorrect.com" = { + enableACME = true; + forceSSL = true; + locations = { + "/" = { + proxyPass = "http://localhost:9091"; #TODO: hacer que eso estĂ© en alguna config o en algĂșn let + }; + "= /api/verify" = { + proxyPass = "http://localhost:9091"; + }; + "= /api/authz/" = { + proxyPass = "http://localhost:9091"; + }; + }; + }; + }; + + authelia.instances.main = { + enable = true; + package = pkgs.unstable.authelia; + # config based on https://github.com/authelia/authelia/blob/master/config.template.yml + secrets = { + jwtSecretFile = "/var/trust/authelia-main/jwt-secret"; + storageEncryptionKeyFile = "/var/trust/authelia-main/storage-encryption-file"; + sessionSecretFile = "/var/trust/authelia-main/session-secret-file"; + }; + settings = { + theme = "dark"; + default_2fa_method = "totp"; + server = { + disable_healthcheck = true; + port = 9091; + host = "localhost"; + endpoints.authz.auth-request.implementation = "AuthRequest"; + }; + # tls settings not modified https://github.com/authelia/authelia/blob/master/config.template.yml#L53 + log = { + level = "info"; + format = "text"; + }; + telemetry.metrics.enabled = false; + totp = { + disable = false; + issuer = "https://getaegis.app/ or whatever you prefer"; + }; + webauthn = { + disable = false; + }; + duo_api.disable = true; + authentication_backend.file = { + path = "/var/lib/authelia-main/users_database.yml"; + password.algorithm = "argon2"; + }; + password_policy.zxcvbn = { + enabled = true; + min_score = 3; + }; + access_control = { + default_policy = "deny"; + rules = [ + { + domain = "auth.posixlycorrect.com"; + policy = "bypass"; + } + { + domain = "meet.posixlycorrect.com"; + policy = "bypass"; + } + ]; + }; + session = { + name = "posixlycorrect_session"; + same_site = "lax"; + inactivity = "5m"; + expiration = "1h"; + remember_me = "1M"; + cookies = [ + { + name = "posixlycorrect_session"; + domain = "posixlycorrect.com"; + authelia_url = "https://auth.posixlycorrect.com"; + default_redirection_url = "https://posixlycorrect.com"; + same_site = "lax"; + inactivity = "5 minutes"; + expiration = "1 hour"; + remember_me = "1 month"; + } + ]; + }; + + regulation = { + max_retries = 3; + find_time = "2 minutes"; + ban_time = "5 minutes"; + }; + + storage.local.path = "/var/lib/authelia-main/db.sqlite3"; + + # TODO: usar smtp + notifier.filesystem = { + filename = "/tmp/trash.txt"; + }; + }; + }; + }; + }; +} diff --git a/sys/srv/bepasty.nix b/sys/srv/bepasty.nix index 964dbec..cfcc88b 100644 --- a/sys/srv/bepasty.nix +++ b/sys/srv/bepasty.nix @@ -9,10 +9,6 @@ with lib; { virtualHosts."send.posixlycorrect.com" = { enableACME = true; forceSSL = true; - extraConfig = '' - proxy_headers_hash_max_size 512; - proxy_headers_hash_bucket_size 128; - ''; locations."/" = { proxyPass = "http://127.0.0.1:8989"; }; diff --git a/sys/srv/default.nix b/sys/srv/default.nix index 61ccd14..de92f8d 100644 --- a/sys/srv/default.nix +++ b/sys/srv/default.nix @@ -17,5 +17,6 @@ with lib; { ./jellyfin.nix ./msmtp.nix ./kuma.nix + ./authelia ]; } diff --git a/sys/srv/forgejo.nix b/sys/srv/forgejo.nix index 4651285..2464514 100644 --- a/sys/srv/forgejo.nix +++ b/sys/srv/forgejo.nix @@ -16,10 +16,6 @@ with lib; { virtualHosts."git.posixlycorrect.com" = { enableACME = true; forceSSL = true; - extraConfig = '' - proxy_headers_hash_max_size 512; - proxy_headers_hash_bucket_size 128; - ''; locations."/".proxyPass = "http://localhost:9170"; }; }; diff --git a/sys/srv/jellyfin.nix b/sys/srv/jellyfin.nix index 07c8896..3a607b3 100644 --- a/sys/srv/jellyfin.nix +++ b/sys/srv/jellyfin.nix @@ -9,10 +9,6 @@ with lib; { virtualHosts."stream.posixlycorrect.com" = { enableACME = true; forceSSL = true; - extraConfig = '' - proxy_headers_hash_max_size 512; - proxy_headers_hash_bucket_size 128; - ''; locations."/" = { proxyPass = "http://localhost:8096"; }; diff --git a/sys/srv/jitsi.nix b/sys/srv/jitsi.nix index 42c62e6..c4a011d 100644 --- a/sys/srv/jitsi.nix +++ b/sys/srv/jitsi.nix @@ -10,15 +10,12 @@ with lib; { enableACME = true; forceSSL = true; extraConfig = '' - proxy_headers_hash_max_size 512; - proxy_headers_hash_bucket_size 128; - - ssl_verify_depth 1; - ssl_verify_client on; - ssl_client_certificate ${../../pki/gatekeeper_ca.pem}; - if ($ssl_client_verify != "SUCCESS") { - return 403; - } + ssl_verify_depth 1; + ssl_verify_client on; + ssl_client_certificate ${../../pki/gatekeeper_ca.pem}; + if ($ssl_client_verify != "SUCCESS") { + return 403; + } ''; }; }; diff --git a/sys/srv/kuma.nix b/sys/srv/kuma.nix index e698c04..60594c8 100644 --- a/sys/srv/kuma.nix +++ b/sys/srv/kuma.nix @@ -9,10 +9,6 @@ with lib; { virtualHosts."status.posixlycorrect.com" = { enableACME = true; forceSSL = true; - extraConfig = '' - proxy_headers_hash_max_size 512; - proxy_headers_hash_bucket_size 128; - ''; locations."/" = { proxyPass = "http://127.0.0.1:4456"; }; diff --git a/sys/srv/mediawiki.nix b/sys/srv/mediawiki.nix index d07bd80..d976d40 100644 --- a/sys/srv/mediawiki.nix +++ b/sys/srv/mediawiki.nix @@ -10,10 +10,7 @@ with lib; { virtualHosts."wiki.posixlycorrect.com" = { enableACME = true; forceSSL = true; - extraConfig = '' - proxy_headers_hash_max_size 512; - proxy_headers_hash_bucket_size 128; - ''; + enableAuthelia = true; }; }; mediawiki = { diff --git a/sys/srv/net.nix b/sys/srv/net.nix index 9d22700..f49edaf 100644 --- a/sys/srv/net.nix +++ b/sys/srv/net.nix @@ -26,6 +26,10 @@ with lib; { recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; + commonHttpConfig = '' + proxy_headers_hash_max_size 512; + proxy_headers_hash_bucket_size 128; + ''; logError = "/var/log/nginx/error.log"; clientMaxBodySize = "99M"; virtualHosts = { diff --git a/sys/srv/vaultwarden.nix b/sys/srv/vaultwarden.nix index 2b8dc91..0d81ee7 100644 --- a/sys/srv/vaultwarden.nix +++ b/sys/srv/vaultwarden.nix @@ -9,10 +9,6 @@ with lib; { virtualHosts."vault.posixlycorrect.com" = { enableACME = true; forceSSL = true; - extraConfig = '' - proxy_headers_hash_max_size 512; - proxy_headers_hash_bucket_size 128; - ''; locations."/".proxyPass = "http://127.0.0.1:${toString config.services.vaultwarden.config.ROCKET_PORT}"; }; };