From 7da7458a345db546928692a04314a57cfc7fb0d7 Mon Sep 17 00:00:00 2001 From: Jack O'Sullivan Date: Mon, 6 Jun 2022 00:18:24 +0100 Subject: [PATCH] nixos: Working ACME certs --- nixos/boxes/colony/vms/estuary/default.nix | 2 +- nixos/boxes/colony/vms/estuary/dns.nix | 50 ++++++++++++++-- .../colony/vms/shill/containers/middleman.nix | 55 +++++++++++++++++- nixos/modules/firewall.nix | 5 +- nixos/modules/pdns.nix | 3 + nixos/modules/tmproot.nix | 10 ++++ secrets/dhparams.pem.age | Bin 1119 -> 1127 bytes secrets/pdns-file-records.key.age | Bin 0 -> 876 bytes secrets/user-passwd.txt.age | Bin 987 -> 902 bytes secrets/vaultwarden.env.age | 19 +++--- 10 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 secrets/pdns-file-records.key.age diff --git a/nixos/boxes/colony/vms/estuary/default.nix b/nixos/boxes/colony/vms/estuary/default.nix index eebd19f..6872c6a 100644 --- a/nixos/boxes/colony/vms/estuary/default.nix +++ b/nixos/boxes/colony/vms/estuary/default.nix @@ -176,7 +176,7 @@ } table inet nat { chain prerouting { - iifname wan meta l4proto { udp, tcp } th dport domain redirect to :5353 + ${matchInet "meta l4proto { udp, tcp } th dport domain redirect to :5353" "estuary"} } chain postrouting { ip saddr ${lib.my.colony.prefixes.all.v4} masquerade diff --git a/nixos/boxes/colony/vms/estuary/dns.nix b/nixos/boxes/colony/vms/estuary/dns.nix index d5636cc..acc1512 100644 --- a/nixos/boxes/colony/vms/estuary/dns.nix +++ b/nixos/boxes/colony/vms/estuary/dns.nix @@ -13,14 +13,14 @@ let pdns-file-record = pkgs.writeShellApplication { name = "pdns-file-record"; - runtimeInputs = [ pkgs.gnused ]; + runtimeInputs = with pkgs; [ gnused pdns ]; text = '' die() { echo "$@" >&2 exit 1 } usage() { - die "usage: $0 [content]" + die "usage: $0 [content]" } add() { @@ -47,11 +47,14 @@ let dir=/run/pdns/file-records mkdir -p "$dir" - if [ $# -lt 1 ]; then + if [ $# -lt 2 ]; then usage fi + zone="$1" + shift cmd="$1" shift + case "$cmd" in add) add "$@";; @@ -60,11 +63,48 @@ let *) usage;; esac + + # TODO: This feels pretty hacky? + zDat=/var/lib/pdns/bind-zones/"$zone".dat + # shellcheck disable=SC1090 + source "$zDat" + ((serial++)) + sed -i "s/^serial=.*$/serial=$serial/g" "$zDat" + sed "s/@@SERIAL@@/$serial/g" < /etc/pdns/bind-zones/"$zone".zone > /run/pdns/bind-zones/"$zone".zone + pdns_control bind-reload-now "$zone" ''; }; in { config = { + users = { + users = { + "pdns-file-records" = + let + script = pkgs.writeShellScript "pdns-file-records-ssh.sh" '' + read -r -a args <<< "$SSH_ORIGINAL_COMMAND" + exec ${pdns-file-record}/bin/pdns-file-record "''${args[@]}" + ''; + in + { + group = "pdns"; + isSystemUser = true; + shell = pkgs.bashInteractive; + openssh.authorizedKeys.keys = [ + ''command="${script}" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBSvcgbEesOgvKJLt3FLXPaLOcCIuOUYtZXXtEv6k4Yd'' + ]; + }; + }; + }; + + systemd = { + services = { + pdns.preStart = '' + install -d -m 775 /run/pdns/file-records + ''; + }; + }; + services.pdns-recursor = { enable = true; dns = { @@ -164,7 +204,7 @@ in wildcardPtr6Z = wildcardPtr6 ptrDots6; fileRecScript = pkgs.writeText "file-record.lua" '' - local path = "/run/pdns/file-records/" .. qname:toStringNoDot() .. ".txt" + local path = "/run/pdns/file-records/" .. string.lower(qname:toStringNoDot()) .. ".txt" if not os.execute("test -e " .. path) then return {} end @@ -195,8 +235,10 @@ in @ IN ALIAS ${config.networking.fqdn}. + $TTL 3 _acme-challenge IN LUA TXT ${fileRecVal} + $TTL 60 ${intRecords} ''; }; diff --git a/nixos/boxes/colony/vms/shill/containers/middleman.nix b/nixos/boxes/colony/vms/shill/containers/middleman.nix index a727a16..d03f6ee 100644 --- a/nixos/boxes/colony/vms/shill/containers/middleman.nix +++ b/nixos/boxes/colony/vms/shill/containers/middleman.nix @@ -16,7 +16,7 @@ }; }; - configuration = { lib, config, assignments, allAssignments, ... }: + configuration = { lib, pkgs, config, assignments, allAssignments, ... }: let inherit (lib) mkMerge mkIf; inherit (lib.my) networkdAssignment; @@ -29,7 +29,13 @@ secrets = { key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAuvP9DEsffop53Fsh7xIdeVyQSF6tSKrOUs2faq6rip"; - files."dhparams.pem" = {}; + files = { + "dhparams.pem" = {}; + "pdns-file-records.key" = { + owner = "acme"; + group = "acme"; + }; + }; }; firewall = { @@ -44,6 +50,51 @@ network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal; }; + security = { + acme = { + acceptTerms = true; + defaults = { + email = "dev@nul.ie"; + server = "https://acme-staging-v02.api.letsencrypt.org/directory"; + reloadServices = [ "nginx" ]; + dnsResolver = "8.8.8.8"; + }; + + certs = { + "${config.networking.domain}" = { + extraDomainNames = [ + "*.${config.networking.domain}" + ]; + dnsProvider = "exec"; + credentialsFile = + let + script = pkgs.writeShellScript "lego-update-int.sh" '' + case "$1" in + present) + cmd=add;; + cleanup) + cmd=del;; + *) + exit 1;; + esac + + echo "$@" + exec ${pkgs.openssh}/bin/ssh \ + -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ + -i ${config.age.secrets."pdns-file-records.key".path} \ + pdns-file-records@estuary-vm "${config.networking.domain}" "$cmd" "$2" "$3" + ''; + in + pkgs.writeText "lego-exec-vars.conf" '' + EXEC_PROPAGATION_TIMEOUT=60 + EXEC_POLLING_INTERVAL=2 + EXEC_PATH=${script} + ''; + }; + }; + }; + }; + services = { nginx = { enable = true; diff --git a/nixos/modules/firewall.nix b/nixos/modules/firewall.nix index 1f1ca66..49cb193 100644 --- a/nixos/modules/firewall.nix +++ b/nixos/modules/firewall.nix @@ -128,11 +128,10 @@ in table inet nat { chain prerouting { - type nat hook prerouting priority 0; + type nat hook prerouting priority dstnat; } - chain postrouting { - type nat hook postrouting priority 100; + type nat hook postrouting priority srcnat; } } diff --git a/nixos/modules/pdns.nix b/nixos/modules/pdns.nix index 809fb35..ac477d7 100644 --- a/nixos/modules/pdns.nix +++ b/nixos/modules/pdns.nix @@ -156,6 +156,9 @@ in mkdir -p /var/lib/pdns/bind-zones loadZones start ''; + postStart = '' + chmod -R g+w /run/pdns /var/lib/pdns + ''; # pdns reloads existing zones, so the only trigger will be if the zone files themselves change. If any new zones # are added or removed, named.conf will change, in turn changing the overall pdns settings and causing pdns to diff --git a/nixos/modules/tmproot.nix b/nixos/modules/tmproot.nix index b0d6b93..5440e42 100644 --- a/nixos/modules/tmproot.nix +++ b/nixos/modules/tmproot.nix @@ -225,6 +225,16 @@ in my.tmproot.persistence.config.files = concatMap (k: [ k.path "${k.path}.pub" ]) config.services.openssh.hostKeys; }) + (mkIf (config.security.acme.certs != { }) { + my.tmproot.persistence.config.directories = [ + { + directory = "/var/lib/acme"; + mode = "0750"; + user = "acme"; + group = "acme"; + } + ]; + }) (mkIf config.my.build.isDevVM { fileSystems = mkVMOverride { # Hijack the "root" device for persistence in the VM diff --git a/secrets/dhparams.pem.age b/secrets/dhparams.pem.age index 49d2a75ea1487441748d8fbe7db16256f96b6b28..0dde440a963fb5ef6a95bd21f93c9a188beedafb 100644 GIT binary patch delta 1098 zcmV-Q1hxC$27dJRxxTebaOR0S~)j$VrgP{Xn0aLcM2^& zAXqXrH8D9LPEj;fdQU_~L1<7|cT;jJQA$!{X>3e3LNirHFn>cuWJpJJLuzbQF<~-m z3Qa_3FhOl*M{Rd@cuz$+bzxIea(GsDYF15QXE#VSR5Ua+a!_(NVqtGt3N1b$OFwZb zGej+Ca%Ew2Wgsw2ePtkhDo#l}AZsZuN+%&8VkmG;X9_TNcWX&!3N0-yAWl|HR%BR8 zQburVbw^5ZM}JU6Okr78Q#n&GFjz}Md1O{kV?<_cFmy&pa|$M*()J}lb)gEK0Zm@$ z=gsq=2$=1|0X|l22NtoA5zQ6Pc5m0?)6@uQj@42E3yLpz8*$bz#YEFCBabc^^5=UK=448+}_YhO+GJg~2bQ;Z4F~pQk>es&2vz0e!YZ-z+ z_uZEFJRn>h)4k(4JN9XoX#R$tu`}!siMznrk2wpt+=?}a%1`t)nO{PVfJK&2c+zz_ zTUk6WsegrFf;RZ=hGXuRNZ=f>URM!4!D6(fdrTN_x1|Lq*Y8uoB_x~DW^Tcj;#Ptw zJtTa7%;1H*+aKVvf+zConM0>=vYQbdm9Jc{Kxrc*pz9sQn{8u@w!B1Cc>njQzZx#V z+xrIa;<&#TgLoybcS0`#h%Z>i7nH`aU_^WKmwzIHp^7x&-hwGxdJA@A?%|i2mD!wp zl^3nG>{Cz#ihIej3~HuwsrHFWI;YmFWQIV_e3Q|*&59jmeYz^UJ2I%~vD$=pd&)&( zUG)EiYBL~Dc(5}%#W1R9W>=t$EY$96+dnNs?JIo2hZcaXrP~tuY277nF|e}STYOsk zwtubWMAAdZo6Tch8GQ<=d3AWSAzi@JFeD&)(b_=SkhwCu7m8rwE|~DFM~byhIj48D zHNz3~6wnNnl2Q-CJ4a@dbD>e~|^sWsAW)4{QwD1O7Mf< z4&G$mDCZhjpH1a?cJ9i}cAW2wa;iv>n8<|rB>mKF7A0BMjQ||9nSq`smLUXh8AICg zLLB|$y#|-tILN#D(ELlf|5ozT?24C$DN)AY#}AD@b_;Tv60($q?Q#5`s95lAX#vDc Qm(4erA`itH*0=XwVU9BObN~PV delta 1090 zcmV-I1iky`2;T^hEPr}sXK6J~OLTN)Ib~C6D`9ACYC$woR9QAtc56~fZ!tzwNOosU zXI4mfFbXqhL@_aSYB+jnL{l>}WpzPPST|BuWMo=%M^J4;P%mvsYEM{dXiR1}a|$g! zAXqXrH8D9LM>2XVNKZ6RY+7haVl!A#bt`m1OLM&I9F6@RdZ8jSxi@J3N1b$WJD=D zSWzu!a%Ew2WgvV?AZ#EkK{#$rATBItR&;($3QtB^3N0-yAX#x~MKX3YY)eZ?P(gJ^ zIa5JRH*`ZZQh#D_Gb?CyZYyO`adS#_QDjkft~}-ko2Gym6btD=MOTIo;Am zuR|pZE6`#;5`S6wu_{ct2b-0DY9jU8dJx7sLCgZO;bxFQoLoF#1R58D|@9_dxBM! zTSU}r`?pk@rRN{u)exD`E2qQ)GGxw@xTkCwZ%Xs=7X=8F%(k%KL#?JGhnr2+X z&<4Zm8T?&?JMjIm8;<}qQ6OZV=d+ZgKfNL9#eXDuiqr8W0Wf#OV$6g#;ufyLkqy0uLH3BKOYrih449XZ&7nQ^hXnD z^nbLxdbzyNC9Ka$@3I~c-MA!Rw7>~HZ7PI4^9Za{tRMTg$KL!ECZCP5x7DP;6?RRX z4peSrX=~6&5sj)`{$C$_(Q`!<4K?kcJpmMY;z6QW%@~|`n*AMEWY}S!@(eikz_0Lw z3zU@_?~oMyOKM_50yB{m9(&1^R+xMTjDIMdaQRVk!8R|CB2f|eLjiU1Bu`6Q!sQwaz!{;X>l}nc2x?lJKAENoKjEv+?8QTr|*hUff9b1m7zSTZeTB+71D2;0$I!aazlwgb7jv=k!qH8y>= zGeZ|(1X3cLA&4_3O%l1GW8 literal 0 HcmV?d00001 diff --git a/secrets/user-passwd.txt.age b/secrets/user-passwd.txt.age index 17e090938230cc874de63e5dd4fd539b64ff74c4..d05c3bd87f2a38145024eac7ceb86892c69160d5 100644 GIT binary patch literal 902 zcmZ9~%j??&0Kjn^(_yY+Px7N@YnR8bd2PedG`}QG+dP}*anUACleBrKd0u`KrXc)8 zJni5?1P?#Uq*{@C=CR^r&5Irekg& z?Mwhknhe>Ef=HYc169Qhg2KW;)(#&J-~VSj|=Z5KSPa@C!g$`*u{x zhhk-AdJ2u}L5jwL6a@2@q#ATG)k1-yH7=|6=QSHM7n#>*70yxzzGRw*D%$9~(x!Ay zR~#KX2=Ig>)*G;tr!6_sOu$TZ5RZ+LE*K@{wjJa(oRbk)nP2hM02r)SFJ(SdyB?b~? ztm47IlZlW6n^;<*8gW?7@m-hYvi3|fo)5yRhl#gsjB?Dl)`=BB%1OtdxHMLIuh4e< zEc5L~)Y%0)0wnm@5yM%VxXx(PV6HeAmQIbS%71uz^A`-nwg3yoG~WndN3T<;X36Y&wnY@?Q( zpd7uyqP4B#+tLJ<+?V&yKJNYe$NL}r-Me-5r`0Rp?vCi|H?F;X<@C~}A8ud#_4SKK z?f9Qx-ubY&`N>P*@7BHTUr%mdKfCq$cb|Ut^~2s(+3(%0kIXOLds+C6)NX?Jq51-q zT^7H2;l_X8U+CREeM0>C##epqUGNdUeCx*-|2-4#J^tvZUgOF; F=>GhA literal 987 zcmZ9~&CA<#0Kjn%JLMoEA`XQGHkcavq)GGAA}DEI+B8X%w8_)7&tN8LnwO^erAeAJ z(Tjq(iwHXi>cAHmySUqfm-!C}qM~d}WH86niyoYyUKAbPp1a++! zasVP0p8~y{ZAP*@q*se_loJvFTm24ZOlet5(4k^+?!&2Of z(0aNb4?w>xK!K^MHccx>4C~!Gi2@_YmQzPl#lgyIShRgobEvtp^vLUZcBgJhqLoyOm9onHa=`!MU{2)mp9Bn!c*~ z>L}qj%s;8g+oV0O;5r(ojxmK|)VRz=Yo|X>3z!(TWGdY|D(; zutb7tXFLAF#=Yq*oy0zbIN`wI%W!|l1su;ZXu~LVY>(NTR4T4$FBIQT1%sL#iVp?n z)wA)-otIjE=GnOiH%D-|8nf`TA%H_Q7&KFBhQLdQ5wv;^=mvff*r$ zlFfG4lQ}QC)V>qeYcW&+0=P&*j8$I|HsKtKG?nI?RU)bGpkOmtOx_45X*tD`v#>v3KvO*FU;;<@l>h*lTB= fyk)-i#;N-kZ$J3t{FQol_4;3reDmj{=J|gC9W+?p diff --git a/secrets/vaultwarden.env.age b/secrets/vaultwarden.env.age index e729478..9fc3560 100644 --- a/secrets/vaultwarden.env.age +++ b/secrets/vaultwarden.env.age @@ -1,9 +1,12 @@ age-encryption.org/v1 --> ssh-ed25519 Lqn0Yw 8O/4DNOBVj9N2QBh4iAcpQPFYKK884dVYBGii6QvMFs -enBLaFlBILu61uFQwV6v8PyWG0M0JkmSfpk/tztrLls --> X25519 6X2M/VOMrMTIdgg9dRlVQmF2LWq5W53rNLzZ8UAJWVM -xFEKeZD+w68RyK+jlyFB82oQ6a6+FCBmYcjvc/8Wg9M --> uVBC-grease -70cjnfhD0khuuiGtBG7MwE2CSEgmClW9/wQeZhAdOQ4 ---- hykfNiGB0dkhlbOabguSHtVFYtAtlFK6ld7GU8E3+WI -L;s5M%u ӆ3#%5#1gujtc79r^OȸߥɗbcobvÊN郑`R ;6?ʱ!' \ No newline at end of file +-> ssh-ed25519 Lqn0Yw ybVbnUjgm3QGOZPv9A/q6zPXjZbuYe4krqe+qjrkziw +SIEEGlziouUT3pzxw+C7p2IO2sDJ3xmaTrHaDGFgLOs +-> X25519 bq/2lRh9a3BwhwR6o9TXeuXA5AGdtlrQm8/JOyAzUEU +I5xRPDb6rUcNBXqOXefFkO2HvlYIJAG+OFkZygywkqg +-> 0g#WDK-grease .DWBEk* +Vf8DHmVCY3bfTT+CPPm5dELSid+aZJquOxjEccmkZXVKtefHlwLRx6Dh3HT5IZqR +Pl2j/4SQvVf1MrPjtbkMwBhxh9zPZa7WQIBGeF6oB2kl9vyc65lXpaxRSMs2eVsv + +--- /eCT0Rqu+we6CXUSP3dpd+blpQxwOG0t5rDiGfffXPs +F +f~"[%?}1P~ҋ$Nrnh*y _Ʌ!*h\MߑxsFd3u/$9  Р&iv \ No newline at end of file