1
0
Fork 0

add extraDomains options for cert generation

fixes #133
This commit is contained in:
ibizaman 2024-01-23 23:16:46 -08:00 committed by Pierre Penninckx
parent 229e29d1eb
commit 0bfa15fd3c
2 changed files with 91 additions and 32 deletions

View file

@ -73,6 +73,20 @@ in
example = "example.com"; example = "example.com";
}; };
extraDomains = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
Other domains to generate a certificate for.
'';
default = [];
example = lib.literalExpression ''
[
"sub1.example.com"
"sub2.example.com"
]
'';
};
paths = lib.mkOption { paths = lib.mkOption {
description = '' description = ''
Paths where certs will be located. Paths where certs will be located.
@ -109,6 +123,20 @@ in
example = "example.com"; example = "example.com";
}; };
extraDomains = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = ''
Other domains to generate a certificate for.
'';
default = [];
example = lib.literalExpression ''
[
"sub1.example.com"
"sub2.example.com"
]
'';
};
paths = lib.mkOption { paths = lib.mkOption {
description = '' description = ''
Paths where certs will be located. Paths where certs will be located.
@ -278,7 +306,11 @@ in
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig.RuntimeDirectory = serviceName certCfg.systemdService; serviceConfig.RuntimeDirectory = serviceName certCfg.systemdService;
# Taken from https://github.com/NixOS/nixpkgs/blob/7f311dd9226bbd568a43632c977f4992cfb2b5c8/nixos/tests/custom-ca.nix # Taken from https://github.com/NixOS/nixpkgs/blob/7f311dd9226bbd568a43632c977f4992cfb2b5c8/nixos/tests/custom-ca.nix
script = '' script =
let
extraDnsNames = lib.strings.concatStringsSep "\n" (map (n: "dns_name = ${n}") certCfg.extraDomains);
in
''
cd $RUNTIME_DIRECTORY cd $RUNTIME_DIRECTORY
# server cert template # server cert template
@ -287,6 +319,7 @@ in
cn = "${certCfg.domain}" cn = "${certCfg.domain}"
expiration_days = 30 expiration_days = 30
dns_name = "${certCfg.domain}" dns_name = "${certCfg.domain}"
${extraDnsNames}
encryption_key encryption_key
signing_key signing_key
EOF EOF
@ -327,7 +360,7 @@ in
security.acme.certs = lib.mkMerge (lib.mapAttrsToList (name: certCfg: { security.acme.certs = lib.mkMerge (lib.mapAttrsToList (name: certCfg: {
"${name}" = { "${name}" = {
extraDomainNames = [ certCfg.domain ]; extraDomainNames = [ certCfg.domain ] ++ certCfg.extraDomains;
email = certCfg.adminEmail; email = certCfg.adminEmail;
inherit (certCfg) dnsProvider dnsResolver; inherit (certCfg) dnsProvider dnsResolver;
credentialsFile = certCfg.credentialsFile; credentialsFile = certCfg.credentialsFile;

View file

@ -28,33 +28,45 @@
domain = "subdomain.example.com"; domain = "subdomain.example.com";
}; };
multi = {
ca = config.shb.certs.cas.selfsigned.myca;
domain = "multi1.example.com";
extraDomains = [ "multi2.example.com" "multi3.example.com" ];
};
}; };
}; };
# The configuration below is to create a webserver that uses the server certificate. # The configuration below is to create a webserver that uses the server certificate.
networking.hosts."127.0.0.1" = [ "example.com" "subdomain.example.com" "wrong.example.com" ]; networking.hosts."127.0.0.1" = [
"example.com"
"subdomain.example.com"
"wrong.example.com"
"multi1.example.com"
"multi2.example.com"
"multi3.example.com"
];
services.nginx.enable = true; services.nginx.enable = true;
services.nginx.virtualHosts."example.com" = services.nginx.virtualHosts =
{ let
onlySSL = true; mkVirtualHost = response: cert: {
sslCertificate = config.shb.certs.certs.selfsigned.top.paths.cert; onlySSL = true;
sslCertificateKey = config.shb.certs.certs.selfsigned.top.paths.key; sslCertificate = cert.paths.cert;
locations."/".extraConfig = '' sslCertificateKey = cert.paths.key;
add_header Content-Type text/plain; locations."/".extraConfig = ''
return 200 'Top domain'; add_header Content-Type text/plain;
''; return 200 '${response}';
}; '';
services.nginx.virtualHosts."subdomain.example.com" = };
{ in
onlySSL = true; {
sslCertificate = config.shb.certs.certs.selfsigned.subdomain.paths.cert; "example.com" = mkVirtualHost "Top domain" config.shb.certs.certs.selfsigned.top;
sslCertificateKey = config.shb.certs.certs.selfsigned.subdomain.paths.key; "subdomain.example.com" = mkVirtualHost "Subdomain" config.shb.certs.certs.selfsigned.subdomain;
locations."/".extraConfig = '' "multi1.example.com" = mkVirtualHost "multi1" config.shb.certs.certs.selfsigned.multi;
add_header Content-Type text/plain; "multi2.example.com" = mkVirtualHost "multi2" config.shb.certs.certs.selfsigned.multi;
return 200 'Subdomain'; "multi3.example.com" = mkVirtualHost "multi3" config.shb.certs.certs.selfsigned.multi;
''; };
};
systemd.services.nginx = { systemd.services.nginx = {
after = [ config.shb.certs.certs.selfsigned.top.systemdService config.shb.certs.certs.selfsigned.subdomain.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 ]; requires = [ config.shb.certs.certs.selfsigned.top.systemdService config.shb.certs.certs.selfsigned.subdomain.systemdService ];
@ -68,6 +80,7 @@
myotherca = nodes.server.shb.certs.cas.selfsigned.myotherca; myotherca = nodes.server.shb.certs.cas.selfsigned.myotherca;
top = nodes.server.shb.certs.certs.selfsigned.top; top = nodes.server.shb.certs.certs.selfsigned.top;
subdomain = nodes.server.shb.certs.certs.selfsigned.subdomain; subdomain = nodes.server.shb.certs.certs.selfsigned.subdomain;
multi = nodes.server.shb.certs.certs.selfsigned.multi;
in in
'' ''
start_all() start_all()
@ -81,27 +94,40 @@
server.wait_for_file("${top.paths.cert}") server.wait_for_file("${top.paths.cert}")
server.wait_for_file("${subdomain.paths.key}") server.wait_for_file("${subdomain.paths.key}")
server.wait_for_file("${subdomain.paths.cert}") server.wait_for_file("${subdomain.paths.cert}")
server.wait_for_file("${multi.paths.key}")
server.wait_for_file("${multi.paths.cert}")
# Wait for jkkk
server.require_unit_state("${nodes.server.shb.certs.systemdService}", "inactive") server.require_unit_state("${nodes.server.shb.certs.systemdService}", "inactive")
machine.wait_for_unit("nginx") server.wait_for_unit("nginx")
machine.wait_for_open_port(443) server.wait_for_open_port(443)
with subtest("Certificate is trusted in curl"): with subtest("Certificate is trusted in curl"):
resp = machine.succeed("curl --fail-with-body -v https://example.com") resp = server.succeed("curl --fail-with-body -v https://example.com")
if resp != "Top domain": if resp != "Top domain":
raise Exception('Unexpected response, got: {}'.format(resp)) raise Exception('Unexpected response, got: {}'.format(resp))
resp = machine.succeed("curl --fail-with-body -v https://subdomain.example.com") resp = server.succeed("curl --fail-with-body -v https://subdomain.example.com")
if resp != "Subdomain": if resp != "Subdomain":
raise Exception('Unexpected response, got: {}'.format(resp)) raise Exception('Unexpected response, got: {}'.format(resp))
resp = server.succeed("curl --fail-with-body -v https://multi1.example.com")
if resp != "multi1":
raise Exception('Unexpected response, got: {}'.format(resp))
resp = server.succeed("curl --fail-with-body -v https://multi2.example.com")
if resp != "multi2":
raise Exception('Unexpected response, got: {}'.format(resp))
resp = server.succeed("curl --fail-with-body -v https://multi3.example.com")
if resp != "multi3":
raise Exception('Unexpected response, got: {}'.format(resp))
with subtest("Fail if certificate is not in CA bundle"): 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") server.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") server.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") server.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") server.fail("curl --cacert /etc/static/ssl/certs/ca-certificates.crt --fail-with-body -v https://subdomain.example.com")
''; '';
}; };
} }