From 7e2f76e7f90a0a5441ced8ff4c8e923f94559653 Mon Sep 17 00:00:00 2001 From: ibizaman Date: Sat, 20 Jan 2024 20:11:03 -0800 Subject: [PATCH] improve ssl block --- modules/blocks/ssl.nix | 5 +++ modules/blocks/ssl/docs/default.md | 14 ++++---- test/vm/ssl.nix | 57 +++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/modules/blocks/ssl.nix b/modules/blocks/ssl.nix index 5a27571..8719dba 100644 --- a/modules/blocks/ssl.nix +++ b/modules/blocks/ssl.nix @@ -257,8 +257,13 @@ in script = '' mkdir -p /etc/ssl/certs + rm -f /etc/ssl/certs/ca-bundle.crt rm -f /etc/ssl/certs/ca-certificates.crt + + cat /etc/static/ssl/certs/ca-bundle.crt > /etc/ssl/certs/ca-bundle.crt + cat /etc/static/ssl/certs/ca-bundle.crt > /etc/ssl/certs/ca-certificates.crt for file in ${lib.concatStringsSep " " (lib.mapAttrsToList (_name: caCfg: caCfg.paths.cert) cfg.cas.selfsigned)}; do + cat "$file" >> /etc/ssl/certs/ca-bundle.crt cat "$file" >> /etc/ssl/certs/ca-certificates.crt done ''; diff --git a/modules/blocks/ssl/docs/default.md b/modules/blocks/ssl/docs/default.md index 0a8ce53..a241840 100644 --- a/modules/blocks/ssl/docs/default.md +++ b/modules/blocks/ssl/docs/default.md @@ -96,22 +96,22 @@ To use either a self-signed certificates or a Let's Encrypt generated one, we ca where the certificate and the private key are located: ```nix -config.shb.certs...paths.cert -config.shb.certs...paths.key +config.shb.certs.certs...paths.cert +config.shb.certs.certs...paths.key ``` For example: ```nix -config.shb.certs.selfsigned."example.com".paths.cert -config.shb.certs.selfsigned."example.com".paths.key +config.shb.certs.certs.selfsigned."example.com".paths.cert +config.shb.certs.certs.selfsigned."example.com".paths.key ``` We can then configure Nginx to use those certificates: ```nix services.nginx.virtualHosts."example.com" = let - cert = config.shb.certs.selfsigned."example.com"; + cert = config.shb.certs.certs.selfsigned."example.com"; in { onlySSL = true; @@ -130,8 +130,8 @@ certificate to the generated: ```nix systemd.services.nginx = { - after = [ config.shb.certs.selfsigned."example.com".systemdService ]; - requires = [ config.shb.certs.selfsigned."example.com".systemdService ]; + after = [ config.shb.certs.certs.selfsigned."example.com".systemdService ]; + requires = [ config.shb.certs.certs.selfsigned."example.com".systemdService ]; }; ``` diff --git a/test/vm/ssl.nix b/test/vm/ssl.nix index 553d454..44f580a 100644 --- a/test/vm/ssl.nix +++ b/test/vm/ssl.nix @@ -18,31 +18,46 @@ }; }; certs.selfsigned = { - mycert = { + top = { ca = config.shb.certs.cas.selfsigned.myca; domain = "example.com"; }; + subdomain = { + ca = config.shb.certs.cas.selfsigned.myca; + + domain = "subdomain.example.com"; + }; }; }; # The configuration below is to create a webserver that uses the server certificate. - networking.hosts."127.0.0.1" = [ "example.com" ]; + networking.hosts."127.0.0.1" = [ "example.com" "subdomain.example.com" "wrong.example.com" ]; services.nginx.enable = true; services.nginx.virtualHosts."example.com" = { onlySSL = true; - sslCertificate = config.shb.certs.certs.selfsigned.mycert.paths.cert; - sslCertificateKey = config.shb.certs.certs.selfsigned.mycert.paths.key; + sslCertificate = config.shb.certs.certs.selfsigned.top.paths.cert; + sslCertificateKey = config.shb.certs.certs.selfsigned.top.paths.key; locations."/".extraConfig = '' add_header Content-Type text/plain; - return 200 'It works!'; + return 200 'Top domain'; + ''; + }; + services.nginx.virtualHosts."subdomain.example.com" = + { + onlySSL = true; + sslCertificate = config.shb.certs.certs.selfsigned.subdomain.paths.cert; + sslCertificateKey = config.shb.certs.certs.selfsigned.subdomain.paths.key; + locations."/".extraConfig = '' + add_header Content-Type text/plain; + return 200 'Subdomain'; ''; }; systemd.services.nginx = { - after = [ config.shb.certs.certs.selfsigned.mycert.systemdService ]; - requires = [ config.shb.certs.certs.selfsigned.mycert.systemdService ]; + after = [ config.shb.certs.certs.selfsigned.top.systemdService config.shb.certs.certs.selfsigned.subdomain.systemdService ]; + requires = [ config.shb.certs.certs.selfsigned.top.systemdService config.shb.certs.certs.selfsigned.subdomain.systemdService ]; }; }; @@ -51,7 +66,8 @@ let myca = nodes.server.shb.certs.cas.selfsigned.myca; myotherca = nodes.server.shb.certs.cas.selfsigned.myotherca; - mycert = nodes.server.shb.certs.certs.selfsigned.mycert; + top = nodes.server.shb.certs.certs.selfsigned.top; + subdomain = nodes.server.shb.certs.certs.selfsigned.subdomain; in '' start_all() @@ -61,16 +77,31 @@ server.wait_for_file("${myca.paths.cert}") server.wait_for_file("${myotherca.paths.key}") server.wait_for_file("${myotherca.paths.cert}") - server.wait_for_file("${mycert.paths.key}") - server.wait_for_file("${mycert.paths.cert}") + server.wait_for_file("${top.paths.key}") + server.wait_for_file("${top.paths.cert}") + server.wait_for_file("${subdomain.paths.key}") + server.wait_for_file("${subdomain.paths.cert}") # Wait for jkkk server.require_unit_state("${nodes.server.shb.certs.systemdService}", "inactive") + machine.wait_for_unit("nginx") + machine.wait_for_open_port(443) + with subtest("Certificate is trusted in curl"): - machine.wait_for_unit("nginx") - machine.wait_for_open_port(443) - machine.succeed("curl --fail-with-body -v https://example.com") + resp = machine.succeed("curl --fail-with-body -v https://example.com") + if resp != "Top domain": + raise Exception('Unexpected response, got: {}'.format(resp)) + + resp = machine.succeed("curl --fail-with-body -v https://subdomain.example.com") + if resp != "Subdomain": + raise Exception('Unexpected response, got: {}'.format(resp)) + + with subtest("Fail if certificate is not in CA bundle"): + machine.fail("curl --cacert /etc/static/ssl/certs/ca-bundle.crt --fail-with-body -v https://example.com") + machine.fail("curl --cacert /etc/static/ssl/certs/ca-bundle.crt --fail-with-body -v https://subdomain.example.com") + machine.fail("curl --cacert /etc/static/ssl/certs/ca-certificates.crt --fail-with-body -v https://example.com") + machine.fail("curl --cacert /etc/static/ssl/certs/ca-certificates.crt --fail-with-body -v https://subdomain.example.com") ''; }; }