From d6f40dd4fdd71570be6983e04021d919a8819cc8 Mon Sep 17 00:00:00 2001 From: Fabian Montero Date: Sat, 24 Aug 2024 18:50:57 -0600 Subject: [PATCH] still wip --- sys/srv/authelia.nix | 138 ---------------- sys/srv/authelia/authelia-authrequest.conf | 32 ++++ sys/srv/authelia/authelia-location.conf | 20 +++ sys/srv/authelia/default.nix | 174 +++++++++++++++++++++ sys/srv/bepasty.nix | 4 - sys/srv/default.nix | 1 + sys/srv/forgejo.nix | 4 - sys/srv/jellyfin.nix | 4 - sys/srv/jitsi.nix | 15 +- sys/srv/kuma.nix | 4 - sys/srv/mediawiki.nix | 5 +- sys/srv/net.nix | 4 + sys/srv/vaultwarden.nix | 4 - 13 files changed, 238 insertions(+), 171 deletions(-) delete mode 100644 sys/srv/authelia.nix create mode 100644 sys/srv/authelia/authelia-authrequest.conf create mode 100644 sys/srv/authelia/authelia-location.conf create mode 100644 sys/srv/authelia/default.nix diff --git a/sys/srv/authelia.nix b/sys/srv/authelia.nix deleted file mode 100644 index 90f3c3b..0000000 --- a/sys/srv/authelia.nix +++ /dev/null @@ -1,138 +0,0 @@ -{ - lib, - pkgs, - ... -}: -with lib; { - #TODO: no poner authelia-main en todo lado, usar config (o let o no sé) - systemd.services.authelia-main = { - preStart = '' - mkdir -p /var/trust/authelia-main/ - chown authelia-main:authelia-main /var/trust/authelia-main/ - chmod 700 /var/trust/authelia-main/ - - [ -f /var/trust/authelia-main/jwt-secret ] || { - "${pkgs.openssl}/bin/openssl" rand -base64 32 > /var/trust/authelia-main/jwt-secret - chown authelia-main:authelia-main /var/trust/authelia-main/jwt-secret - chmod 600 /var/trust/authelia-main/jwt-secret - } - [ -f /var/trust/authelia-main/storage-encryption-file ] || { - "${pkgs.openssl}/bin/openssl" rand -base64 32 > /var/trust/authelia-main/storage-encryption-file - chown authelia-main:authelia-main /var/trust/authelia-main/storage-encryption-file - chmod 600 /var/trust/authelia-main/storage-encryption-file - } - [ -f /var/trust/authelia-main/session-secret-file ] || { - "${pkgs.openssl}/bin/openssl" rand -base64 32 > /var/trust/authelia-main/session-secret-file - chown authelia-main:authelia-main /var/trust/authelia-main/session-secret-file - chmod 600 /var/trust/authelia-main/session-secret-file - } - ''; - - serviceConfig.LoadCredential = [ - "jwt-secret:/var/trust/authelia-main/jwt-secret" - "storage-encryption-file:/var/trust/authelia-main/storage-encryption-file" - "session-secret-file:/var/trust/authelia-main/session-secret-file" - ]; - }; - - services = { - nginx = { - virtualHosts."auth.posixlycorrect.com" = { - enableACME = true; - forceSSL = true; - }; - }; - - authelia.instances.main = { - enable = true; - # config based on https://github.com/authelia/authelia/blob/master/config.template.yml - settings = { - secrets = { - jwtSecretFile = "/var/trust/authelia-main/jwt-secret"; - storageEncryptionKeyFile = "/var/trust/authelia-main/storage-encryption-file"; - sessionSecretFile = "/var/trust/authelia-main/session-secret-file"; - }; - - theme = "dark"; - default_2fa_method = "totp"; - server = { - disable_healthcheck = true; - port = 9091; - host = "localhost"; - address = "tcp://:9091/"; - }; - # tls settings not modified https://github.com/authelia/authelia/blob/master/config.template.yml#L53 - log = { - level = "info"; - format = "text"; - }; - telemetry.enabled = false; - totp = { - disable = false; - issuer = "https://getaegis.app/ or whatever you prefer"; - # default values assumed https://github.com/authelia/authelia/blob/master/config.template.yml#L181 - }; - webauthn = { - disable = false; - # default values assumed: https://github.com/authelia/authelia/blob/master/config.template.yml#L231 - }; - duo_api.disable = true; - # identity_validation default values assumed: https://github.com/authelia/authelia/blob/master/config.template.yml#L266 - authentication_backend.file = { - path = "/var/trust/authelia-main/users_database.yml"; #TODO: - password.algorithm = "argon2"; - password_policy.zxcvbn = { - enable = true; - min_score = 3; - }; - }; - access_control = { - default_policy = "deny"; - rules = [ - { - domain = "auth.posixlycorrect.com"; - policy = "bypass"; - } - { - domain = "meet.posixlycorrect.com"; - policy = "bypass"; - } - ]; - }; - session = { - cookies = { - name = "posixlycorrect_session"; - domain = "auth.posixlycorrect.com"; - authelia_url = "https://auth.posixlycorrect.com"; - same_site = "lax"; - - # see https://github.com/authelia/authelia/blob/master/config.template.yml#L756 - inactivity = "5 minutes"; - expiration = "1 hour"; - remember_me = "1 month"; - }; - - # see https://github.com/authelia/authelia/blob/master/config.template.yml#L774 - name = "authelia_session"; - same_site = "lax"; - inactivity = "5m"; - expiration = "1h"; - remember_me = "1M"; - }; - - regulation = { - max_retries = 3; - find_time = "2 minutes"; - ban_time = "5 minutes"; - }; - - storage.local.path = "/var/trust/authelia-main/db.sqlite3"; #TODO: - - # TODO: - #notifier.smtp = { - # - #}; - }; - }; - }; -} 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..1eb2f37 --- /dev/null +++ b/sys/srv/authelia/default.nix @@ -0,0 +1,174 @@ +{ + 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; + # 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"; + address = "tcp://localhost:9091/"; #TODO: user unix socket + 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.enabled = false; + totp = { + disable = false; + issuer = "https://getaegis.app/ or whatever you prefer"; + # default values assumed https://github.com/authelia/authelia/blob/master/config.template.yml#L181 + }; + webauthn = { + disable = false; + # default values assumed: https://github.com/authelia/authelia/blob/master/config.template.yml#L231 + }; + duo_api.disable = true; + # identity_validation default values assumed: https://github.com/authelia/authelia/blob/master/config.template.yml#L266 + authentication_backend.file = { + path = "/var/trust/authelia-main/users_database.yml"; #TODO: + password.algorithm = "argon2"; + password_policy.zxcvbn = { + enable = true; + min_score = 3; + }; + }; + access_control = { + default_policy = "deny"; + rules = [ + { + domain = "auth.posixlycorrect.com"; + policy = "bypass"; + } + { + domain = "meet.posixlycorrect.com"; + policy = "bypass"; + } + ]; + }; + session = { + cookies = { + name = "posixlycorrect_session"; + domain = "auth.posixlycorrect.com"; + authelia_url = "https://auth.posixlycorrect.com"; + default_redirection_url = "https://posixlycorrect.com"; + same_site = "lax"; + + # see https://github.com/authelia/authelia/blob/master/config.template.yml#L756 + inactivity = "5 minutes"; + expiration = "1 hour"; + remember_me = "1 month"; + }; + + # see https://github.com/authelia/authelia/blob/master/config.template.yml#L774 + name = "authelia_session"; + same_site = "lax"; + inactivity = "5m"; + expiration = "1h"; + remember_me = "1M"; + }; + + regulation = { + max_retries = 3; + find_time = "2 minutes"; + ban_time = "5 minutes"; + }; + + storage.local.path = "/var/trust/authelia-main/db.sqlite3"; #TODO: + + # TODO: + #notifier.smtp = { + # + #}; + }; + }; + }; + }; +} 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}"; }; };