From 0cf89b0ae4548420bb5f0d13ec5655a166bdad90 Mon Sep 17 00:00:00 2001 From: Rouven Seifert Date: Sun, 11 May 2025 16:49:43 +0200 Subject: [PATCH] caddy: enable dns challenges --- flake.lock | 6 +-- hosts/falkenstein/modules/dns/default.nix | 49 +++++++++++------- .../falkenstein/modules/networks/default.nix | 1 + hosts/fujitsu/modules/jellyfin/default.nix | 2 +- hosts/thinkpad/modules/security/default.nix | 2 - secrets.nix | 3 ++ secrets/falkenstein/acme-dns.age | Bin 0 -> 466 bytes secrets/shared/acme-caddy.age | Bin 0 -> 743 bytes shared/caddy/default.nix | 8 ++- shared/systemd.nix | 2 + 10 files changed, 48 insertions(+), 25 deletions(-) create mode 100644 secrets/falkenstein/acme-dns.age create mode 100644 secrets/shared/acme-caddy.age diff --git a/flake.lock b/flake.lock index 16cdc90..f9281ca 100644 --- a/flake.lock +++ b/flake.lock @@ -92,11 +92,11 @@ ] }, "locked": { - "lastModified": 1746901403, - "narHash": "sha256-2tkRHeNEkaE1x0ayfi30+nrIQv4Nio/NeT8U3i3qeQA=", + "lastModified": 1746905309, + "narHash": "sha256-m5sov8Pcj1PbCF3JmcPNTJC1FJVOEvFB1Bx9o35FiYw=", "owner": "rouven0", "repo": "nixos-caddy-patched", - "rev": "ad2df7623e62ee4595c8f523b30cf6914a2cb6bd", + "rev": "c65d3f16d1f821983a6a8de3aeeb00b05d142272", "type": "github" }, "original": { diff --git a/hosts/falkenstein/modules/dns/default.nix b/hosts/falkenstein/modules/dns/default.nix index 80db608..81c0f2a 100644 --- a/hosts/falkenstein/modules/dns/default.nix +++ b/hosts/falkenstein/modules/dns/default.nix @@ -2,6 +2,12 @@ let secondary = "185.181.104.96"; domain = config.networking.domain; + # fetches all VgetVirtualHosts from the caddy config + getVirtualHosts = hostname: map (name: builtins.substring 0 (builtins.stringLength name - (builtins.stringLength domain + 1)) name) (builtins.attrNames self.nixosConfigurations."${hostname}".config.services.caddy.virtualHosts); + # generate CNAMES from caddy service to host + genCNAMEs = hostname: lib.attrsets.genAttrs (getVirtualHosts hostname) (_label: { CNAME = [ "${hostname}.${domain}." ]; }); + # generate Bind config to allow dynamic updates + genKeyGrants = hostname: builtins.foldl' (x: y: x + "grant caddy name _acme-challenge." + y + ".${domain} txt;\n") "" (lib.lists.remove ":2018" (getVirtualHosts hostname)); zonefile = with dns.lib.combinators; pkgs.writeText "rfive.de.zone.txt" (dns.lib.toString domain { TTL = 3600; SOA = @@ -11,8 +17,8 @@ let { nameServer = "ns.rfive.de."; adminEmail = "hostmaster@rfive.de"; - # serial = lib.strings.toInt (builtins.substring 0 8 self.sourceInfo.lastModifiedDate + toString ((modulo self.sourceInfo.lastModified 86400) / 864)); - serial = 2025051079; + serial = lib.strings.toInt (builtins.substring 0 8 self.sourceInfo.lastModifiedDate + toString ((modulo self.sourceInfo.lastModified 86400) / 864)); + # serial = 2025051143; refresh = 10800; retry = 3600; expire = 604800; @@ -37,12 +43,10 @@ let subdomains = let - # fetches all VgetVirtualHosts from the caddy config - getVirtualHosts = hostname: map (name: builtins.substring 0 (builtins.stringLength name - (builtins.stringLength domain + 1)) name) (builtins.attrNames self.nixosConfigurations."${hostname}".config.services.caddy.virtualHosts); - # generate CNAMES from caddy service to host - genCNAMEs = hostname: lib.attrsets.genAttrs (getVirtualHosts hostname) (_label: { CNAME = [ "${hostname}.${domain}." ]; }); # generate ACME challenge recorsd for every VirtualHost - genACMECNAMEs = hostname: lib.attrsets.genAttrs (getVirtualHosts hostname) (_label: { subdomains._acme-challenge.CNAME = [ "challenge.acme.${domain}." ]; }); + genACMECNAMEs = hostname: lib.attrsets.genAttrs (getVirtualHosts hostname) (_label: { + subdomains._acme-challenge.CNAME = [ "challenge.acme.${domain}." ]; + }); # fuckery to merge the generated attribute lists mergeRecords = recordList: lib.attrsets.mapAttrs (_host: records: lib.attrsets.mergeAttrsList records) (lib.attrsets.zipAttrs recordList); in @@ -62,21 +66,26 @@ let mail = falkenstein; _dmarc.TXT = [ "v=DMARC1; p=none; adkim=s; fo=1; rua=mailto:dmarc@rfive.de; ruf=mailto:dmarc@rfive.de" ]; _domainkey.subdomains.rspamd.TXT = [ "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoirUMubro4nlmY6a8JMwK9QB2agAXiJzexDU/7ba6KCggONfoSTfUHlrM/XeM1GG/9oKpngApxDPP97adJuxc8/EELyo4HjTyYD8GBFZhg0AN7V8IPaJ1o5k6dGDk8ZLh41ZCnlAVWkhVSKs5pYtzkrlJIfUSzyuoe8nuFsVe3QIDAQAB" ]; - "*".subdomains."_acme-challenge".CNAME = [ "challenge.acme.rfive.de" ]; } - (mergeRecords [ - (builtins.removeAttrs (genCNAMEs "nuc") ([ ":2018" ] ++ (builtins.filter (host: lib.strings.hasInfix "vpn" host) (getVirtualHosts "nuc")))) - (builtins.removeAttrs (genACMECNAMEs "nuc") ([ ":2018" ])) - ]) - (mergeRecords [ - (builtins.removeAttrs (genCNAMEs "falkenstein") ([ ":2018" "mail" ])) - (builtins.removeAttrs (genACMECNAMEs "falkenstein") ([ ":2018" "mail" ])) - ]) - (builtins.removeAttrs (genACMECNAMEs "fujitsu") ([ ":2018" ])) + (builtins.removeAttrs (genCNAMEs "nuc") ([ ":2018" ] ++ (builtins.filter (host: lib.strings.hasInfix "vpn" host) (getVirtualHosts "nuc")))) + (builtins.removeAttrs (genCNAMEs "falkenstein") ([ ":2018" "mail" ])) + # (mergeRecords [ + # (builtins.removeAttrs (genCNAMEs "nuc") ([ ":2018" ] ++ (builtins.filter (host: lib.strings.hasInfix "vpn" host) (getVirtualHosts "nuc")))) + # (builtins.removeAttrs (genACMECNAMEs "nuc") ([ ":2018" ])) + # ]) + # (mergeRecords [ + # (builtins.removeAttrs (genCNAMEs "falkenstein") ([ ":2018" "mail" ])) + # (builtins.removeAttrs (genACMECNAMEs "falkenstein") ([ ":2018" "mail" ])) + # ]) + # (builtins.removeAttrs (genACMECNAMEs "fujitsu") ([ ":2018" ])) ]; }); in { + age.secrets.acme-dns = { + file = ../../../../secrets/falkenstein/acme-dns.age; + owner = "named"; + }; services.bind = rec { enable = true; directory = "/var/lib/bind"; @@ -89,6 +98,7 @@ in publish-safety 1d; retire-safety 1d; }; + include "${config.age.secrets.acme-dns.path}"; ''; zones = { "rfive.de" = { @@ -102,7 +112,10 @@ in inline-signing yes; serial-update-method date; update-policy { - grant caddy. name challenge.acme.rfive.de. txt; + grant caddy name _acme-challenge.cinema.vpn.rfive.de. txt; + ${genKeyGrants "nuc"} + ${genKeyGrants "falkenstein"} + ${genKeyGrants "fujitsu"} }; ''; file = "${directory}/rfive.de.zone.txt"; diff --git a/hosts/falkenstein/modules/networks/default.nix b/hosts/falkenstein/modules/networks/default.nix index 3cb693e..ce0f776 100644 --- a/hosts/falkenstein/modules/networks/default.nix +++ b/hosts/falkenstein/modules/networks/default.nix @@ -28,6 +28,7 @@ extraInputRules = '' ip saddr 192.168.0.0/16 tcp dport 19531 accept comment "Allow journald gateway access from local networks" ''; + trustedInterfaces = [ "wg0" ]; }; }; services.resolved = { diff --git a/hosts/fujitsu/modules/jellyfin/default.nix b/hosts/fujitsu/modules/jellyfin/default.nix index 12f003e..4143f10 100644 --- a/hosts/fujitsu/modules/jellyfin/default.nix +++ b/hosts/fujitsu/modules/jellyfin/default.nix @@ -1,6 +1,6 @@ { ... }: let - domain = "media.vpn.rfive.de"; + domain = "cinema.vpn.rfive.de"; in { services.jellyfin = { diff --git a/hosts/thinkpad/modules/security/default.nix b/hosts/thinkpad/modules/security/default.nix index fbbeb97..63b94eb 100644 --- a/hosts/thinkpad/modules/security/default.nix +++ b/hosts/thinkpad/modules/security/default.nix @@ -18,8 +18,6 @@ cue = true; }; }; - # fixes run0 failing to execute - services.systemd-run0 = { }; }; krb5 = { enable = true; diff --git a/secrets.nix b/secrets.nix index fa598a6..7e09836 100644 --- a/secrets.nix +++ b/secrets.nix @@ -3,6 +3,7 @@ let nuc = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6pI2rVvnEMG7oHzA47NRahEKQj99pagrat+Q7pOT2v"; falkenstein = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJxar1P+KXVPzHCaIcGg33Gvog+a5Z8snHWSFqbY3WC6"; rouven = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILkxTuzjS3EswMfj+wSKu9ciRyStvjDlDUXzkqEUGDaP"; + fujitsu = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGC8bPI3sl4l1Xy+/JdfU+3bXJT5sqmFwF+46s1PErr3"; in { # thinkpad @@ -37,7 +38,9 @@ in "secrets/falkenstein/borg/passphrase.age".publicKeys = [ rouven falkenstein ]; "secrets/falkenstein/borg/key.age".publicKeys = [ rouven falkenstein ]; "secrets/falkenstein/dmarc.age".publicKeys = [ rouven falkenstein ]; + "secrets/falkenstein/acme-dns.age".publicKeys = [ rouven falkenstein ]; #shared "secrets/shared/maxmind.age".publicKeys = [ rouven nuc falkenstein ]; + "secrets/shared/acme-caddy.age".publicKeys = [ rouven nuc falkenstein fujitsu ]; } diff --git a/secrets/falkenstein/acme-dns.age b/secrets/falkenstein/acme-dns.age new file mode 100644 index 0000000000000000000000000000000000000000..ea0723a1666cee96837e0875626de014a78f1718 GIT binary patch literal 466 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCSH4Nr3P2vn#rO)N6f zb}BasDa`fu4{@q6HVrf|3Gs|f4odVc%=L6mtJ1e9G|f&9FX!?r4fjaRNKGv&h{!iJ z$@EMzv@A07H8d)=EDbI$bz%d)_%(lW^> z$}F`kDBGzjDksq`)xRRD!l&HS&(I~@$ve}@#g{8TFTBu2-%;P$Kfoo?H^kSgBD=IO zu{6s(FWI8J$gI>QIKVL6%rYglsF+JvS63k?$0#TyqRb-5BQM3PA~Y+*qO!~}!bdwR z(>XOaExXvq(oEYTsK6u5HIPdsc>5#u3po$xNd7%={hYA%;;tX}U2IGk+Y1uf9{#^I zZ}nu|2j^zKC>Kg$wwF<~wY5K^IboLMQ~!{k3Ui&V@E-a$Z9`AC#iiJw9sA}2s zT0yoOPK&L}s_Tj^A%QNJ6SkJ30^$!@lQh$lRl5OD@GBHzk4v2xrw7nvhr7tT_#_H~ z7)VBO8fQZmD#f$aw8tIE!U_!Pn51Jww6l~WDTO`XID|e!-$T+pV8yIFJPPWQ< z8W-FW5r{w_0V;0079d@e7t#a*6?xvv14_1sB_-BpS|H6sxHUxaxqER31<;V4N4ZeQ zP%~`A>9C^)3+FikpbgBichfTkMwP9&IG7d`CL>nzX$j$>PSX!%tLYe7>dy4#P$b@y z0i>`>gd(OT8uJnfmmI3vnG7NZ8Qd98;cA>STt&@{2Ox!KAYY=J0tj*MW@J0^ZrKV1 zgKj}EVn&}6ld$fHfMlqOpwJ#Y2(p6Lo5xZyn4pTi4#a|!39`bKalcxoK}4!Xk(^xh z1$ez<(50o#0+6%Q!BjY+hGmP*X0!ULoGQeUcBTNM6_vrL0@{a$^av%=mg$am&@v+_#zeuEx*K#|^Q`3!~Wh$Jym4_iwL%Ki4d%JC}3H_<{V9LrcAPR_dPd ztyAdO(3`~uc%D?-YVzsUg^R}XX>+RiLy>>9daN?Cx!#jB7G5dA!Kbl(e~hoS7xk8F zJAsK4_twn2?Vi8O^@+u|P2!co>bwq_|EBn(Ll4()cEouZ+Gw~HJbQ9>PO5MBZ#VG- z`Mcf!;Kp&f1vtF)tA3qdVW$_z0xi+j$*qx>ZNrzEM&OxeUq-FlT&+0K)*nDd^8Kxw eKZnl@SO(~WyF;J$D;w#xKefi!?|-~o-Te=BNEDF( literal 0 HcmV?d00001 diff --git a/shared/caddy/default.nix b/shared/caddy/default.nix index bf4aa0d..b9d8118 100644 --- a/shared/caddy/default.nix +++ b/shared/caddy/default.nix @@ -1,15 +1,21 @@ { config, caddy-patched, ... }: { + age.secrets.acme-caddy = { + file = ../../secrets/shared/acme-caddy.age; + owner = "caddy"; + }; services.caddy = { enable = true; - # package = caddy-patched.packages.x86_64-linux.default; + package = caddy-patched.packages.x86_64-linux.default; email = "ca@${config.networking.domain}"; logFormat = "format console"; globalConfig = '' servers { metrics } + import ${config.age.secrets.acme-caddy.path} ''; + virtualHosts.":2018" = { extraConfig = '' metrics diff --git a/shared/systemd.nix b/shared/systemd.nix index c1d9105..d2b90af 100644 --- a/shared/systemd.nix +++ b/shared/systemd.nix @@ -1,6 +1,8 @@ { pkgs, lib, ... }: { + # fixes run0 failing to execute + security.pam.services.systemd-run0 = { }; systemd = { # package = lib.mkDefault (nixpkgs-systemd-256.legacyPackages.x86_64-linux.systemd.override { withHomed = false; });