From 4a2f900c5a454850cc63857a50e294339810758b Mon Sep 17 00:00:00 2001 From: Henri Dohmen Date: Sat, 4 Oct 2025 14:04:17 +0200 Subject: [PATCH] self signed cert --- bin/gen-tls-cert | 30 ++++++++++++++++++++++++++++++ common/security.nix | 2 ++ flake.nix | 1 + host/roam/services.nix | 11 +++++++---- mod/nginx.nix | 30 ++++++++++++++++++++---------- pki/ca.cert | 19 +++++++++++++++++++ pki/server.cert | 20 ++++++++++++++++++++ secrets.nix | 1 + secrets/tlskey.age | Bin 0 -> 2136 bytes 9 files changed, 100 insertions(+), 14 deletions(-) create mode 100755 bin/gen-tls-cert create mode 100644 pki/ca.cert create mode 100644 pki/server.cert create mode 100644 secrets/tlskey.age diff --git a/bin/gen-tls-cert b/bin/gen-tls-cert new file mode 100755 index 0000000..9a2e9cb --- /dev/null +++ b/bin/gen-tls-cert @@ -0,0 +1,30 @@ +#!/bin/sh +tmp=$(mktemp -d) +trap 'rm -rf -- "$keyfile"' EXIT + +# ref https://stackoverflow.com/questions/59738140/why-is-firefox-not-trusting-my-self-signed-certificate +openssl req -x509 -nodes \ + -newkey RSA:2048 \ + -keyout "$tmp/ca.key" \ + -days 365 \ + -out "$tmp/ca.cert" \ + -subj '/CN=hd_root' \ + +rm secrets/tlskey.age +openssl req -nodes \ + -newkey rsa:2048 \ + -keyout - \ + -out "$tmp/server.csr" \ + -subj '/CN=lan' \ + | agenix -e secrets/tlskey.age + +openssl x509 -req \ + -CA "$tmp/ca.cert" \ + -CAkey "$tmp/ca.key" \ + -in "$tmp/server.csr" \ + -out pki/server.cert \ + -days 365 \ + -CAcreateserial \ + -extfile <(printf "subjectAltName=DNS:roam.lan,DNS:*.roam.lan\nauthorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth") + +mv "$tmp/ca.cert" pki/ca.cert \ No newline at end of file diff --git a/common/security.nix b/common/security.nix index e3ef3f2..2556f06 100644 --- a/common/security.nix +++ b/common/security.nix @@ -93,5 +93,7 @@ } ]; }; + + pki.certificateFiles = [ ../pki/ca.cert ]; }; } diff --git a/flake.nix b/flake.nix index c9490f1..a33bc11 100644 --- a/flake.nix +++ b/flake.nix @@ -115,6 +115,7 @@ buildInputs = [ colmena.packages.${system}.colmena agenix.packages.${system}.default + pkgs.openssl ]; }; formatter = pkgs.nixfmt-tree; diff --git a/host/roam/services.nix b/host/roam/services.nix index 4ee1db9..a78ce18 100644 --- a/host/roam/services.nix +++ b/host/roam/services.nix @@ -1,13 +1,15 @@ { var, + config, + secrets, ... }: { services = { nginx = { - recommendedTlsSettings = true; - recommendedProxySettings = true; - recommendedOptimisation = true; + # recommendedTlsSettings = true; + # recommendedProxySettings = true; + # recommendedOptimisation = true; enable = true; virtualHosts.default = { @@ -16,11 +18,12 @@ rejectSSL = true; locations."/".return = "444"; }; - virtualHostsPriv."roam.lan" = { + privateVirtualHosts."roam.lan" = { locations."/" = { }; }; virtualHosts."roam.hdohmen.de" = { enableACME = true; + forceSSL = true; locations."/" = { }; }; }; diff --git a/mod/nginx.nix b/mod/nginx.nix index 2eae403..75b6df6 100644 --- a/mod/nginx.nix +++ b/mod/nginx.nix @@ -3,35 +3,45 @@ options, config, var, + secrets, ... }: with lib; { - options.services.nginx.virtualHostsPriv = mkOption { + options.services.nginx.privateVirtualHosts = mkOption { type = options.services.nginx.virtualHosts.type; default = { }; description = "Declarative vhost config listening on onet"; }; - config = { + config = mkIf (config.services.nginx.privateVirtualHosts != { }) { + age.secrets.tlskey = { + file = secrets."tlskey.age"; + mode = "440"; + owner = config.services.nginx.user; + group = config.services.nginx.group; + }; + services.nginx.virtualHosts = builtins.mapAttrs ( _: v: v // { + sslCertificateKey = config.age.secrets.tlskey.path; + sslCertificate = ../pki/server.cert; + + addSSL = true; listen = [ { addr = var.wg.ips.roam; port = 80; } - /* - { TODO: Fix certs - addr = var.wg.ips.roam; - port = 443; - ssl = true; - } - */ + { + addr = var.wg.ips.roam; + port = 443; + ssl = true; + } ]; } - ) config.services.nginx.virtualHostsPriv; + ) config.services.nginx.privateVirtualHosts; }; } diff --git a/pki/ca.cert b/pki/ca.cert new file mode 100644 index 0000000..78901f9 --- /dev/null +++ b/pki/ca.cert @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAe2gAwIBAgIUQZNUMLFIGLdsj9Cj3a3TpX45Wv0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHaGRfcm9vdDAeFw0yNTEwMDQxMTU3NTdaFw0yNjEwMDQx +MTU3NTdaMBIxEDAOBgNVBAMMB2hkX3Jvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC7bpbr+iJ4O5asQmy3bP1xe0hgNkU3BqKGxFmQ5neKDMBEhnHt +ubb0jlPDns9reawX/2/7MGZFKTHvjlzZdKkSA+7t/afRs4O/sP3gqN0N7g6QdRGt +aC+7skib+tN1mrx7ZlL3UXhDE4iLhwff1PJdsGuwW3Kt4GoXISwaQlFrAhGNyuB9 +5ZQuGk4TySiBRsghg/Q54V7njl7Ob5XfH2MfgONPTpd7j58kA4g5Y5HJYK6THdzU +GZG5YrxWdmxRRhXC0LFPvS/QRc/HzvOdjryEgAQBl0VUNaU+hsd0smxNWFCbUIx3 +XafZXxlDGFnU8ktbkgHnMjlgbteBYxx9BB/BAgMBAAGjUzBRMB0GA1UdDgQWBBQM +lKKCnjZOHyPIm1peyUgQLErdRTAfBgNVHSMEGDAWgBQMlKKCnjZOHyPIm1peyUgQ +LErdRTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCMviNrad9B +I2XL3grAeyWAsbo9Ne4UApozzjInbX/fczxuP0QL9zSt6l3FVgN2HOnd56NjwSKF +LJyGJwjO+HoC6XDGIcMwFvch16FSTzuORKMCjWOXEq2ZFsbTa8fcSyfXRq+xcdc+ +lgaqsEMBaO3vi19nFxEOO7Ps467F46uHF8RuTCnslI0UCHWiHoOT0n0E7Pr++IX/ +bsVeL5xRKivi37JMAkAGWPH3qqpk4wh3dgLbPBcwDf/nf6ERS2yGtAF1Ucwpg/9W +7jvtw3TScoL4Fwl0X52aaF1WqRaS1Ovo3DLP8QfeyUVtDCxKdc+YgwXRJ963QDsX +Oj33DVkzEVG1 +-----END CERTIFICATE----- diff --git a/pki/server.cert b/pki/server.cert new file mode 100644 index 0000000..3e99c74 --- /dev/null +++ b/pki/server.cert @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIUNoexai8hK2EXKI7S0NuZFuhtVF0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHaGRfcm9vdDAeFw0yNTEwMDQxMTU3NTdaFw0yNjEwMDQx +MTU3NTdaMA4xDDAKBgNVBAMMA2xhbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMY1qSgzUCcRRyJXsd+8KWRfPS4BMWXRKJwsH3RKXBEFVO5SZGynV5AD +W6sUw/2VeIW1LLhpt7AnEblJ0zVNcIcFyisAGQK0sLgSmPZ0q6j1MHXd37hVQ5GX +7DQ/ZMSPuOJgCpSjWVvCmnUOWlkZtqUpPKIxpHH5YsakbLorQgHiGYjiHeWJTqM7 +Ahi9IaMCRwgBK0G8TQ3jI2CUk1OxX4r48pxp7kR3u+rRLec5ZdzefMboyL6m9K4P +r3MA10uF8SvzEC9IH1PixGMgqW6iMBsscuNGMoWPf6MWnJwYr3DOe1B8G0VrFdZg +mENh84jJhPcKrHTsszdj8fkl0K30ezsCAwEAAaOBkTCBjjAfBgNVHREEGDAWgghy +b2FtLmxhboIKKi5yb2FtLmxhbjAfBgNVHSMEGDAWgBQMlKKCnjZOHyPIm1peyUgQ +LErdRTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcD +ATAdBgNVHQ4EFgQU7XO2i2IykvfcecBTdKGUA8zYxAUwDQYJKoZIhvcNAQELBQAD +ggEBACCt6e3OSOVhqf/hD4rOJMi8rTlOMBroI8ErbDuXKF3NBNfe3vIZBtqaDxeC +1XhuSFAH5RYJupRF/vRlW58M+r1qeRakhHIpFEJDJle0dr3kw27IS+OyxSH4d3vd +3PvUsPLAtO8Cz/SXo6OkkEboNwEWmCuOWjyyj2lbDVpO3wPVUcy7kRLQBqGnv+Eu +xY059qByIZqr0SKrn0MttCRZbfzngdVXyQjC9wyTrQ+yDCE0Cng5omvw7pFrUb/W +0v/JJYXrXXM7/JEtxC2+kbp3uH8zcDorOS3pVtHRROhHSvi83ggTHFCEXzUVtWNH +M7aWXTM62DaugxDtvaPkfyS4Bv8= +-----END CERTIFICATE----- diff --git a/secrets.nix b/secrets.nix index 26351f3..9bdc144 100644 --- a/secrets.nix +++ b/secrets.nix @@ -6,6 +6,7 @@ let "roam/rclone-conf" "roam/firefox-sync-secret" "hd-password" + "tlskey" ]; in builtins.foldl' (acc: x: acc // { "secrets/${x}.age".publicKeys = keys; }) { } secrets diff --git a/secrets/tlskey.age b/secrets/tlskey.age new file mode 100644 index 0000000000000000000000000000000000000000..926f347dac39e321789927448b2cf4cd00556304 GIT binary patch literal 2136 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCTyOsOac4pazpcXjlS z%E<}ybjb@aD-6$ev#d-v*Di8Qt*Xk*3og&q&dEzJ@N)OB$mcRN_4ls`D=7;})wc9E zP7I97Da~^&4JbDY3(YDkHY`d?%QZGBjYu~2@4={=D(&f95$heRei|6WvT7i#*XU&%eoYK5p0F?4~yx z`)wRbf-fB~ers`2Gi9DgwSQ))Y@>L}|2toB|UQ`v>bVz-COV~&C+$6ud#o-re^ebF`d-`i(B?hAb-sF~Bpa-?mI&L3m`ZEJq4 z5#GAnY2{p3W3C^2b@QESXa8RQ`q|X%i?|e6?1SeC+pJQ_u`fBwi$WzcRB3b z?dzqd^}noZ#_Dht|E$*+m<`?R4XoM9pG&tS^qjwcB)h_JX?4VIwe}aRvU6ColMMf= zao>CL*l*sOb*}_(C6}#L&_4D{&|$}a^U&>!el&=)zEvo73imm&%|+U6^)%c{OwTM&<6R^*TouGe^GYoIJHh`oX`0`Uy8Vu3Wp} zUu+;EJ3DBq?eQJgx5>?)r|0r$YSX$!AI&DNjktf^Bd%%Mg5O>fv`T!6n(p`hcGIZe zsCp`Ujl)u@ZCS4wn(er|XJtQEFElV%do^KQdf%ji3rz;smPPB`*1WNx|HSM!Ox$gdnABdYI!Elz%;iM~H#f$yLpN=T+4s(d| zdA9fRJevo5Dod7^@Jt8_%!>FgF=MN-K&yV%Fy*BM?;$j@8GYk5{l?pb*8{pWHQ zc81P;QD(VEu`sA0+)Cv6-gKRrl3IV#-q}8z9)4@0qzeC%hjDdb-Em^8diL*GNs)HFci>4$oR90IcULUta5G%|Tfg@F*-(?ot2-kWuAA=2T6^rm z$C$f+6LKpi*I#{mb{V7ho;L^YJ_wupc2~xq8GCuNOijM4+zZ(sye@BvVsN;*_*SdH zOxYI)n$AS)nXY$w_AK*b>FqtIr?9Bq&+z_sgJX6a8@I0igSedd_uJm(Rtu{ecGQN; zl_YT8>L`qss_{O3=CR!z?zx#!4eg9lx4ex4KjpE`O!{*s`hTZ`;Xzg74}~^Y7qOc; zhhN%uqjthP?c7s=yzk80_GEw4cMQJ&=to1y235A&M4kG~U(Q!NzLl#r%`O&MA^0Lm zA>rt?m+7;9Sl+q%z-yXE)OwCrnvRAQUt!$Qj%Q4HQhv}M6ilS*3ZZP8%+|t&3Cj0ZWeRY{Y}4Oskahm`{NnHPpXRcd z`?!1Nv6N3{J|z6{qDjjm$J!RYR#rv(wAbY~xZW=l%{%3$Jm=Yu_9cODeVk9MVKuM6 z$h|N2^>6RSzU4V)&WXpm{;!Zf$8o^yv&GV5CuBl*1_i18@($_0+}&;P_Hls4)ANY| z{Xe+_mBsA8_O|Z~bV|)wE+Se{Ea_KLaeP8VVE+A{%SIog_OcgzH8+^8I`i&fOR?Iu zj|CPSc;sr&(zJQvm2DYprn1|=bG^uDa9`V^&0s3K{Mq!3Bc0(~=d35J3>GeJ>iL^` z_e|4v-R^(uQXI9*wJr{9n9$>m#GcK4eTb}~#@$0gS>aJB0n%&?w(J^;s1BppDy2AU|^tL_w@YJqjw}FBU>g09qc=GEIIwE z&c`gJiMOv!^R&*Gf0*N!ipaUt$ISaSl$X_nOkpE%Xw_p^tW>8Psg z<1nVDZqFR6-kvFH*u1j$&5|I8)yH|XCMD+Y`64XuJhf+_l>f9|FXSUJ;~VY{ey(i`N8dB zO$r5zYaXAKOfK2;@dmGRficIrqA!o*=dI2Yzj}MOs*-_~V?}a%Q*=$IEr)K+#;sm0 Y?r#z%Xim0TD42Hsh%NIIEny9301GSQzyJUM literal 0 HcmV?d00001