diff --git a/hosts/db-01/default.nix b/hosts/db-01/default.nix index dcad648..66bf962 100644 --- a/hosts/db-01/default.nix +++ b/hosts/db-01/default.nix @@ -24,6 +24,7 @@ ''; ensureDatabases = [ "authelia" + "forgejo" "lldap" ]; ensureUsers = [ @@ -31,6 +32,10 @@ name = "authelia"; ensureDBOwnership = true; } + { + name = "forgejo"; + ensureDBOwnership = true; + } { name = "lldap"; ensureDBOwnership = true; diff --git a/hosts/hosting-01/auth/authelia.nix b/hosts/hosting-01/auth/authelia.nix index ce62ea5..582ac88 100644 --- a/hosts/hosting-01/auth/authelia.nix +++ b/hosts/hosting-01/auth/authelia.nix @@ -70,6 +70,26 @@ }; 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"; diff --git a/hosts/hosting-01/default.nix b/hosts/hosting-01/default.nix index 93e63ea..64043a9 100644 --- a/hosts/hosting-01/default.nix +++ b/hosts/hosting-01/default.nix @@ -28,6 +28,7 @@ in ../common/servers ./auth + ./git ]; time.timeZone = "Europe/Berlin"; 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 index f18681c..f08581c 100644 --- a/hosts/hosting-01/secrets.yaml +++ b/hosts/hosting-01/secrets.yaml @@ -14,6 +14,11 @@ 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 @@ -25,8 +30,8 @@ sops: NW9CUkJQbis1NmpyU0xrb3J4UVNKTDgKsPFnlQBa8LGm6s8uZsUXq9RIt4WzzROc mz9dEVq/R54xvjMRltgzZyu54BWWOQYgkZUEhOnDoqwVnA7XwGGYtA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-07-07T11:53:55Z" - mac: ENC[AES256_GCM,data:UneR3XJjMXINseZN8LXmdKiu72gz70Py4NSc+PW/kFtio9BBXazYf/sGwSI5FhPk1IxeA79pptpSJSZsCqjS5AGgrDZg4npYzyNyoop11SVcwNLJgH5qp3xQmy7i7wk8v9qnafRCdsp3eeCYkMgCrGLLVntymY1mV8n1O+UW7FI=,iv:OsxM2DJCtEo/vb6k3pTsnzC+OOc7988WHtE7R8yoiRI=,tag:d01skLc0/EbFFNmOd5sgaw==,type:str] + 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: |- diff --git a/hosts/mail-01/default.nix b/hosts/mail-01/default.nix index 784b5ff..51384ef 100644 --- a/hosts/mail-01/default.nix +++ b/hosts/mail-01/default.nix @@ -43,7 +43,13 @@ in 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" ]; @@ -64,6 +70,10 @@ in "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 c3174b8..d36843c 100644 --- a/hosts/mail-01/secrets.yaml +++ b/hosts/mail-01/secrets.yaml @@ -1,5 +1,6 @@ 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: age: - recipient: age1u2a7wakgsyct6ed7ah2pksymh7jjl08ankedeyl5pa5jcs8r0uks02jpza @@ -11,8 +12,8 @@ sops: bG9hd3RXaERsYU5RaCtiOVYrcFlvam8Ky3iq96BO4uMiYLpZ903UCJYfByQIMtI5 YNDVMgIqVI9vVDq1BnPqyOssHJ7FO69i+BUSSrjqZKsyAjknqPmvoA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-07-07T08:30:12Z" - mac: ENC[AES256_GCM,data:P3BvhaYciRnpiN//kx1mMsyi3ShWbzRAMX/slHyxaCZrzQqqN7WQ/z1/p9PuNpbCjQvrlbbAa2nPXj1EeIGmJ1ek7EXkikYoMRMIIVqJZotOneOhtRwLa5/v4MlKWddx2Fl5aw/968ACf4rCchi235UmfSz5oN287gSAj/r0FVk=,iv:eeenKmnKReWTT1fG65LwgcXWGJXDd57XRBWZL2EemU0=,tag:C60dwWRRn53HzDkJ8LNx/w==,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: |-