diff --git a/.sops.yaml b/.sops.yaml index 9d48334..7ef9c1a 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,6 +1,8 @@ keys: - &lander 4BE1257015580BAB9F4B9D5FCA5B1C34E649BF92 - &wodan age15m0pdv8mkt4aue8wjay9k4endyymtka5je3gc2t63dgamfzh9vts7774hh + - &db-01 age1a5zz4cyda0aqh0hgf8svpyh9ktwy6z5x3gnnu5ysvpvek9rn03csx7dyqn + - &hosting-01 age18g4z53ykxzq35dsjq3a2np4f88xwat0kwtax229l3zn0ykhlpvqqy8fgtv - &mail-01 age1u2a7wakgsyct6ed7ah2pksymh7jjl08ankedeyl5pa5jcs8r0uks02jpza creation_rules: @@ -16,6 +18,20 @@ creation_rules: - *wodan pgp: - *lander + - path_regex: hosts/common/servers/secrets.yam?l$ + key_groups: + - age: + - *db-01 + - *hosting-01 + - *mail-01 + pgp: + - *lander + - path_regex: hosts/hosting-01/secrets.yam?l$ + key_groups: + - age: + - *hosting-01 + pgp: + - *lander - path_regex: hosts/mail-01/secrets.yam?l$ key_groups: - age: diff --git a/flake.nix b/flake.nix index 1b72c2a..7964e7c 100644 --- a/flake.nix +++ b/flake.nix @@ -66,6 +66,13 @@ }; # servers + db-01 = nixpkgs.lib.nixosSystem { + system = "aarch64-linux"; + specialArgs = { inherit inputs outputs; }; + modules = [ + ./hosts/db-01 + ]; + }; hosting-01 = nixpkgs.lib.nixosSystem { system = "aarch64-linux"; specialArgs = { inherit inputs outputs; }; diff --git a/hosts/common/servers/default.nix b/hosts/common/servers/default.nix index 7811bce..f5c94f1 100644 --- a/hosts/common/servers/default.nix +++ b/hosts/common/servers/default.nix @@ -1,4 +1,9 @@ -{ inputs, pkgs, ... }: +{ + config, + inputs, + pkgs, + ... +}: { imports = [ inputs.disko.nixosModules.disko @@ -25,6 +30,21 @@ ]; }; + sops.secrets.tailscale-authkey = { + owner = "root"; + group = "root"; + sopsFile = ./secrets.yaml; + }; + + services.tailscale = { + enable = true; + openFirewall = true; + extraUpFlags = [ + "--login-server=https://headscale.escapeangle.com" + ]; + authKeyFile = config.sops.secrets.tailscale-authkey.path; + }; + nix = { settings = { trusted-users = [ "lander" ]; diff --git a/hosts/common/servers/secrets.yaml b/hosts/common/servers/secrets.yaml new file mode 100644 index 0000000..6bccbee --- /dev/null +++ b/hosts/common/servers/secrets.yaml @@ -0,0 +1,46 @@ +tailscale-authkey: ENC[AES256_GCM,data:qXgDw5Ua+J7XinLap+sco/9lVM/NMaj4Tpy6hlUJ+tcRoiSFVV1dQB1w20tt8/Rg,iv:bvKua+uX8jbfPAD5LwcEX+lDmCQpKImK7bfw9kKeDt4=,tag:J3hI/0BP99yjw6juYX/JSw==,type:str] +sops: + age: + - recipient: age1a5zz4cyda0aqh0hgf8svpyh9ktwy6z5x3gnnu5ysvpvek9rn03csx7dyqn + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFVVNJRFc4S2NOVTdVZGFu + VjVPSXlJcytGTUdSZ2RhZ0UraElweVVVTUZZClF6SWs2NkdnVUdDVmFPUXhDeGE3 + RFJaV1c5QVQ4NEFjWVowU21hL2IyRFUKLS0tIE5rZVQzY1FSYmRWT1JaNDgzZXB1 + bHlYRWF1TWVkTTZ2SzdXbENPc1U2VmcKTPJ3SeHHoA5FOvOUMiWJdcKYGr9aXriZ + DuW/ijGrVV5zELOgXc/vAOSrsE9ZYW83QDXB80NRvOUnRNGyaax5Sg== + -----END AGE ENCRYPTED FILE----- + - recipient: age18g4z53ykxzq35dsjq3a2np4f88xwat0kwtax229l3zn0ykhlpvqqy8fgtv + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUSHZNazl3WVJIL2N6dUx6 + cUVZZCtpZWVnVklkU0FnL2REYkZuc0JPREgwCnFIZ2lyMW1HdjZLNDRpRTczMmJC + eDJLSkw2S0dyWXBSNlpPOTRJU0ZNQ28KLS0tIHErZENXUkJnektyazdFS2FNQ1JU + ZFhhRm92SFpCc042U1p2VkE1a0dOZDAKFZuxY5YkAeINQRX/kcxAxIQMSEa7FATx + 8v8eFMZLCpHH3wS2+CgtAzxxDX4bIMsPhwDa4C1bvtWkGmUg/2R86Q== + -----END AGE ENCRYPTED FILE----- + - recipient: age1u2a7wakgsyct6ed7ah2pksymh7jjl08ankedeyl5pa5jcs8r0uks02jpza + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkZnhqOGtXS1RMY3BaRjdz + M2ViM3c2QzhCbTMvejdaOU9sRHd6M0ZzRHdRCnVmd0xiSUNqOHBaZGFkcmpaRU95 + cW5oMHNycjZJN0RCc25tanJSQ1Q0TmMKLS0tIG9KeTdjdTJ2Vk43Um5BWmZVYlJ0 + SnBFVkJBMk5DdDR0YlpjbHFDVlFDTHMKtjJMgkybidVzSvSCjrdUVgAXjLzhWBv/ + x7nYJp7O5PqKZRcWdmpDp6bNG4+ENrtnMBXw1AwR2iWvlZC9YOtmdw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-02T21:02:01Z" + mac: ENC[AES256_GCM,data:oxLmFXvuLNbdiLFC8BCh8jb1gMctbdJeS88xuv27etLgn0P38KI2G4OFg7T03s/QK26lWvwt/0FSGc6o51p6FZ2KJLL8FtB96x2Q1QaJqNIUmU5WWnaJhQfRxiE+IDJgS4DkFYs8FMQhMorr1X8iVhQhoxpB5qKs7kVARAyF1FU=,iv:qhxdpeZCzEMoKJw5oVI6S1Y2OqpHRo67oI1guC1iRdM=,tag:F/YhPTth3NNtCZ/RVlQF1g==,type:str] + pgp: + - created_at: "2025-07-02T21:01:46Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4DARdpY4woM6wSAQdAVK+ifhksSiXmYzGNYQcv2dZbhYrgQQSsqmIKMfyYuk4w + SEEGAA7mcqg9j4Cd2ozLnsX/3p5q41cdRapC0r4Tx/pW5dhE53g+K1OWkKNoq/1f + 0l4BG9rFb0AiidaQU/A2WcOZ7Idgy4CuimDCVW1j6Th6k3QHkVDdCv4oQRTVc48P + 48VQ2A1jp0gyRQHFbjE1dwUSSvLrFaJu3O7kGz7WuCwAZH25HonUx9ParK18nB+j + =jICO + -----END PGP MESSAGE----- + fp: 4BE1257015580BAB9F4B9D5FCA5B1C34E649BF92 + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/hosts/db-01/default.nix b/hosts/db-01/default.nix new file mode 100644 index 0000000..66bf962 --- /dev/null +++ b/hosts/db-01/default.nix @@ -0,0 +1,47 @@ +{ pkgs, ... }: +{ + imports = [ + ./disk-config.nix + { + _module.args.disks = [ "/dev/sda" ]; + } + + ../common/servers + ]; + + time.timeZone = "Europe/Berlin"; + + networking.hostName = "db-01"; + networking.nameservers = [ "8.8.8.8" ]; + + services.postgresql = { + enable = true; + enableTCPIP = true; + authentication = pkgs.lib.mkOverride 10 '' + #type database dbuser origin-address auth-method + local all all trust + host all all 100.64.0.0/24 trust # trust tailnet + ''; + ensureDatabases = [ + "authelia" + "forgejo" + "lldap" + ]; + ensureUsers = [ + { + name = "authelia"; + ensureDBOwnership = true; + } + { + name = "forgejo"; + ensureDBOwnership = true; + } + { + name = "lldap"; + ensureDBOwnership = true; + } + ]; + }; + + system.stateVersion = "25.05"; +} diff --git a/hosts/db-01/disk-config.nix b/hosts/db-01/disk-config.nix new file mode 100644 index 0000000..aa2e1fa --- /dev/null +++ b/hosts/db-01/disk-config.nix @@ -0,0 +1,52 @@ +{ + lib, + disks ? [ "/dev/sda" ], + ... +}: +{ + disko.devices = { + disk = lib.genAttrs disks (disk: { + device = disk; + type = "disk"; + content = { + type = "gpt"; + partitions = { + boot = { + name = "boot"; + size = "256M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + main = { + size = "100%"; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; # override existing partition + subvolumes = { + "/" = { + mountOptions = [ "compress=zstd" ]; + mountpoint = "/"; + }; + "/home" = { + mountOptions = [ "compress=zstd" ]; + mountpoint = "/home"; + }; + "/nix" = { + mountOptions = [ + "compress=zstd" + "noatime" + ]; + mountpoint = "/nix"; + }; + }; + }; + }; + }; + }; + }); + }; +} diff --git a/hosts/hosting-01/auth/authelia.nix b/hosts/hosting-01/auth/authelia.nix new file mode 100644 index 0000000..582ac88 --- /dev/null +++ b/hosts/hosting-01/auth/authelia.nix @@ -0,0 +1,171 @@ +{ config, lib, ... }: +{ + services = { + authelia.instances.escapeangle = { + enable = true; + + settings = { + theme = "auto"; + + authentication_backend.ldap = { + address = "ldap://localhost:3890"; + base_dn = "dc=escapeangle,dc=com"; + users_filter = "(&({username_attribute}={input})(objectClass=person))"; + groups_filter = "(memberOf={dn})"; + user = "uid=authelia,ou=people,dc=escapeangle,dc=com"; + }; + + access_control = { + default_policy = "deny"; + rules = lib.mkAfter [ + { + domain = "*.escapeangle.com"; + policy = "one_factor"; + } + ]; + }; + + storage.postgres = { + address = "db-01.tailnet.escapeangle.com"; + database = "authelia"; + username = "authelia"; + password = "authelia"; # using peer auth + }; + + session = { + cookies = [ + { + domain = "escapeangle.com"; + authelia_url = "https://auth.escapeangle.com"; + inactivity = "1M"; + expiration = "3M"; + remember_me = "1y"; + } + ]; + }; + + notifier.smtp = { + address = "smtp://mail.escapeangle.com:587"; + username = "authelia@escapeangle.com"; + sender = "authelia@escapeangle.com"; + + }; + + log.level = "info"; + + identity_providers.oidc = { + cors = { + endpoints = [ "token" ]; + allowed_origins_from_client_redirect_uris = true; + }; + + authorization_policies.default = { + default_policy = "one_factor"; + rules = [ + { + policy = "deny"; + subject = "group:lldap_strict_readonly"; + } + ]; + }; + + clients = [ + { + client_id = "forgejo"; + client_name = "Forgejo"; + client_secret = "$pbkdf2-sha512$310000$C696AL9dgf0.yv6VF.jLvA$iNAWSUckoX/6y6yQcfo5FMjICl6D8iAeElIG5AZD5vC8Z8unBcLFR9LcqdMQgsYK3S9DNekQtJpNbbRzXrliDQ"; + public = false; + authorization_policy = "two_factor"; + require_pkce = true; + pkce_challenge_method = "S256"; + redirect_uris = [ "https://git.escapeangle.com/user/oauth2/Authelia/callback" ]; + scopes = [ + "openid" + "email" + "profile" + ]; + response_types = [ "code" ]; + grant_types = [ "authorization_code" ]; + access_token_signed_response_alg = "none"; + userinfo_signed_response_alg = "none"; + token_endpoint_auth_method = "client_secret_basic"; + } + { + client_id = "headscale"; + client_name = "Headscale"; + client_secret = "$pbkdf2-sha512$310000$fvaPyF69vBFs3oG1h4Qa1w$ezdJFynGV6bSA8UzGNangyOcaST7a3.LZ6WkVYeI.Ag5znxPsjmm9U23BL7OBMQWAY75CsvftYJWK5eE8nxi9A"; + public = false; + authorization_policy = "two_factor"; + require_pkce = true; + redirect_uris = [ "https://headscale.escapeangle.com/oidc/callback" ]; + scopes = [ + "openid" + "email" + "profile" + "groups" + ]; + response_types = [ "code" ]; + grant_types = [ "authorization_code" ]; + access_token_signed_response_alg = "none"; + userinfo_signed_response_alg = "none"; + token_endpoint_auth_method = "client_secret_basic"; + } + ]; + }; + }; + + secrets = with config.sops; { + jwtSecretFile = secrets."authelia/jwt_secret".path; + oidcIssuerPrivateKeyFile = secrets."authelia/jwks".path; + oidcHmacSecretFile = secrets."authelia/hmac_secret".path; + sessionSecretFile = secrets."authelia/session_secret".path; + storageEncryptionKeyFile = secrets."authelia/storage_encryption_key".path; + }; + + environmentVariables = with config.sops; { + AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE = + secrets."authelia/lldap_authelia_password".path; + AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = secrets."authelia/smtp_password".path; + }; + }; + }; + + services.nginx.virtualHosts."auth.escapeangle.com" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:9091"; + }; + }; + + sops.secrets = { + "authelia/hmac_secret" = { + owner = "authelia-escapeangle"; + sopsFile = ../secrets.yaml; + }; + "authelia/jwks" = { + owner = "authelia-escapeangle"; + sopsFile = ../secrets.yaml; + }; + "authelia/jwt_secret" = { + owner = "authelia-escapeangle"; + sopsFile = ../secrets.yaml; + }; + "authelia/session_secret" = { + owner = "authelia-escapeangle"; + sopsFile = ../secrets.yaml; + }; + "authelia/storage_encryption_key" = { + owner = "authelia-escapeangle"; + sopsFile = ../secrets.yaml; + }; + "authelia/lldap_authelia_password" = { + owner = "authelia-escapeangle"; + sopsFile = ../secrets.yaml; + }; + "authelia/smtp_password" = { + owner = "authelia-escapeangle"; + sopsFile = ../secrets.yaml; + }; + }; +} diff --git a/hosts/hosting-01/auth/default.nix b/hosts/hosting-01/auth/default.nix new file mode 100644 index 0000000..aab3e21 --- /dev/null +++ b/hosts/hosting-01/auth/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./authelia.nix + ./lldap.nix + ]; +} diff --git a/hosts/hosting-01/auth/lldap.nix b/hosts/hosting-01/auth/lldap.nix new file mode 100644 index 0000000..40cbc57 --- /dev/null +++ b/hosts/hosting-01/auth/lldap.nix @@ -0,0 +1,49 @@ +{ config, ... }: +{ + services = { + lldap = { + enable = true; + settings = { + ldap_base_dn = "dc=escapeangle,dc=com"; + ldap_user_email = "lander@escapeangle.com"; + database_url = "postgresql://lldap@db-01.tailnet.escapeangle.com/lldap"; + }; + environment = { + LLDAP_JWT_SECRET_FILE = config.sops.secrets."lldap/jwt_secret".path; + LLDAP_KEY_SEED_FILE = config.sops.secrets."lldap/key_seed".path; + LLDAP_USER_PASS_FILE = config.sops.secrets."lldap/admin_password".path; + }; + }; + }; + + services.nginx.virtualHosts."users.escapeangle.com" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:${toString config.services.lldap.settings.http_port}"; + }; + }; + + users = { + users.lldap = { + group = "lldap"; + isSystemUser = true; + }; + groups.lldap = { }; + }; + + sops.secrets = { + "lldap/jwt_secret" = { + owner = "lldap"; + sopsFile = ../secrets.yaml; + }; + "lldap/key_seed" = { + owner = "lldap"; + sopsFile = ../secrets.yaml; + }; + "lldap/admin_password" = { + owner = "lldap"; + sopsFile = ../secrets.yaml; + }; + }; +} diff --git a/hosts/hosting-01/default.nix b/hosts/hosting-01/default.nix index cb10578..64043a9 100644 --- a/hosts/hosting-01/default.nix +++ b/hosts/hosting-01/default.nix @@ -2,8 +2,20 @@ inputs, config, pkgs, + lib, ... }: +let + format = pkgs.formats.yaml { }; + settings = lib.recursiveUpdate config.services.headscale.settings { + acme_email = "/dev/null"; + tls_cert_path = "/dev/null"; + tls_key_path = "/dev/null"; + policy.path = "/dev/null"; + oidc.client_secret_path = "/dev/null"; + }; + headscaleConfig = format.generate "headscale.yml" settings; +in { imports = [ ./disk-config.nix @@ -14,6 +26,9 @@ inputs.headplane.nixosModules.headplane ../common/servers + + ./auth + ./git ]; time.timeZone = "Europe/Berlin"; @@ -50,15 +65,6 @@ }; }; - services.nginx.virtualHosts."headscale.escapeangle.com" = { - forceSSL = true; - enableACME = true; - locations."/" = { - proxyPass = "http://localhost:${toString config.services.headscale.port}"; - proxyWebsockets = true; - }; - }; - services.headplane = { enable = true; agent.enable = false; @@ -73,15 +79,22 @@ headscale = { url = "https://headscale.escapeangle.com"; - config_strict = false; + config_path = "${headscaleConfig}"; + config_strict = true; }; + + integration.proc.enabled = true; }; }; - services.nginx.virtualHosts."headplane.escapeangle.com" = { + services.nginx.virtualHosts."headscale.escapeangle.com" = { forceSSL = true; enableACME = true; locations."/" = { + proxyPass = "http://localhost:${toString config.services.headscale.port}"; + proxyWebsockets = true; + }; + locations."/admin" = { proxyPass = "http://127.0.0.1:${toString config.services.headplane.settings.server.port}"; proxyWebsockets = true; }; diff --git a/hosts/hosting-01/git/default.nix b/hosts/hosting-01/git/default.nix new file mode 100644 index 0000000..88f8d6d --- /dev/null +++ b/hosts/hosting-01/git/default.nix @@ -0,0 +1,6 @@ +{ ... }: +{ + imports = [ + ./forgejo.nix + ]; +} diff --git a/hosts/hosting-01/git/forgejo.nix b/hosts/hosting-01/git/forgejo.nix new file mode 100644 index 0000000..d9a57c4 --- /dev/null +++ b/hosts/hosting-01/git/forgejo.nix @@ -0,0 +1,123 @@ +{ config, lib, ... }: +let + cfg = config.services.forgejo; + srv = cfg.settings.server; +in +{ + services.forgejo = { + enable = true; + + database = { + type = "postgres"; + host = "db-01.tailnet.escapeangle.com"; + }; + + lfs.enable = true; + + settings = { + server = { + DOMAIN = "git.escapeangle.com"; + ROOT_URL = "https://${srv.DOMAIN}"; + HTTP_PORT = 3000; + }; + + service = { + DISABLE_REGISTRATION = false; + ALLOW_ONLY_EXTERNAL_REGISTRATION = true; + SHOW_REGISTRATION_BUTTON = false; + }; + + openid = { + ENABLE_OPENID_SIGNIN = false; + ENABLE_OPENID_SIGNUP = true; + WHITELISTED_URIS = "auth.escapeangle.com"; + }; + + storage = { + STORAGE_TYPE = "minio"; + MINIO_ENDPOINT = "daf6ae2391d4d68ecf3c5af2f1540f5c.r2.cloudflarestorage.com"; + MINIO_BUCKET = "forgejo"; + MINIO_LOCATION = "auto"; + MINIO_USE_SSL = true; + MINIO_CHECKSUM_ALGORITHM = "md5"; + }; + + mailer = { + ENABLED = true; + SMTP_ADDR = "mail.escapeangle.com"; + FROM = "forgejo@escapeangle.com"; + USER = "forgejo@escapeangle.com"; + }; + }; + + secrets = { + storage = { + MINIO_ACCESS_KEY_ID = config.sops.secrets."forgejo/access-key-id".path; + MINIO_SECRET_ACCESS_KEY = config.sops.secrets."forgejo/secret-access-key".path; + }; + + mailer = { + PASSWD = config.sops.secrets."forgejo/mailer-password".path; + }; + }; + }; + + systemd.services.forgejo.preStart = '' + auth="${lib.getExe config.services.forgejo.package} admin auth" + + echo "Trying to find existing sso configuration for Authelia"... + set +e -o pipefail + id="$($auth list | grep "Authelia.*OAuth2" | cut -d' ' -f1)" + found=$? + set -e +o pipefail + + if [[ $found = 0 ]]; then + echo Found sso configuration at id=$id, updating it if needed. + $auth update-oauth \ + --id $id \ + --name "Authelia" \ + --provider openidConnect \ + --key forgejo \ + --secret $(tr -d '\n' < ${config.sops.secrets."forgejo/oidc-secret".path}) \ + --auto-discover-url https://auth.escapeangle.com/.well-known/openid-configuration + else + echo Did not find any sso configuration, creating one with name Authelia. + $auth add-oauth \ + --name Authelia \ + --provider openidConnect \ + --key forgejo \ + --secret $(tr -d '\n' < ${config.sops.secrets."forgejo/oidc-secret".path}) \ + --auto-discover-url https://auth.escapeangle.com/.well-known/openid-configuration + fi + ''; + + services.nginx.virtualHosts."git.escapeangle.com" = { + forceSSL = true; + enableACME = true; + extraConfig = '' + client_max_body_size 512M; + ''; + locations."/" = { + proxyPass = "http://localhost:${toString srv.HTTP_PORT}"; + }; + }; + + sops.secrets = { + "forgejo/mailer-password" = { + owner = "forgejo"; + sopsFile = ../secrets.yaml; + }; + "forgejo/oidc-secret" = { + owner = "forgejo"; + sopsFile = ../secrets.yaml; + }; + "forgejo/access-key-id" = { + owner = "forgejo"; + sopsFile = ../secrets.yaml; + }; + "forgejo/secret-access-key" = { + owner = "forgejo"; + sopsFile = ../secrets.yaml; + }; + }; +} diff --git a/hosts/hosting-01/secrets.yaml b/hosts/hosting-01/secrets.yaml new file mode 100644 index 0000000..f08581c --- /dev/null +++ b/hosts/hosting-01/secrets.yaml @@ -0,0 +1,48 @@ +authelia: + hmac_secret: ENC[AES256_GCM,data:BKW1DTLgoGR5Z+lJxIzDugqDaJD4I9YgwPYKvaY3GyLsjZ+A9YmAKrSVIxixjaV465H2dJU1Gy9IFf1fL1IdKw==,iv:u3lN2yXlJ53Q+KHwjKNOUz+wdFziFGRPYrWYPvPbp3M=,tag:CslQZLCB40KfPnsGNBQh3w==,type:str] + jwt_secret: ENC[AES256_GCM,data:4FvIOu8GFTLfQ5n5owAd2gJxLmamyZaciJFDXG50SADIaS/BTK0e1wp7lw6YvPFmNnpzfUcQ7jxmYatNU1wZjg==,iv:gEu/hOsKAGdXBbvXZAEqaE1a5mIYD4eS80WlxRbDLaM=,tag:2IfNyPZUTsnilPD9a1GBCw==,type:str] + jwks: ENC[AES256_GCM,data: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,iv:rN0J3aCHpdRSEyx8K8FQCuTvEBaKDV6+pQWZVB55wxo=,tag:StQWyn4EpUtRyium8Skg+Q==,type:str] + lldap_authelia_password: ENC[AES256_GCM,data:OdW47EXFf9AwDtnjy1BBeHnMA8Jj4SBjLIGMF8BR4sw=,iv:DWqLJ9Hu16H5mMUxDSEi78W9kdaPmGmtvd2PamM1NqY=,tag:1Im3hAAd17PWdSjH+w+LKA==,type:str] + session_secret: ENC[AES256_GCM,data:Xw4K4DA1jyJGg6nzLLv2y9j4vwoodHeZhL35DrNB9BKBx8Muv99BbPIvz3lDZ2xB2p+aqB+3WzY/8jgkANlgAg==,iv:CxMkaBnOty4Q7dFH6Kn5v3L+F5QWJP9TR86xVRXCKN8=,tag:KIa2BsNn5gzDiaOxEZ2LQg==,type:str] + smtp_password: ENC[AES256_GCM,data:L7yf9g01QysPSirr9IK5ITvnl6XNQONv1AS91zrkf7E=,iv:fRJ9ZIviravLvgdl5BigSoOjUiAfQGB492/bS5GvhL8=,tag:DLhVqa/2Xn/vdChz4/ZixA==,type:str] + storage_encryption_key: ENC[AES256_GCM,data:hl5ciFqrQzv0iGE1RlIFctDMIFv7QOrVqZfqWBuHqn792i8ewwQxWnWQOxglsxSmvZwWYK9c2FcPJuMBWsYlpg==,iv:FBJXZQeenoV84wGCDinerifofKMSqJIY9qw0o3qUmeY=,tag:cymRnw2Jp+VaOo/lhX1C8Q==,type:str] +lldap: + jwt_secret: ENC[AES256_GCM,data:9h7XljbIrLxK3ekcAP8dZTAwlx8u/2eLqdfRHhHn+Lwj/sav3QNmqgfee9pyHhaoLvgZKWwKr7I+ijLZtOpIgQ==,iv:+VZUqDTy9EOm65ATJ6fPGeyA6aR043VmvXTzVmeMH+o=,tag:8nyYCrwoZADmt05EgldymA==,type:str] + key_seed: ENC[AES256_GCM,data:gt3jgAk4upREudd1HYXCSsqg6E3Vuq0WbiDSTjYZF+QJXa7cdq0Ke8XrjJVCAokbp7ZZsf1MMo/wEkr47HXggg==,iv:7xrMZrWNpsAtBoOx4p3RjaEJru9jXrdXkR/Z8rA4vwI=,tag:oLbli5vAw8X00eiD87sSCA==,type:str] + admin_password: ENC[AES256_GCM,data:RBibqepGrtX8hKVzdcAtTbsVZg==,iv:RLu3JkhtmCfXVwZA8EX/dVgqqu7hWURIWNSywlW/8ew=,tag:jQXYo2a+Idh1AIfr1687gg==,type:str] +oidc_clients: + headscale: + hashed: ENC[AES256_GCM,data:WWD40bVWbFAp1qIDHjKhc2UWTtCuVPaMrU+NqHBwvc7CDQ9CiUIb19vGqvUR11dhg5XyX2TgDRKuwRusA6Sv7cKjiLS7Mh1vkPi2rthYt/v5xKK0dvdI7VykkJQ1PV15VWumVuswhHuTu1FHweTA9dnMyaz4fE3cWerb22SRbT7LCko=,iv:psR3lnD/kO5+WTqcmTKbuOFfnd/YNZFR0qYYMGYgzhM=,tag:QPgfxytRP+X6mgtRqZngBg==,type:str] + unhashed: ENC[AES256_GCM,data:UPW0HSB712h6sjSHdEf3dsJ5iwodNyzutxPQy4tFdSrjoBRxzr0ad8uzOsMtqGX7fEt7w88QQBNNvki/9IXRfV07vQMAcOnN,iv:EvdLrxdhq6nLBc8zaGmImRRiuHZJ/R0cofuoj4RNUHI=,tag:R0DLJ0fngr4MRx38bZ9WWA==,type:str] +forgejo: + access-key-id: ENC[AES256_GCM,data:LVlYp0wQ1gxTg/RVG9HduoVpiUKLNCzwmX6DX7dQrv0=,iv:Oh4CA1Gp+nSWmQhX5OGI9vf3yC1XU/VpV/oveQefz8c=,tag:RguhY9Zh2q+cZ8rthhVcrw==,type:str] + secret-access-key: ENC[AES256_GCM,data:nODhpLuUG2uaaSDbULstA6YFHIRPg3mvgIyHqRB0Vj11f5X0TMuLjp3Feq7UeV9DbQWyjDVtEsRg9VGIywrD/Q==,iv:hsStXkXVLBkEWtBP6dY6z2mwfzv3t4L6E+Ht/18KE4E=,tag:vQBUwqXq41bbQ/+aSUIQJg==,type:str] + mailer-password: ENC[AES256_GCM,data:sO8Tt1Smwcr8hME/zYs118DiUfbcmhKnT2FCyjyUZfId4cHfjvxHuqZIHvBSlec27sbCmxRBHeCJ3Can6IFCAA==,iv:kPmW6oFCRBEzKScpFrW3Z0xhFCRg+MpiA9qJozakHjE=,tag:9xCVN/wFjN8Kl95PSC9aXA==,type:str] + oidc-secret: ENC[AES256_GCM,data:NeLfEXssdP5f4ff1uz3RwURw+OWAm3QgYz/EPpWb1aE+vIDIhPigiPem1+NrVvdBQ5uysL3VdnLtJPxwppcouoT7VGJkcog+,iv:eCl4I7EC7GTeQNSthk5QrMqNl1B9qvGGxQTspjD+LEU=,tag:qyPKf7E5xNmUI913Fb8n8A==,type:str] +sops: + age: + - recipient: age18g4z53ykxzq35dsjq3a2np4f88xwat0kwtax229l3zn0ykhlpvqqy8fgtv + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFcjltUDdJL2lrMEZvRk5Q + TFErTFYrYTlvbTc3OHd0SWZEQTNuQzFIZ2dJClNhcWRmWkh4MXlaeklJdEh0K3lp + MG9hMHU1OWcybUhKM1QrclBBeGpOaWcKLS0tIEZMYVNKN1ZxQmxHcFRUQ1BVUUtq + NW9CUkJQbis1NmpyU0xrb3J4UVNKTDgKsPFnlQBa8LGm6s8uZsUXq9RIt4WzzROc + mz9dEVq/R54xvjMRltgzZyu54BWWOQYgkZUEhOnDoqwVnA7XwGGYtA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-08T11:59:46Z" + mac: ENC[AES256_GCM,data:16ZM1HZoWkXsZIILHdYY9yMIrPa6GO8VB2pWTCAuZb61qpIdDI1fYqim3w7MO8d0BtpJI7TvhE7kXuGncOo6IUZtpUiV+JkDUtpFor9yx4l58DAO2PwrjTo3vk/hQ/GNllTtAizt78O4i+VpZNgvP4C+h3GBQeJ3guBRpYZZ9ZY=,iv:enIftwBsWNU73kPUXfeHpbGW3Vo9kGHc5II0KdW4Ma8=,tag:okQ3XkJO4oGfWRJatS2AYA==,type:str] + pgp: + - created_at: "2025-07-06T18:28:35Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hF4DARdpY4woM6wSAQdAzqZHVo7/A+jPwSx63zOXGJ9tCF7qYDvu/Eg7HxCxhFYw + P277CjIB3imnRHCms18b+ze9Bv3A2wNdBGlbqhG/Z1R10NPx3nJydnYCUdZtbKFk + 0lwBTahORz3Ha2RqKTiuUGhncNtz+4U5i08sbLCzp/1Vc32RAwEGtfbMFosS4Uf2 + qCFsnEICj2MuXgBtub5Mw2zpDIFkjaIRGLPohiJy+Yrp9J14hWuZmC79lwGRgQ== + =umk4 + -----END PGP MESSAGE----- + fp: 4BE1257015580BAB9F4B9D5FCA5B1C34E649BF92 + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/hosts/mail-01/default.nix b/hosts/mail-01/default.nix index 669e6ad..51384ef 100644 --- a/hosts/mail-01/default.nix +++ b/hosts/mail-01/default.nix @@ -37,7 +37,19 @@ in sopsFile = ./secrets.yaml; }; + sops.secrets.mail-password-authelia = { + owner = "root"; + group = "root"; + sopsFile = ./secrets.yaml; + }; + + sops.secrets.mail-password-forgejo = { + owner = "root"; + group = "root"; + sopsFile = ./secrets.yaml; + }; mailserver = { + enable = true; fqdn = "mail.escapeangle.com"; domains = [ "escapeangle.com" ]; @@ -54,6 +66,14 @@ in "escapeangle.com" ]; }; + + "authelia@escapeangle.com" = { + hashedPasswordFile = config.sops.secrets.mail-password-authelia.path; + }; + + "forgejo@escapeangle.com" = { + hashedPasswordFile = config.sops.secrets.mail-password-forgejo.path; + }; }; extraVirtualAliases = { diff --git a/hosts/mail-01/secrets.yaml b/hosts/mail-01/secrets.yaml index 3788d21..d36843c 100644 --- a/hosts/mail-01/secrets.yaml +++ b/hosts/mail-01/secrets.yaml @@ -1,9 +1,7 @@ mail-password-lander: ENC[AES256_GCM,data:6A0pw04sdzAAE2dakrGt68OkYzMFzeY1fKBAAIcO6PF1Sbna+6JbdIjikuN7ucdEGC+cPBpHNaWM8ZuZ,iv:LC4WSSAWW4uEFGHiDiZG5Q1mQgQnp28WngFyE4sECI8=,tag:gcDe1+PX9Zbe7Uu6RXJ8Ng==,type:str] +mail-password-authelia: ENC[AES256_GCM,data:pbI48v40B8Sehrl28HuZKEdw0nK4pmn7O8FveQzCh/C5+kkbg1QBG6facY58+mvsHXJ5pBZNfPp9uAV9,iv:zZkwl+dDzY0ynun0Pgm5lVB+YZIGFnGr/nNTRE9IgHc=,tag:KmuBl1E8/80yvzP9IAGlnw==,type:str] +mail-password-forgejo: ENC[AES256_GCM,data:arHdupQdSSJgVzcjJdYZ3gB51VfdABk8VNa9tuc9ayerfoOCPn7ydt8eS/qg7XX5fKsH+/5h4q9N/Etw,iv:cc+mqg0ETTikuwXC/i8vKea2k7Ph9Dx7fQOb2iHAOk8=,tag:/bxU7tArkKtv33HPeyxauA==,type:str] sops: - kms: [] - gcp_kms: [] - azure_kv: [] - hc_vault: [] age: - recipient: age1u2a7wakgsyct6ed7ah2pksymh7jjl08ankedeyl5pa5jcs8r0uks02jpza enc: | @@ -14,8 +12,8 @@ sops: bG9hd3RXaERsYU5RaCtiOVYrcFlvam8Ky3iq96BO4uMiYLpZ903UCJYfByQIMtI5 YNDVMgIqVI9vVDq1BnPqyOssHJ7FO69i+BUSSrjqZKsyAjknqPmvoA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-01-17T23:47:07Z" - mac: ENC[AES256_GCM,data:aY/fxm82ypgW5Js6d2m4+xWX/mb1quNt8VSIATsvXOlQTrFHWBJr0ZoI1ZvgkAYDNrgqBm9iCBq9KzM+Uvin+LnuH1EPkjMtoIdTPK8z2pHcHlcHJec9sTG7WHHqCzvVQIXFC7ht4nYvzDJbS5nJBgEVaTGDx7jFyq7oJglvyP0=,iv:ysG15QRfWkqUMPf7IYnQoGvI9H0yuZEM2OiwXneGKNM=,tag:oIfsso9FVLCTzd8X+6sUQA==,type:str] + lastmodified: "2025-07-08T10:48:10Z" + mac: ENC[AES256_GCM,data:8BkeK7uMlWWulKvr1aEcKDpDsHntIVTIz37qePaSSby3zOVu6agc4VwNVNk4tbCLvuXJS+ULPUltkAfh9qffsFJe5X+Jd7ZnvEd5IBMJGdWDDtP1iYSMgga9aYfl/hE030xSo6Utblprf2KGw+KpHEeCViFvU6+oJFqTB/Vwekc=,iv:97YBIUh9HjLIwoGFB1oDiLC6OqwRK1POeksDxE+Ierc=,tag:ZBBb4k5tJdqI/HcZCfKoLg==,type:str] pgp: - created_at: "2025-01-17T23:46:22Z" enc: |- @@ -29,4 +27,4 @@ sops: -----END PGP MESSAGE----- fp: 4BE1257015580BAB9F4B9D5FCA5B1C34E649BF92 unencrypted_suffix: _unencrypted - version: 3.9.2 + version: 3.10.2