From 6119c9a88ac1eff7e1d79580b5371553dc65c7bf Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Sun, 23 Apr 2023 04:22:01 +0100 Subject: [PATCH] dns: got a working letsencrypt setup --- applications/dns.nix | 192 +++++++++++++++++++---------------- machines/_base.nix | 10 +- secrets/dns_certs.secret.age | Bin 1118 -> 1813 bytes secrets/dns_dnskeys.conf.age | 48 +++++---- secrets/secrets.nix | 6 +- secrets/stream_ulfm.age | Bin 3196 -> 3944 bytes 6 files changed, 145 insertions(+), 111 deletions(-) diff --git a/applications/dns.nix b/applications/dns.nix index 85a0cf5..eabdce8 100644 --- a/applications/dns.nix +++ b/applications/dns.nix @@ -73,106 +73,124 @@ in { }; services.bind = { - enable = true; + enable = true; - ipv4Only = true; + ipv4Only = true; - # need to take a look at https://nixos.org/manual/nixos/unstable/#module-security-acme-config-dns - extraConfig = '' - include "/run/agenix/dns_dnskeys"; - ''; + # need to take a look at https://nixos.org/manual/nixos/unstable/#module-security-acme-config-dns + extraConfig = '' + include "/run/agenix/dns_dnskeys"; + ''; - # set the upstream dns servers - # overrides the default dns servers - forwarders = [ - # Cloudflare - "1.1.1.1" - # Google - "8.8.8.8" - # Quad9 - "9.9.9.9" - ]; + # set the upstream dns servers + # overrides the default dns servers + forwarders = [ + # Cloudflare + "1.1.1.1" + # Google + "8.8.8.8" + # Quad9 + "9.9.9.9" + ]; - cacheNetworks = [ - # this server itself - "127.0.0.0/24" - # all of skynet can use this as a resolver - "193.1.99.64/26" - ]; + cacheNetworks = [ + # this server itself + "127.0.0.0/24" + # all of skynet can use this as a resolver + "193.1.99.64/26" + ]; - zones = { - /* - put any other zones above skynet and link to their files like so: + zones = { + /* + put any other zones above skynet and link to their files like so: - example.ie = { - extraConfig = ""; - file = ./dns/example; - master = true; - masters = []; - slaves = [ ]; - }; - - Skynet is handled a bit more dynamically since it is the key one we should focus on - */ - - "skynet.ie" = { - extraConfig = "allow-update { key rfc2136key.skynet.ie.; };"; - # really wish teh nixos config didnt use master/slave + example.ie = { + extraConfig = ""; + file = ./dns/example; master = true; + masters = []; slaves = [ ]; - # need to write this to a file - file = pkgs.writeText "dns_zone_skynet" - # no leading whitespace for first line - '' - $TTL 60 ; 1 minute - ; hostmaster@skynet.ie is an email address that recieves stuff related to dns - @ IN SOA ${cfg.own.nameserver}.skynet.ie. hostmaster.skynet.ie. ( - 2023011701 ; Serial (YYYYMMDDCC) - 600 ; Refresh (10 minutes) - 300 ; Retry (5 minutes) - 2419200 ; Expire (4 weeks) - 3600 ; Minimum (1 hour) - ) - NS ns1.skynet.ie. - NS ns2.skynet.ie. - ; @ stands for teh root domain so teh A record below is where skynet.ie points to - A 193.1.99.76 - MX 5 mail.skynet.ie. - - ; can have multiple mailserves - ;MX 20 mail2.skynet.ie. - - - ; ------------------------------------------ - ; Server Names - ; ------------------------------------------ - - ; External addresses - ; ------------------------------------------ - ${lib.strings.concatMapStrings (x: x + "\n") cfg.records.external} - - - ; this is fixed for now - wintermute A 193.1.101.148 - - - ; internal addresses - ; ------------------------------------------ - ; May come back to this idea in teh future - ; agentjones.int A 172.20.20.1 - - - ; cname's - ; ------------------------------------------ - ${lib.strings.concatMapStrings (x: x + "\n") cfg.records.cname} - - ''; }; + + Skynet is handled a bit more dynamically since it is the key one we should focus on + */ + + "skynet.ie" = { + extraConfig = "allow-update { key rfc2136key.skynet.ie.; };"; + # really wish teh nixos config didnt use master/slave + master = true; + slaves = [ ]; + # need to write this to a file + file = "/etc/dns_custom/dns_zone_skynet"; + # no leading whitespace for first line + }; }; - }; + # creates a folder in /etc for the dns to use + users.users.named = { + createHome = true; + home = "/etc/dns_custom"; + }; + + environment.etc = { + # Creates /etc/dns_custom/dns_zone_skynet + + "dns_custom/dns_zone_skynet" = { + user = "named"; + group = "named"; + + # The UNIX file mode bits + mode = "0644"; + text = + '' + $TTL 60 ; 1 minute + ; hostmaster@skynet.ie is an email address that recieves stuff related to dns + @ IN SOA ${cfg.own.nameserver}.skynet.ie. hostmaster.skynet.ie. ( + 2023011701 ; Serial (YYYYMMDDCC) + 600 ; Refresh (10 minutes) + 300 ; Retry (5 minutes) + 2419200 ; Expire (4 weeks) + 3600 ; Minimum (1 hour) + ) + NS ns1.skynet.ie. + NS ns2.skynet.ie. + ; @ stands for teh root domain so teh A record below is where skynet.ie points to + A 193.1.99.76 + MX 5 mail.skynet.ie. + + ; can have multiple mailserves + ;MX 20 mail2.skynet.ie. + + + ; ------------------------------------------ + ; Server Names + ; ------------------------------------------ + + ; External addresses + ; ------------------------------------------ + ${lib.strings.concatMapStrings (x: x + "\n") cfg.records.external} + + + ; this is fixed for now + wintermute A 193.1.101.148 + + + ; internal addresses + ; ------------------------------------------ + ; May come back to this idea in teh future + ; agentjones.int A 172.20.20.1 + + + ; cname's + ; ------------------------------------------ + ${lib.strings.concatMapStrings (x: x + "\n") cfg.records.cname} + + ''; + }; + }; + }; } \ No newline at end of file diff --git a/machines/_base.nix b/machines/_base.nix index 449925a..a94b718 100644 --- a/machines/_base.nix +++ b/machines/_base.nix @@ -35,16 +35,16 @@ # cannot use our own it seems? nameservers = [ # ns2 - #"193.1.99.109" + "193.1.99.109" # ns1 - #"193.1.99.120" + "193.1.99.120" # Cloudflare - "1.1.1.1" + #"1.1.1.1" # Google - "8.8.8.8" + #"8.8.8.8" # Quad9 - "9.9.9.9" + #"9.9.9.9" ]; }; diff --git a/secrets/dns_certs.secret.age b/secrets/dns_certs.secret.age index 72e41693a9f89476916ecf7e80681c7a2de69749..c233170134327651861ef9ba8e4d50c8f1e321a7 100644 GIT binary patch literal 1813 zcmZY8+sotz0R?dBVyRgbl|`-kFm_oi4qqq9OlC4J6*9Rellyg2!A|bUB$G@sxebW; zAX2fSv?3H&YkgWT$hr?w6hXWdS)o?xu82h~xS(JaR4Vkr`rymwU+_Bz&e=x6S+Mu2 zp*$wV{-L6ZCM^Vr~8;j;B-z(DPcwc3IoK z9spkqW&;^h49RCi?aL2I|)cR zPnnjEkFqg%qU&V|Hb5uxyynW`VHS<({aS~ifZWT8fm8hy>zX|^Vewc&5iW7krAPF; z4N^!(2P{DW?RpX`(_EP984~#OGT)9{!s^1>7Q0izRgSGMqxt`Jlc6Nzlo7dhNG43( zYP{TAyf+CYAwJ14u`BY6|j1G-w)t z5K{$T!L*)XB&>!zNVaN2hW02MdnrF7(a;GDSadNwIFq4<1}W6XAFdZH29es*J5O zt!e;oVePRz-|HINm%YWa!U zo@R_!Pp1u!>AZNXe35o^`1MC1YC>@MWIAqos)3O;p+!Jp`m8Z11wxv!%Y;^yDqCkQ z9wzm^>07_n_h7=I8a7MSn4%mMgF7@1#<;pB_9oNuz>#d|xJJ5T+nfCb)+)qx3`G@^lu_OpcsD zEtusPdt7g@I8I1B%(jeI^dLXP8$R9j04T-6Cfj69IB_c~gfOC1Cix21R*pzPk}D@- zmB2MZ4SgH9bIaJsirwm(-{WK^ZABm`A{x$can`L#!E@ zAo3mDD#>BWH=Qo5mnWabalj}n+&-4&viEso;-yK;))Q#qm^o3<+=irjL`u@>9HVy}K^WL%v~mjS=X+Qr)4F^62yB6JI!ot=#qDhh5-p#@^; znj~wj`ByjYz5V&u?*8n4 zQm)@xShrrjcJE(*aqI1Omv=8*`)G8-diMDzZhrNP>bK5*dgZrY{{0K@MbsBw{n67u zeC-YIeD)FP(TiWd6ezd9@Q&vnde3*uSE0wR{rY3#!`O?r-t@p@zz@b(=}$d=;hA?o z^QcNm?;kNQ{rEdi{NZyS_|q)AuY2s{Z~k}l$|vr5>uooId;4YL TlRx?0^(Vc5T=|!K&$a&msfTbz literal 1118 zcmZY4+pF6I0D$o!cw|LIL_|1Fqnn5;wMm<_sh7=MnkG$~CQZ^b^#Z-*+T3%RG~JMi z58K$>P(;RXJD}S@WJ5QZKFAR~2YfmB*k{jz+18GWmr|i#?<&(pFQd4?K%CJT}Zzf+uzf8^cTfb}eF3CrN=+ z$48ist;qVYF7>2Nm?VZ=$@u&bg>|pufsIUO14b68b`Bbhv&CRs>Iy04kmx*A>Ya$D zy`G8tB_)g|Er!F3Fs8%Ic5TG#A#4Ch){+Q!8qOI`VEg!BScWZBn~>DlDr1UUCsp=1V@Vw?M^wTJhb8nqwR={tw!jC-I?t#Owo4xtv)4Aw`)9PIZXj*fI0>u zl@&%CHK015YU+X)m=ff>UW-Juj>6I2jLQUVF6Sh)f=O}!`h8Y&6gG%w(uD7U9y3W` z9W!NkY9S7qX{P%>tuIDcB?YFYK+~33QY(V*ayB${HHpj0A_zM~iSXs2sO6({+LJ^k z=d>|S?UI4giOEtza%_i3S;|%IAalpA!r>0JKnJrTKgPDd1^A@trT|DUSjrF^VWpF1 zP=7#^RK}vJruZh2ini8f@P5?n*BZn$*J}}^1v41vF3j$1LS$A$EuxMPboyq}i`B{u z?`o7UQIfD-OG+wO!vG}2wYDhvWwH`&v$lRKD71DJ=Zr1?|-#nik(nZ0`E zzSHX`cI>@>=e?_2m#!HvA3X5oOLu;7_T>4^ ssh-ed25519 V1pwNA 2ktkYzbOCI8Sedb7cFXrmOL7HqPmMFSmavTgJ/kXVyA -3kcv57UNk7Hryd8RckwYzuzN7eY6Lle4+DdG+QC86Hk --> ssh-ed25519 rIwlvw MoH0rHRt6ZL/3Ew1O7zHN9pz5CSA6YxbJ840gx0jCGY -AO7z51p5PlbAYUZgmk/joTdGeK4SxlCc+VgMcOrxkP0 --> ssh-ed25519 bPfq4g zu5ZfmzDiMBSn0UUpyO9iFieE7b+MMbuk4X5ABSUwhg -HKNFCsxNqEK94tEnYz5+cVypheP5Cf+5tYRft3rCucY --> ssh-ed25519 P1ilJQ pnX29lb1zHoXzv4S6+D4VtLPJEsrnkyhfNjsaNwkJmw -hXc9XLxtvyzUJNdhPi40bMFzdpuUKOHkpZ3gWMfjWwk --> ssh-ed25519 XSrA6w +h7/dC7DYOcRK1nxTDvdsgDEM43bBChM6vJ4PuL45ww -n0mVPplmTM3A76iF27Wt62RDJ4yeoZa51q6bRhPEcXA --> ssh-ed25519 pBdJmw b/oJKbk8mXkUsd0oRuzrAQHTsiZdE8cW5bDC3dM3Vn8 -6L+Zry15OyCXKOE71iqihTFVc2WB2Y7X7ZuFZSWXFSw --> ssh-ed25519 v2Y09A DBZDXfWnm/3d83xG4a7XnMDAU+WYR2l4UDOjWAwlVxA -4wE9Ss/D2Mmq4WddUsoa79S3db4Z6vpDs9zQR+zLROw --> R9;-grease -C4FHCe8aUuP55YV6ZnrphOE ---- /fL2KiOXipdwzKNjkkfwON+3h9JGa+M8wod12lkJ37A -twkGhmhg?:LXJ^NN0O|a|3|8E"%3Z~uՆbrڈA.)q,\62a`/<1'rIV3P _ID )RݔcVc)BGƦOլ;R#4(-eD \ No newline at end of file +-> ssh-ed25519 V1pwNA sW0/BN/WfF+8VshBdG/RcuJNUJFoRiV207qXHJ+nEQU +3xBHqOiK1MXQpfefvXpsUCAtB8SmpPYQxgWnKLY4/Mo +-> ssh-ed25519 rIwlvw 5N++1xasQ3ngJK8rWcnV1febLgOxdQxzj2FdwLeuvm0 +Ync9n2pX/MPHi6fKcBw/rir/KUOBDRZapaxxsu+XQyI +-> ssh-ed25519 bPfq4g GM5ZOInllLXKdpyIREUMWU0QToOgJe7TNWVoMXbYHTk +EfTBSko70+g28s21kPAWixZmkgbwfmTzosmP11q5Kh0 +-> ssh-ed25519 P1ilJQ 6NcCV8qZcm4zCPAixGhazZvwh2bQxqHsz0p3XuS54z0 +wUPo7zXREnpUkS8mRTU3tM3WR9QuYiC48Rlzl7CyPdk +-> ssh-ed25519 XSrA6w XV0e5v8rRSuTgsFPNjQOcaQnAJJ4JOCViTsiK7ClFUI +BgY93FYHCAE2BmcNm8SRYKRqMoXc3IshLxkNlJVGxrU +-> ssh-ed25519 pBdJmw /ppt+XqNCOj3ToS59AbT40lliyPi5aYdgsb+nOd70Cc +pXQqbfdC00/ITW9zblgGS+SCaM84BcWRrVr12Gkaqqk +-> ssh-ed25519 v2Y09A 25QeUKlLkjSOKFIBUHi8I0yQFtjJ10eMd5skrgB4wh4 +87j2b0Lvx+Qow8ggjVmkqDTc9par1RUAfmPxB9hL810 +-> ssh-rsa l6p0xw +aXJe3/ZW4d1wW58cGO43c1c7VqUid6LQNudUXZQF7hDGwWp66zUeTtJS8iK1uVRr +fBEd9MfCQXZ6e4mmeEsFDYhhsrihjFNqjv/V229VRfvlh6PFjyFsi8kOZmN0IyPC +rffk42oS9cVuG1JT/98kE56vUdJ098E+D7W5vHD6lVayp97DpncQRNqXyTWMdYB+ +75aHyUnI3JXmhftwPmQXthwKqYm/z5Q1yHtUWqo3VZ/UIN2fWD17XOxIVVdksSh6 +WdhJ7B+KYP1oXHZKeTGMpmPP7FYrgybbFlNl2Bg3+hc2g+Pav63ovnokr4hzmxf9 ++Vy0/gwE5tLKYXhSgCsfYLoYLcjh2LtdyWttG7z12TjKFtoxS1wfO71PBmQAWwV6 +MAaOfZdCbxZ6xpcJuvONmuvXaxzOxbZ5bgtrd2msEf2L3xlDDAPzUB786kvTLjjh +SkQFZvX8SWQBB4u7GKu7jwUYl8zcBfczVvQQ0APL/UUdIyYEClhbJO1MKJHgFAGN +mnuU0GQguxllgsT6+lNyKT9yP9W7wP92Bh+FzfRBH39Rq+FTb+VSQ5aOdoxtmbdQ +G99WJKDW0v3JXnveUeNGLXe0p0kH5qBdsZmRGcXmu1Wqwa5iIZKC80HEzztYFngc +n9dxirg30yQYoGUdASEQUDA55ZWb4hsrY7O1bz/fJ/g +-> B21^W'i:-grease X\JYH |@t jh9o +t4jio4eAlhMaiiGmy7ZKe7feRi36XQpUMkHAWyF42EMDbwzRcNVcvophXSQ +--- mvcfX2P6vxluKGbahXGgsl0bnjzgZF7Gd1HNEDnPh0o +ׁK/Z7A0+F)Voe(O}cu([(m6rByX1=- _8&˔ۊw?Y,I9 =8F̑]oaWXG;2jem.H ?"mKF9 XR \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 2a0509d..be972ac 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -16,6 +16,9 @@ let galatea = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII3Mke5YtaMkLvXJxJ3y7YAIEBesoJk3qJyJsnoLUWgW root@galatea"; + # for testing configs at home + silver_homelab = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCG1JzosOwS7oKjgm0+FlqMKrUbu+M5403un+VA7LwiGRQnneawuq6aqQsIoDqAlb9AzUdLTeBQb+rBf94kx7yVGdEIz1i34WdMK3kgl176jnDIR4TWeNKdj8Q6+4d7tn5mZrqmpXZ/+1KSauV9JHxytR+7A4NVexkhGX1Mq3efGBYsCKzUQh83lHs2baWUYuxaPCCR6vy6uklzQRQfg+NsxCCUKkbgJwv1ar5U1ccr4N89EWiR2Yu4XsPzXr0JJUQcUy587l+G7QYVoCwVgUKHevCRqtRlmnI6JrzWctQJPpAmWF4EF66QnWccdXUS+aVc0IKP0ORqmz8Nps4NWWVPjRRxeshl2XfFawWxGlgT4WJ0+qv/EDVPZQvNBrjFvY5QBAaU08Nnkg6QzehlwD4/zQQMFiDjMb7sUuhXdq0vOK235QMhS4jtX7Sm2ki6mJdXrlErq9dIaqcoYuw9EtfajaM/NnGYIy97JUOrfztQTAwiuPgrc4DijpdR0QtvYK7NvefiJYcW+osmcv+FYM03kMXK9uGtM6KI44i27ZdsUFWTIHeiR1yBGUfP1ObFLLaNx5E42jSA77RLF8BSUaPbGgRv3OciACNftIKhAJrV4AZGvBbaUvAlzC8CryFAcRDgQwIVlXBJzChc7Rh9/V8I5342Tq7xMmzBQ2WcQdqZ9Q== root@galatea"; + systems = [ agentjones @@ -23,12 +26,13 @@ let galatea vendetta vigil + + silver_homelab ]; in { # nix run github:ryantm/agenix -- -e secret1.age - "wireguard.age".publicKeys = users ++ systems; "dns_certs.secret.age".publicKeys = users ++ systems; "dns_dnskeys.conf.age".publicKeys = users ++ systems; diff --git a/secrets/stream_ulfm.age b/secrets/stream_ulfm.age index c68c602823e402706d99a2000ee52dbbc63e8c17..9be65594877259c8e0d0ca799a7e1f23f899df38 100644 GIT binary patch literal 3944 zcmZXVXIoT<+J$Xc#!d)oB4&grWrS&a%9be3?CHHXL73UIncn+|6&nf?6VybFVo=b4 zqM#x+&={goL{Y&SJy>JKf?YhG5AT<}zu>-}^{o3^dJ~e4IAL$Z?YFp`87{908^oj1 zr=xv7b2?%qkVtqCt-`xQA{sghG%q(~4~Ecw zKPb>J!csd0MJAqJn3o12`IJlnSHsP()<9)Xl?CC_0GEFseyVgzmKv+;##MFC()oT&a>x zV^jZ4li)3Oo)jJN`yvXdR?fh&On90|3+qTS3JbF0{S=*r0Y;GkV5YL@MuwAy(zvt{ zMF1o_DMG2)%XCH6Rx2x{pxdkxo=`!?SWFlWY+z6vPUgR98o8H74xue_0_==+az>?OG4yoG!%_QjUlO7 zJ~3Ov6Mz0ZgYKi+bQmuzlenxNyIBgUEKvi?u9e9M0ZcGz;R!@Wk_jRBfq&l?BxrFU z4b2XdxghA&(}^sqPN<}lC`=!jEVmhbCLAmb0*rj3)Fafff)N0vRAcoRxytBpv-tuo z%nHD2mmLs@Xi*x%BS=UZNq}f|Xo-~k(EriAK0Vq_cH_b!6ptttIM_H5#{~=MG?`n* z57Vq+H4_08h$JKc)I`9er}I4`f{>*CTnP)06GSv1&coLE>?W=PCBhq{7BDqukXtw$mZv3LOjfhiYYhgDS&eC9PGT5U59b7$u$)GBj29YDIlM#ecmsllra7F5$a=NFu_E1YD`Wd z3bBD^3Qi9hRXmZCrd0!EQWPh|xk)^~!JM!2vizW!&BNgki5b#L7zDh>ZL_+ha)*r_ z_i(m}|rbETIio>R$ zmI|q0tJ9%HL4Z`?(h0RRglH3CLu_YQgB9t8S|^v|#MxCsZ-9?zl%jwb2BjK-U#zu< zC~(*aa1n*e5#n1=ykO9zqaboCgb)M)2@7E8WPnw~3qI{~5F@H{+dGkXL|0VV{&T(1m81A}@J*BkPAl~R|0ZG<8eLX;`P>-BP;n-rEX zwcL2ISU13TtD^wkAvb7HL77oNQ!3~z z9Rva%rqmn>ll1~c)MD0&DPA5!Dy2xcvJn4&TBWC>KMw_mVqk076dcYalByK$u#HD@ zAVh0a$XD_45}C@uaP!StrW9q?+ZRSRyk4jZPR|?vwb*Q|tFCWe`QmwAs;{+4eWPha z=H!aFnJFE2Ye()&x@^xZm;JP|>QMX0`L!n;ddEkB2^^Bw>HuYksr%>R~8j zc>9FA^fULRRTL9)A~`V@NW^TqT-6Q^9g$eK0@yyveB*CxBI8QgWjNzuG&HGJ)UwWU zH+5avoNde7;!f57FkSX%)z$fF2`|kHy4R%$8eJD%JJti1{#ULhxvBE?e{P3{5s*i#`jpl z7jr&61RCL;>V9P@E39`$tr~SFx;~ehJZtN(yu|q2k=KWz#&#Y|NS;I-+CAlC@q!y? z%lgG^eH1@!(&?plY6>1kg7YtDoXnaOLmfD3KxFVASz~ikN+90{(z#XY9W|nxPoM4= zOUqt4_kJ}XGoKJ!_IBjHxuNn#qH6QfV8P}0X^Gs^KQ@ICc;}{=;lHRwUn9ziDJ!?6 z#(mrGdPd7*@us;i)bWn;22<=0f56ez@dv;2HLWO|(Q+v{_4ljg2m4yk(E>fHBRPoKI^BK4oCPmV7tLiHuX`Zku7@z9U)wBU_rT`IeD@^@EGyk39cQ{&)3=dJIKuNLkZJkm;v zbei*q9GseSEoE*eyvXC?ew#h?-H@&K_YQLJtr%X}c4@??c1b%|&~dT+>oz5XT~a!8L2Q<|FN5&sD^%>0eRZ#%_Bq%3eaDBHx#KEsOzGqH9PeSP z8mC@aol|#V<*A8hO=G_y^t-z~z9OT4&cxLE|B#DEX8tu%uW#FOaDT;_b#H1@H%=a~ z{@TujK7XA11BglBOzl3>dw*wbj!o9Sr#5`*Kn-aeewFaZ^1J7VdGgIs7FKK# z0o^b$;ihh1o-{Y}^t(4} z`hS;}r`)!s;AC2ATF2{}mIW1oDGj*nUnhRpnwXP)ekgh!FmNrH;=gfzQ_`tjJL5G= zPQ7?5G`2`x#eX^bK1zbkXUhi48%0A}$6{ZX9!qM!oplVk++?2gbMon?=IVl7)m~fT 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