1{
2 pkgs,
3 makeTest,
4 genTests,
5}:
6
7let
8 inherit (pkgs) lib;
9
10 runWithOpenSSL =
11 file: cmd:
12 pkgs.runCommand file {
13 buildInputs = [ pkgs.openssl ];
14 } cmd;
15 caKey = runWithOpenSSL "ca.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
16 caCert = runWithOpenSSL "ca.crt" ''
17 openssl req -new -x509 -sha256 -key ${caKey} -out $out -subj "/CN=test.example" -days 36500
18 '';
19 serverKey = runWithOpenSSL "server.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
20 serverKeyPath = "/var/lib/postgresql";
21 serverCert = runWithOpenSSL "server.crt" ''
22 openssl req -new -sha256 -key ${serverKey} -out server.csr -subj "/CN=db.test.example"
23 openssl x509 -req -in server.csr -CA ${caCert} -CAkey ${caKey} \
24 -CAcreateserial -out $out -days 36500 -sha256
25 '';
26 clientKey = runWithOpenSSL "client.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
27 clientCert = runWithOpenSSL "client.crt" ''
28 openssl req -new -sha256 -key ${clientKey} -out client.csr -subj "/CN=test"
29 openssl x509 -req -in client.csr -CA ${caCert} -CAkey ${caKey} \
30 -CAcreateserial -out $out -days 36500 -sha256
31 '';
32 clientKeyPath = "/root";
33
34 makeTestFor =
35 package:
36 makeTest {
37 name = "postgresql-tls-client-cert-${package.name}";
38 meta.maintainers = with lib.maintainers; [ erictapen ];
39
40 nodes.server =
41 { ... }:
42 {
43 system.activationScripts = {
44 keyPlacement.text = ''
45 mkdir -p '${serverKeyPath}'
46 cp '${serverKey}' '${serverKeyPath}/server.key'
47 chown postgres:postgres '${serverKeyPath}/server.key'
48 chmod 600 '${serverKeyPath}/server.key'
49 '';
50 };
51 services.postgresql = {
52 inherit package;
53 enable = true;
54 enableTCPIP = true;
55 ensureUsers = [
56 {
57 name = "test";
58 ensureDBOwnership = true;
59 }
60 ];
61 ensureDatabases = [ "test" ];
62 settings = {
63 ssl = "on";
64 ssl_ca_file = toString caCert;
65 ssl_cert_file = toString serverCert;
66 ssl_key_file = "${serverKeyPath}/server.key";
67 };
68 authentication = ''
69 hostssl test test ::/0 cert clientcert=verify-full
70 '';
71 };
72 networking = {
73 interfaces.eth1 = {
74 ipv6.addresses = [
75 {
76 address = "fc00::1";
77 prefixLength = 120;
78 }
79 ];
80 };
81 firewall.allowedTCPPorts = [ 5432 ];
82 };
83 };
84
85 nodes.client =
86 { ... }:
87 {
88 system.activationScripts = {
89 keyPlacement.text = ''
90 mkdir -p '${clientKeyPath}'
91 cp '${clientKey}' '${clientKeyPath}/client.key'
92 chown root:root '${clientKeyPath}/client.key'
93 chmod 600 '${clientKeyPath}/client.key'
94 '';
95 };
96 environment = {
97 variables = {
98 PGHOST = "db.test.example";
99 PGPORT = "5432";
100 PGDATABASE = "test";
101 PGUSER = "test";
102 PGSSLMODE = "verify-full";
103 PGSSLCERT = clientCert;
104 PGSSLKEY = "${clientKeyPath}/client.key";
105 PGSSLROOTCERT = caCert;
106 };
107 systemPackages = [ package ];
108 };
109 networking = {
110 interfaces.eth1 = {
111 ipv6.addresses = [
112 {
113 address = "fc00::2";
114 prefixLength = 120;
115 }
116 ];
117 };
118 hosts = {
119 "fc00::1" = [ "db.test.example" ];
120 };
121 };
122 };
123
124 testScript = ''
125 server.wait_for_unit("multi-user.target")
126 client.wait_for_unit("multi-user.target")
127 client.succeed("psql -c \"SELECT 1;\"")
128 '';
129 };
130in
131genTests { inherit makeTestFor; }