Skip to content

Commit

Permalink
Merge pull request #317567 from erictapen/postgresql-tls-client-cert-…
Browse files Browse the repository at this point in the history
…test

nixos/tests/postgresql: add tls client cert test
  • Loading branch information
Ma27 authored Jul 12, 2024
2 parents dc6634e + 7f7ec52 commit 8d75ee9
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,7 @@ in {
postgresql = handleTest ./postgresql.nix {};
postgresql-jit = handleTest ./postgresql-jit.nix {};
postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {};
postgresql-tls-client-cert = handleTest ./postgresql-tls-client-cert.nix {};
powerdns = handleTest ./powerdns.nix {};
powerdns-admin = handleTest ./powerdns-admin.nix {};
power-profiles-daemon = handleTest ./power-profiles-daemon.nix {};
Expand Down
141 changes: 141 additions & 0 deletions nixos/tests/postgresql-tls-client-cert.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{ system ? builtins.currentSystem
, config ? { }
, pkgs ? import ../.. { inherit system config; }
, package ? null
}:

with import ../lib/testing-python.nix { inherit system pkgs; };

let
lib = pkgs.lib;

# Makes a test for a PostgreSQL package, given by name and looked up from `pkgs`.
makeTestAttribute = name:
{
inherit name;
value = makePostgresqlTlsClientCertTest pkgs."${name}";
};

makePostgresqlTlsClientCertTest = pkg:
let
runWithOpenSSL = file: cmd: pkgs.runCommand file
{
buildInputs = [ pkgs.openssl ];
}
cmd;
caKey = runWithOpenSSL "ca.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
caCert = runWithOpenSSL
"ca.crt"
''
openssl req -new -x509 -sha256 -key ${caKey} -out $out -subj "/CN=test.example" -days 36500
'';
serverKey =
runWithOpenSSL "server.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
serverKeyPath = "/var/lib/postgresql";
serverCert =
runWithOpenSSL "server.crt" ''
openssl req -new -sha256 -key ${serverKey} -out server.csr -subj "/CN=db.test.example"
openssl x509 -req -in server.csr -CA ${caCert} -CAkey ${caKey} \
-CAcreateserial -out $out -days 36500 -sha256
'';
clientKey =
runWithOpenSSL "client.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
clientCert =
runWithOpenSSL "client.crt" ''
openssl req -new -sha256 -key ${clientKey} -out client.csr -subj "/CN=test"
openssl x509 -req -in client.csr -CA ${caCert} -CAkey ${caKey} \
-CAcreateserial -out $out -days 36500 -sha256
'';
clientKeyPath = "/root";

in
makeTest {
name = "postgresql-tls-client-cert-${pkg.name}";
meta.maintainers = with lib.maintainers; [ erictapen ];

nodes.server = { ... }: {
system.activationScripts = {
keyPlacement.text = ''
mkdir -p '${serverKeyPath}'
cp '${serverKey}' '${serverKeyPath}/server.key'
chown postgres:postgres '${serverKeyPath}/server.key'
chmod 600 '${serverKeyPath}/server.key'
'';
};
services.postgresql = {
package = pkg;
enable = true;
enableTCPIP = true;
ensureUsers = [
{
name = "test";
ensureDBOwnership = true;
}
];
ensureDatabases = [ "test" ];
settings = {
ssl = "on";
ssl_ca_file = toString caCert;
ssl_cert_file = toString serverCert;
ssl_key_file = "${serverKeyPath}/server.key";
};
authentication = ''
hostssl test test ::/0 cert clientcert=verify-full
'';
};
networking = {
interfaces.eth1 = {
ipv6.addresses = [
{ address = "fc00::1"; prefixLength = 120; }
];
};
firewall.allowedTCPPorts = [ 5432 ];
};
};

nodes.client = { ... }: {
system.activationScripts = {
keyPlacement.text = ''
mkdir -p '${clientKeyPath}'
cp '${clientKey}' '${clientKeyPath}/client.key'
chown root:root '${clientKeyPath}/client.key'
chmod 600 '${clientKeyPath}/client.key'
'';
};
environment = {
variables = {
PGHOST = "db.test.example";
PGPORT = "5432";
PGDATABASE = "test";
PGUSER = "test";
PGSSLMODE = "verify-full";
PGSSLCERT = clientCert;
PGSSLKEY = "${clientKeyPath}/client.key";
PGSSLROOTCERT = caCert;
};
systemPackages = [ pkg ];
};
networking = {
interfaces.eth1 = {
ipv6.addresses = [
{ address = "fc00::2"; prefixLength = 120; }
];
};
hosts = { "fc00::1" = [ "db.test.example" ]; };
};
};

testScript = ''
server.wait_for_unit("multi-user.target")
client.wait_for_unit("multi-user.target")
client.succeed("psql -c \"SELECT 1;\"")
'';
};

in
if package == null then
# all-tests.nix: Maps the generic function over all attributes of PostgreSQL packages
builtins.listToAttrs (map makeTestAttribute (builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs)))
else
# Called directly from <package>.tests
makePostgresqlTlsClientCertTest package

0 comments on commit 8d75ee9

Please sign in to comment.