From c0616edd38161b81ec1624efba3f024b120ba4c6 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Tue, 18 Feb 2025 20:43:43 +0100 Subject: firefly-iii --- hosts/surtr/default.nix | 2 +- hosts/surtr/dns/default.nix | 2 +- hosts/surtr/dns/keys/firefly.yggdrasil.li_acme | 24 ++++++++++ hosts/surtr/dns/zones/li.yggdrasil.soa | 10 +++- hosts/surtr/firefly.nix | 66 ++++++++++++++++++++++++++ hosts/surtr/tls/tsig_keys/firefly.yggdrasil.li | 24 ++++++++++ hosts/vidhar/default.nix | 2 +- hosts/vidhar/firefly-iii/app_key | 24 ++++++++++ hosts/vidhar/firefly-iii/default.nix | 64 +++++++++++++++++++++++++ hosts/vidhar/network/ruleset.nft | 4 ++ hosts/vidhar/pgbackrest/default.nix | 2 + 11 files changed, 220 insertions(+), 4 deletions(-) create mode 100644 hosts/surtr/dns/keys/firefly.yggdrasil.li_acme create mode 100644 hosts/surtr/firefly.nix create mode 100644 hosts/surtr/tls/tsig_keys/firefly.yggdrasil.li create mode 100644 hosts/vidhar/firefly-iii/app_key create mode 100644 hosts/vidhar/firefly-iii/default.nix diff --git a/hosts/surtr/default.nix b/hosts/surtr/default.nix index 1b33630a..06d3866f 100644 --- a/hosts/surtr/default.nix +++ b/hosts/surtr/default.nix @@ -7,7 +7,7 @@ with lib; tmpfs-root qemu-guest openssh rebuild-machines zfs ./zfs.nix ./dns ./tls ./http ./bifrost ./matrix ./postgresql ./prometheus ./email ./vpn ./borg.nix ./etebase ./immich.nix - ./paperless.nix + ./paperless.nix ./firefly.nix ]; config = { diff --git a/hosts/surtr/dns/default.nix b/hosts/surtr/dns/default.nix index 64864272..eb09e296 100644 --- a/hosts/surtr/dns/default.nix +++ b/hosts/surtr/dns/default.nix @@ -157,7 +157,7 @@ in { ${concatMapStringsSep "\n" mkZone [ { domain = "yggdrasil.li"; addACLs = { "yggdrasil.li" = ["ymir_acme_acl"]; }; - acmeDomains = ["surtr.yggdrasil.li" "yggdrasil.li" "etesync.yggdrasil.li" "immich.yggdrasil.li" "app.etesync.yggdrasil.li" "paperless.yggdrasil.li"]; + acmeDomains = ["surtr.yggdrasil.li" "yggdrasil.li" "etesync.yggdrasil.li" "immich.yggdrasil.li" "app.etesync.yggdrasil.li" "paperless.yggdrasil.li" "firefly.yggdrasil.li"]; } { domain = "nights.email"; addACLs = { "nights.email" = ["ymir_acme_acl"]; }; diff --git a/hosts/surtr/dns/keys/firefly.yggdrasil.li_acme b/hosts/surtr/dns/keys/firefly.yggdrasil.li_acme new file mode 100644 index 00000000..3bd0df26 --- /dev/null +++ b/hosts/surtr/dns/keys/firefly.yggdrasil.li_acme @@ -0,0 +1,24 @@ +{ + "data": "ENC[AES256_GCM,data:cwnYMc/noE+Cv2Vh2KVJLlYdF9ul5XygFuZEEpd7YsP/r+ls+9gYSMDWmkUBC0F1Pt/SlZlIM/dwHs4Bd21B6g+rBAlHz9IJyA9l7Nl4HKwMxlDU6C0Z/l3YdgLhDIPUARHianJqAfJ3xIMIGYVFIqA0haKCgxS6jMG5Z50+FZa0aeF24fweUea56sD3+A/Hg+YdXfOwmqlwNILADLknv+0ZLgp7bpieZCsi4wluuVg8RSj1kPOvHd8Y7GRe2ooyY1ZOyjqIOT9Gz+pOCTTxEQi5uBV1KLju,iv:hI1pD19VjIG//+qLgfc8UYlhr2OLVkOYq3BRRkC9cSE=,tag:I0xFufqFu4zxYHfehv8cNg==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1rmmhetcmllq0ahl5qznlr0eya2zdxwl9h6y5wnl97d2wtyx5t99sm2u866", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2ZG5xaFIzR2s1RUF4aGhx\nb3lwd05nTi81aUJ0T1c4eXFDdmxjQ2pqdEVRCmk5WnhlNm1rc3pDNjJHeEN1YzZ2\nN2sxcHYyaHpBMGo1aXNLSGNuTnhpYjgKLS0tIHdKcGcvYTRuWGxnVGRHa2tTbXVW\nUDhxeHBVVFM1MVdXR05vaE1STlVxaGMKKLG5ZCotuVRYqq1kSgqgA8DfJMg0JqO4\nIEChfbwWc3DQneaLa6393ZWdyDdxLxqvWWTzEOGbK8MFL3rqFW9IFg==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age19a7j77w267z04zls7m28a8hj4a0g5af6ltye2d5wypg33c3l89csd4r9zq", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArV0RzdS9ZUFhqRDRqZFBJ\naUU2WnV3N0tkdDJIMCtzeUhlN283akVkd0FnClJWc0JPZk83K3RmOUxYZ2VHOWdV\ndXh1VVlvdW52WllMakJnK2dYNnY1TmMKLS0tIHVYWm14LzFWNnhPUm9IMnQwTHBN\nZkRYVkFhNEpLOXFYUDVDdHdmbG8yRFkKq8+CSq0ZxDHDU85SRLtZjss+91VG6bVY\nlj1bmGrvSd+hLqCXmHr6UfwYAr71Z+XhoJCj8GKGAXvA147QnEWgTQ==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-18T18:18:41Z", + "mac": "ENC[AES256_GCM,data:UTEZfJkycq+nFG1xpshpDu+9ne13DG6fserHespXh7FFJ43rD7CI9azW0O5U88aVxkPEXe3yA27pldxto6AGGSx0o3fvz9CryN56qB6keZAWY78sQJLD8GoZtkNujgsvSa8F+haMJTznRfOtlJ4bMTmfuO9QSyzvwwgre+2hVrQ=,iv:ndAnqBqBxXE1MNDxuUxoSMOJSAxlB+8UXh2EH1gXZE8=,tag:F/opqs+Zm7tZUNf+APoPaQ==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/hosts/surtr/dns/zones/li.yggdrasil.soa b/hosts/surtr/dns/zones/li.yggdrasil.soa index c77c9b82..d77337c6 100644 --- a/hosts/surtr/dns/zones/li.yggdrasil.soa +++ b/hosts/surtr/dns/zones/li.yggdrasil.soa @@ -1,7 +1,7 @@ $ORIGIN yggdrasil.li. $TTL 3600 @ IN SOA ns.yggdrasil.li. hostmaster.yggdrasil.li ( - 2025021300 ; serial + 2025021800 ; serial 10800 ; refresh 3600 ; retry 604800 ; expire @@ -85,6 +85,14 @@ _acme-challenge.paperless IN NS ns.yggdrasil.li. paperless IN HTTPS 1 . alpn="h2,h3" ipv4hint="202.61.241.61" ipv6hint="2a03:4000:52:ada::" +firefly IN A 202.61.241.61 +firefly IN AAAA 2a03:4000:52:ada:: +firefly IN MX 0 surtr.yggdrasil.li +firefly IN TXT "v=spf1 redirect=surtr.yggdrasil.li" +_acme-challenge.firefly IN NS ns.yggdrasil.li. + +firefly IN HTTPS 1 . alpn="h2,h3" ipv4hint="202.61.241.61" ipv6hint="2a03:4000:52:ada::" + vidhar IN AAAA 2a03:4000:52:ada:4:1:: vidhar IN MX 0 ymir.yggdrasil.li vidhar IN TXT "v=spf1 redirect=yggdrasil.li" diff --git a/hosts/surtr/firefly.nix b/hosts/surtr/firefly.nix new file mode 100644 index 00000000..2d9641b0 --- /dev/null +++ b/hosts/surtr/firefly.nix @@ -0,0 +1,66 @@ +{ config, ... }: + +{ + config = { + security.acme.rfc2136Domains = { + "firefly.yggdrasil.li" = { + restartUnits = ["nginx.service"]; + }; + }; + + services.nginx = { + upstreams."firefly" = { + servers = { + "[2a03:4000:52:ada:4:1::]:9000" = {}; + }; + extraConfig = '' + keepalive 8; + ''; + }; + virtualHosts = { + "firefly.yggdrasil.li" = { + kTLS = true; + http3 = true; + forceSSL = true; + sslCertificate = "/run/credentials/nginx.service/firefly.yggdrasil.li.pem"; + sslCertificateKey = "/run/credentials/nginx.service/firefly.yggdrasil.li.key.pem"; + sslTrustedCertificate = "/run/credentials/nginx.service/firefly.yggdrasil.li.chain.pem"; + extraConfig = '' + charset utf-8; + ''; + + locations = { + "/".extraConfig = '' + proxy_pass http://firefly; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Forwarded-Proto $scheme; + + client_max_body_size 0; + proxy_request_buffering off; + proxy_buffering off; + ''; + }; + }; + }; + }; + + systemd.services.nginx = { + serviceConfig = { + LoadCredential = [ + "firefly.yggdrasil.li.key.pem:${config.security.acme.certs."firefly.yggdrasil.li".directory}/key.pem" + "firefly.yggdrasil.li.pem:${config.security.acme.certs."firefly.yggdrasil.li".directory}/fullchain.pem" + "firefly.yggdrasil.li.chain.pem:${config.security.acme.certs."firefly.yggdrasil.li".directory}/chain.pem" + ]; + }; + }; + }; +} diff --git a/hosts/surtr/tls/tsig_keys/firefly.yggdrasil.li b/hosts/surtr/tls/tsig_keys/firefly.yggdrasil.li new file mode 100644 index 00000000..d03f25c1 --- /dev/null +++ b/hosts/surtr/tls/tsig_keys/firefly.yggdrasil.li @@ -0,0 +1,24 @@ +{ + "data": "ENC[AES256_GCM,data:zpfz2m+93X9kSbUeF8BVJtznD1jGT6yyybCW3PbSzzVLYRUNrKZkkoaCQoKA,iv:sXo1hDebOr1bGlkazvjc29RHuPHu8ihtKj4+EeKgeHU=,tag:nexS/rIUS79Ui63Tg4KFrw==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1rmmhetcmllq0ahl5qznlr0eya2zdxwl9h6y5wnl97d2wtyx5t99sm2u866", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0eElJT1A2dVNhRVRWaFRk\nelF6d2FJRzVEdGk3SzFYWUVSSWZ2blFZYWdvCkMrRnl1d0picFA0R2lpWFprSU84\nYVJDNy80MW9IUnk3YTB6bVNrcXJVMXMKLS0tIGxLN0pWQ0VUbXJrV1RGME9XKzdT\nckFObDg0UnA4amJuSEpHWE83ck1NVFkK1u5xi1utsa6vEXeF+PT4Fe2o2eAi8G+Z\nOZNQ5JcmGEZbqOdlf2VEkOAjzG1OZvAKF2RMCTtx9ABKiR7FThhRwg==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age19a7j77w267z04zls7m28a8hj4a0g5af6ltye2d5wypg33c3l89csd4r9zq", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoU1g3M0VyWVE4QjN4KzFY\nVExjcE5qdExDMS9lT0VnTTQ4RGNSZGxKSWswCi9FWW83OUhIZEZIczhMV21iejVK\nNmVJa1IxMUs1bEIxOUZxbys0aU85Rm8KLS0tIGpxd2FzeVFJQ2JHOTgzWXJzYzVt\nOC9wSGRyeHVqSEhWSVJyU1V1WjhQVDAKUOQMKzwRJ9IYGCNa+KwgIMWzxGNE1wtX\n8yM1XYlEKAc38koZF8K6ZD9jK9pzZZXcHJMYOrwsBUw6+hOl4+Ezug==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-18T18:18:42Z", + "mac": "ENC[AES256_GCM,data:L6xMl54Cq0HTDHpgzwwSyh1Kex2o78n+NT/iyGxxXj7ats3Vv/XIbtVIwS7ZHfoccyldl/kmeqdThTXEp5yT/FyhXDcfVrjrlZiHZ6j8xNH9Tp7gcVeHTrLXy/8JtrsvFRNmtF9rXXceaDSRTfQIY3sgyQF+JKTKeoO2HNo87CI=,iv:wBM1hwPMJJYH1NNtIAp9pfOro9wB2oI3g8fcJU/jkQY=,tag:dkLojSIuZnOGsGVHwHcAng==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/hosts/vidhar/default.nix b/hosts/vidhar/default.nix index 9660931d..90e58b42 100644 --- a/hosts/vidhar/default.nix +++ b/hosts/vidhar/default.nix @@ -4,7 +4,7 @@ with lib; { imports = with flake.nixosModules.systemProfiles; [ - ./zfs.nix ./network ./samba.nix ./dns ./prometheus ./borg ./pgbackrest ./postgresql.nix ./immich.nix ./paperless + ./zfs.nix ./network ./samba.nix ./dns ./prometheus ./borg ./pgbackrest ./postgresql.nix ./immich.nix ./paperless ./firefly-iii tmpfs-root zfs initrd-all-crypto-modules default-locale openssh rebuild-machines build-server diff --git a/hosts/vidhar/firefly-iii/app_key b/hosts/vidhar/firefly-iii/app_key new file mode 100644 index 00000000..b318b9c1 --- /dev/null +++ b/hosts/vidhar/firefly-iii/app_key @@ -0,0 +1,24 @@ +{ + "data": "ENC[AES256_GCM,data:Z/u19vdnY5B76AaQCZOaXGRHTXiAaZ3OlnpEwehK40De6EoTzvs8BzC4/a6KVam5JDjcog==,iv:ZlCNcjQV1brRllTVdfFjhOcDe7sjHIRVbjs/dNT/w0o=,tag:bAtBraAy+i02pyVuhWoXBg==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1rmmhetcmllq0ahl5qznlr0eya2zdxwl9h6y5wnl97d2wtyx5t99sm2u866", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIZEZVVTZLU2VPQmM2Tjk3\nVEUvVitWRjdGRnE2Vm9FVjFhTk1IZ0g1bjJjCjd5dnZNd1VrTVc4QktRM0Z2aFdp\nVlRqLy9BMDV4VGI1SjdmWTFFVFZONG8KLS0tIHRYMGlpalZZUEJFU3c0Z0hXK1lQ\ndnFndWJmTTFjWVAzdkhwN0x6eHVHVmsKVls/ERf4ZfnTqryB6yt5OcjU42RlgAoD\nmMZzuEbhuGBApu2rEKlo4v/AKST6OVIlsiYr0na2W4vlmBOEs8OB1g==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1qffdqvy9arld9zd5a5cylt0n98xhcns5shxhrhwjq5g4qa844ejselaa4l", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCcVVJZWNkMzlYc1lOMzlu\nai82RjhkZm5UYVplV0NNTjZlWm8zcmpCaW1BCnhMaGV5NFNkUUw5ODM5OVZZMUxO\nUUpVTGhtZDM4VzF3WXhTMFpHLytKUzAKLS0tIEZCSVFIODRhRDZuMzFFbSt1YlBI\ndldaZEd6dTBvU2huREhoQ3VNQ2NNdWMKyGuG1tzxIas5G6nlWRkgbxHTOGQ8cLx6\nOw83t98BBfWSZVTuUfHAemn5fPsjRUhsZvEuH70NvQXDRxSvV2nvww==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-18T18:05:57Z", + "mac": "ENC[AES256_GCM,data:7rl6npBWEFeS+IZMLb2+jLcs1d5gSzZyGkCDcrpAbxAB7doAp4vh5DJUEFnAUMtN/iHlwjX71pRNjBHLlYqCs344aaGkcEVMDO/C2m8efuPq+qIi+z372PlM+ekVDXquthvc8fcPhsCWHyso1LTpDjMRqf6kizk0wEtwJj5kOWA=,iv:OEaeQUJ2f0XZidWkttC8Y+WAkDyNkViTNiiDgy5QKr8=,tag:ERsBlT0T3iZvoEWcRhTpPA==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/hosts/vidhar/firefly-iii/default.nix b/hosts/vidhar/firefly-iii/default.nix new file mode 100644 index 00000000..026d4643 --- /dev/null +++ b/hosts/vidhar/firefly-iii/default.nix @@ -0,0 +1,64 @@ +{ config, ... }: +{ + config = { + services.postgresql = { + ensureDatabases = [ "firefly-iii" ]; + ensureUsers = [ + { name = "firefly-iii"; + ensureDBOwnership = true; + } + ]; + }; + + services.firefly-iii = { + enable = true; + enableNginx = true; + group = "firefly-iii"; + virtualHost = "firefly.yggdrasil.li"; + settings = { + DB_CONNECTION = "pgsql"; + DB_DATABASE = "firefly-iii"; + APP_KEY_FILE = config.sops.secrets."firefly-iii_app_key".path; + APP_URL = "https://${config.services.firefly-iii.virtualHost}"; + }; + }; + + services.nginx = { + commonHttpConfig = '' + map $http_x_forwarded_proto $fastcgi_param_https_variable { + default '''; + https 'on'; + } + ''; + virtualHosts.${config.services.firefly-iii.virtualHost} = { + listen = [ + { addr = "[2a03:4000:52:ada:4:1::]"; port = 9000; } + ]; + extraConfig = '' + set_real_ip_from 2a03:4000:52:ada:4::; + ''; + locations."~ \\.php$" = { + extraConfig = '' + fastcgi_param HTTPS $fastcgi_param_https_variable; + ''; + }; + }; + }; + + sops.secrets."firefly-iii_app_key" = { + format = "binary"; + sopsFile = ./app_key; + group = config.services.firefly-iii.group; + mode = "0440"; + restartUnits = [ "firefly-iii-setup.service" "firefly-iii-cron.service" "phpfpm-firefly-iii.service" ]; + }; + + users.groups.${config.services.firefly-iii.group} = {}; + + systemd.services = { + nginx.serviceConfig.SupplementaryGroups = [ config.services.firefly-iii.group ]; + "firefly-iii-setup".serviceConfig.ReadWritePaths = [ "/run/postgresql" ]; + "firefly-iii-cron".serviceConfig.ReadWritePaths = [ "/run/postgresql" ]; + }; + }; +} diff --git a/hosts/vidhar/network/ruleset.nft b/hosts/vidhar/network/ruleset.nft index 3ead8fac..5398cbee 100644 --- a/hosts/vidhar/network/ruleset.nft +++ b/hosts/vidhar/network/ruleset.nft @@ -93,6 +93,7 @@ table inet filter { counter pgbackrest-rx {} counter immich-rx {} counter paperless-rx {} + counter firefly-rx {} counter established-rx {} @@ -123,6 +124,7 @@ table inet filter { counter pgbackrest-tx {} counter immich-tx {} counter paperless-tx {} + counter firefly-tx {} counter tx {} @@ -200,6 +202,7 @@ table inet filter { iifname bifrost tcp dport 2283 ip6 saddr $bifrost_surtr counter name immich-rx accept iifname bifrost tcp dport 28981 ip6 saddr $bifrost_surtr counter name paperless-rx accept + iifname bifrost tcp dport 9000 ip6 saddr $bifrost_surtr counter name firefly-rx accept ct state { established, related } counter name established-rx accept @@ -250,6 +253,7 @@ table inet filter { iifname bifrost tcp sport 2283 ip6 daddr $bifrost_surtr counter name immich-tx accept iifname bifrost tcp sport 28981 ip6 daddr $bifrost_surtr counter name paperless-tx accept + iifname bifrost tcp sport 28981 ip6 daddr $bifrost_surtr counter name firefly-tx accept counter name tx diff --git a/hosts/vidhar/pgbackrest/default.nix b/hosts/vidhar/pgbackrest/default.nix index 1e0828ce..38d68335 100644 --- a/hosts/vidhar/pgbackrest/default.nix +++ b/hosts/vidhar/pgbackrest/default.nix @@ -159,5 +159,7 @@ in { group = "pgbackrest"; mode = "0400"; }; + + systemd.services.postgresql.serviceConfig.SupplementaryGroups = [ "pgbackrest" ]; }; } -- cgit v1.2.3