1{ system ? builtins.currentSystem,
2 config ? {},
3 pkgs ? import ../.. { inherit system config; }
4}:
5
6with import ../lib/testing-python.nix { inherit system pkgs; };
7let
8 mkSpec = { host, service ? null, action }: {
9 inherit action;
10 authority = {
11 file = {
12 group = "nginx";
13 owner = "nginx";
14 path = "/var/ssl/${host}-ca.pem";
15 };
16 label = "www_ca";
17 profile = "three-month";
18 remote = "localhost:8888";
19 };
20 certificate = {
21 group = "nginx";
22 owner = "nginx";
23 path = "/var/ssl/${host}-cert.pem";
24 };
25 private_key = {
26 group = "nginx";
27 mode = "0600";
28 owner = "nginx";
29 path = "/var/ssl/${host}-key.pem";
30 };
31 request = {
32 CN = host;
33 hosts = [ host "www.${host}" ];
34 key = {
35 algo = "rsa";
36 size = 2048;
37 };
38 names = [
39 {
40 C = "US";
41 L = "San Francisco";
42 O = "Example, LLC";
43 ST = "CA";
44 }
45 ];
46 };
47 inherit service;
48 };
49
50 mkCertmgrTest = { svcManager, specs, testScript }: makeTest {
51 name = "certmgr-" + svcManager;
52 nodes = {
53 machine = { config, lib, pkgs, ... }: {
54 networking.firewall.allowedTCPPorts = with config.services; [ cfssl.port certmgr.metricsPort ];
55 networking.extraHosts = "127.0.0.1 imp.example.org decl.example.org";
56
57 services.cfssl.enable = true;
58 systemd.services.cfssl.after = [ "cfssl-init.service" "networking.target" ];
59
60 systemd.tmpfiles.rules = [ "d /var/ssl 777 root root" ];
61
62 systemd.services.cfssl-init = {
63 description = "Initialize the cfssl CA";
64 wantedBy = [ "multi-user.target" ];
65 serviceConfig = {
66 User = "cfssl";
67 Type = "oneshot";
68 WorkingDirectory = config.services.cfssl.dataDir;
69 };
70 script = ''
71 ${pkgs.cfssl}/bin/cfssl genkey -initca ${pkgs.writeText "ca.json" (builtins.toJSON {
72 hosts = [ "ca.example.com" ];
73 key = {
74 algo = "rsa"; size = 4096; };
75 names = [
76 {
77 C = "US";
78 L = "San Francisco";
79 O = "Internet Widgets, LLC";
80 OU = "Certificate Authority";
81 ST = "California";
82 }
83 ];
84 })} | ${pkgs.cfssl}/bin/cfssljson -bare ca
85 '';
86 };
87
88 services.nginx = {
89 enable = true;
90 virtualHosts = lib.mkMerge (map (host: {
91 ${host} = {
92 sslCertificate = "/var/ssl/${host}-cert.pem";
93 sslCertificateKey = "/var/ssl/${host}-key.pem";
94 extraConfig = ''
95 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
96 '';
97 onlySSL = true;
98 serverName = host;
99 root = pkgs.writeTextDir "index.html" "It works!";
100 };
101 }) [ "imp.example.org" "decl.example.org" ]);
102 };
103
104 systemd.services.nginx.wantedBy = lib.mkForce [];
105
106 systemd.services.certmgr.after = [ "cfssl.service" ];
107 services.certmgr = {
108 enable = true;
109 inherit svcManager;
110 inherit specs;
111 };
112
113 };
114 };
115 inherit testScript;
116 };
117in
118{
119 systemd = mkCertmgrTest {
120 svcManager = "systemd";
121 specs = {
122 decl = mkSpec { host = "decl.example.org"; service = "nginx"; action ="restart"; };
123 imp = toString (pkgs.writeText "test.json" (builtins.toJSON (
124 mkSpec { host = "imp.example.org"; service = "nginx"; action = "restart"; }
125 )));
126 };
127 testScript = ''
128 machine.wait_for_unit("cfssl.service")
129 machine.wait_until_succeeds("ls /var/ssl/decl.example.org-ca.pem")
130 machine.wait_until_succeeds("ls /var/ssl/decl.example.org-key.pem")
131 machine.wait_until_succeeds("ls /var/ssl/decl.example.org-cert.pem")
132 machine.wait_until_succeeds("ls /var/ssl/imp.example.org-ca.pem")
133 machine.wait_until_succeeds("ls /var/ssl/imp.example.org-key.pem")
134 machine.wait_until_succeeds("ls /var/ssl/imp.example.org-cert.pem")
135 machine.wait_for_unit("nginx.service")
136 assert 1 < int(machine.succeed('journalctl -u nginx | grep "Starting Nginx" | wc -l'))
137 machine.succeed("curl --cacert /var/ssl/imp.example.org-ca.pem https://imp.example.org")
138 machine.succeed(
139 "curl --cacert /var/ssl/decl.example.org-ca.pem https://decl.example.org"
140 )
141 '';
142 };
143
144 command = mkCertmgrTest {
145 svcManager = "command";
146 specs = {
147 test = mkSpec { host = "command.example.org"; action = "touch /tmp/command.executed"; };
148 };
149 testScript = ''
150 machine.wait_for_unit("cfssl.service")
151 machine.wait_until_succeeds("stat /tmp/command.executed")
152 '';
153 };
154
155}