Merge pull request 'The Simulacrum: Stage 4' (#112) from pr-simulacrum-stage-4 into master
Reviewed-on: https://forge.privatevoid.net///privatevoid.net/depot/pulls/112
This commit is contained in:
commit
5a68c052a9
7 changed files with 123 additions and 24 deletions
60
cluster/services/acme-client/augment.nix
Normal file
60
cluster/services/acme-client/augment.nix
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
lift = config;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
nowhere.names = {
|
||||||
|
"acme-v02.api.letsencrypt.org" = "stepCa";
|
||||||
|
"api.buypass.com" = "stepCa";
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.nowhere = { config, ... }: {
|
||||||
|
links.stepCa.protocol = "https";
|
||||||
|
|
||||||
|
environment.etc.step-ca-password.text = "";
|
||||||
|
|
||||||
|
services = {
|
||||||
|
step-ca = {
|
||||||
|
enable = true;
|
||||||
|
address = config.links.stepCa.ipv4;
|
||||||
|
inherit (config.links.stepCa) port;
|
||||||
|
intermediatePasswordFile = "/etc/step-ca-password";
|
||||||
|
settings = {
|
||||||
|
root = "${lift.nowhere.certs.ca}/ca.pem";
|
||||||
|
crt = "${lift.nowhere.certs.intermediate}/cert.pem";
|
||||||
|
key = "${lift.nowhere.certs.intermediate}/cert-key.pem";
|
||||||
|
address = config.links.stepCa.tuple;
|
||||||
|
db = {
|
||||||
|
type = "badgerv2";
|
||||||
|
dataSource = "/var/lib/step-ca/db";
|
||||||
|
};
|
||||||
|
authority.provisioners = [
|
||||||
|
{
|
||||||
|
type = "ACME";
|
||||||
|
name = "snakeoil";
|
||||||
|
challenges = [
|
||||||
|
"dns-01"
|
||||||
|
"http-01"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nginx.virtualHosts = {
|
||||||
|
"acme-v02.api.letsencrypt.org".locations."/".extraConfig = ''
|
||||||
|
rewrite /directory /acme/snakeoil/directory break;
|
||||||
|
'';
|
||||||
|
"api.buypass.com".locations."/".extraConfig = ''
|
||||||
|
rewrite /acme/directory /acme/snakeoil/directory break;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
defaults.environment.etc."dummy-secrets/acmeDnsApiKey".text = "ACME_DNS_DIRECT_STATIC_KEY=simulacrum";
|
||||||
|
defaults.environment.etc."dummy-secrets/acmeDnsDirectKey".text = "ACME_DNS_DIRECT_STATIC_KEY=simulacrum";
|
||||||
|
defaults.environment.etc."dummy-secrets/acmeDnsDbCredentials".text = "PGPASSWORD=simulacrum";
|
||||||
|
}
|
|
@ -2,5 +2,6 @@
|
||||||
services.acme-client = {
|
services.acme-client = {
|
||||||
nodes.client = [ "checkmate" "grail" "thunderskin" "VEGAS" "prophet" ];
|
nodes.client = [ "checkmate" "grail" "thunderskin" "VEGAS" "prophet" ];
|
||||||
nixos.client = ./client.nix;
|
nixos.client = ./client.nix;
|
||||||
|
simulacrum.augments = ./augment.nix;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 NO562A YndVtONpmfFXYB1ASnPHsfczl1UbgZ2vccIrX2pEgx0
|
|
||||||
VzH2UD583L6wBLMCo6faIGyHR4+zXXOUTgQduEiFOxI
|
|
||||||
-> ssh-ed25519 5/zT0w +67r5S6PSFEgnrTu3eZpOd3eemZUdDOE+kjUw6GDgUM
|
|
||||||
jPzlW7hePFgsABUjryePu5yergQ2Qjczmmoxuo6CK+U
|
|
||||||
-> ssh-ed25519 TCgorQ DGJPjJYpeibxM+8OwofUCdttIT2OdNbvQ66wpWQM8XU
|
|
||||||
JCNQ3bT21j2ZsxbzA6FieKIui6lsvk1p0nvNOT7YtFo
|
|
||||||
-> ssh-ed25519 d3WGuA hIl5yluwf1f0DP5ZW1MalGPCj4XFYOu2sofwJSQZ6RE
|
|
||||||
BSHoe4cdRJlPrkc+taUIaIIUknexlGttzz2d9I3jtmk
|
|
||||||
-> ssh-ed25519 YIaSKQ EbqXS/XFQHSXCbzDJmg4gGUxP9TX3+vOxWtNQDJ8ih4
|
|
||||||
hNaWzoFG2iVef4Gm30LilGXYNsVkhmVt9dOvBo02mbM
|
|
||||||
-> V]i@xRtJ-grease
|
|
||||||
NEPxMUZa76GclWOasWptt6QS7frMclp9o+kD4KCLJB7ucFOYK7xxWfAEMkjtadfP
|
|
||||||
m0bbgbw7Jcs9/lA8VNAG2D5jTBayGgpkBQZ4
|
|
||||||
--- ViqZD8mJEKIMCZ5Q+wRQWR2FX/LMEfUwoumUtHlYabQ
|
|
||||||
KAÉû¹ÝgZü<šë*DfV6·=äG»+eœ`ºpª±ï÷6°<1E>º[Û‘Û û¸¢ºÐý-H1<1B>»Ã›Íí[fV.¾¢HÁ"OhÐñŒ½j•ùö8ïßß$‰;Û‘&5<>äxw§/mŒë<C592>Ö‘ß^7î‘f5ÔµyÏŽÓûC‚´6”¹U•æýi-R=/_R<5F><52>„·==æà½1˜'Ò qÞ·ŒvÜcwø
|
|
|
@ -43,9 +43,6 @@ in {
|
||||||
links.localAuthoritativeDNS = {};
|
links.localAuthoritativeDNS = {};
|
||||||
|
|
||||||
age.secrets = {
|
age.secrets = {
|
||||||
acmeDnsDbCredentials = {
|
|
||||||
file = ./acme-dns-db-credentials.age;
|
|
||||||
};
|
|
||||||
acmeDnsDirectKey = {
|
acmeDnsDirectKey = {
|
||||||
file = ./acme-dns-direct-key.age;
|
file = ./acme-dns-direct-key.age;
|
||||||
};
|
};
|
||||||
|
@ -78,8 +75,12 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.locksmith.waitForSecrets.acme-dns = [
|
||||||
|
"patroni-acmedns"
|
||||||
|
];
|
||||||
|
|
||||||
systemd.services.acme-dns.serviceConfig.EnvironmentFile = with config.age.secrets; [
|
systemd.services.acme-dns.serviceConfig.EnvironmentFile = with config.age.secrets; [
|
||||||
acmeDnsDbCredentials.path
|
"/run/locksmith/patroni-acmedns"
|
||||||
acmeDnsDirectKey.path
|
acmeDnsDirectKey.path
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,13 @@ in
|
||||||
];
|
];
|
||||||
before = [ "acme-securedns.${domain}.service" ];
|
before = [ "acme-securedns.${domain}.service" ];
|
||||||
wants = [ "acme-finished-securedns.${domain}.target" ];
|
wants = [ "acme-finished-securedns.${domain}.target" ];
|
||||||
serviceConfig.LoadCredential = [
|
serviceConfig = {
|
||||||
|
LoadCredential = [
|
||||||
"dot-cert.pem:${dot.directory}/fullchain.pem"
|
"dot-cert.pem:${dot.directory}/fullchain.pem"
|
||||||
"dot-key.pem:${dot.directory}/key.pem"
|
"dot-key.pem:${dot.directory}/key.pem"
|
||||||
];
|
];
|
||||||
|
ExecReload = lib.mkForce [];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
security.acme.certs."securedns.${domain}" = {
|
security.acme.certs."securedns.${domain}" = {
|
||||||
|
|
|
@ -56,6 +56,21 @@ in
|
||||||
coredns = ./coredns.nix;
|
coredns = ./coredns.nix;
|
||||||
client = ./client.nix;
|
client = ./client.nix;
|
||||||
};
|
};
|
||||||
|
simulacrum = {
|
||||||
|
enable = true;
|
||||||
|
deps = [ "consul" "acme-client" "patroni" ];
|
||||||
|
settings = ./test.nix;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
patroni = {
|
||||||
|
databases.acmedns = {};
|
||||||
|
users.acmedns = {
|
||||||
|
locksmith = {
|
||||||
|
nodes = config.services.dns.nodes.authoritative;
|
||||||
|
format = "envFile";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
dns.records = {
|
dns.records = {
|
||||||
|
|
35
cluster/services/dns/test.nix
Normal file
35
cluster/services/dns/test.nix
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{ cluster, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (cluster._module.specialArgs.depot.lib.meta) domain;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nodes.nowhere = { pkgs, ... }: {
|
||||||
|
passthru = cluster;
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.knot-dns
|
||||||
|
pkgs.openssl
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
import json
|
||||||
|
nodeNames = json.loads('${builtins.toJSON cluster.config.services.dns.nodes.authoritative}')
|
||||||
|
dotNames = json.loads('${builtins.toJSON cluster.config.services.dns.nodes.coredns}')
|
||||||
|
nodes = [ n for n in machines if n.name in nodeNames ]
|
||||||
|
dotServers = [ n for n in machines if n.name in dotNames ]
|
||||||
|
|
||||||
|
start_all()
|
||||||
|
|
||||||
|
with subtest("should allow external name resolution for own domain"):
|
||||||
|
for node in nodes:
|
||||||
|
node.wait_for_unit("coredns.service")
|
||||||
|
nowhere.wait_until_succeeds("[[ $(kdig +short securedns.${domain} | wc -l) -ne 0 ]]", timeout=60)
|
||||||
|
nowhere.fail("[[ $(kdig +short example.com | wc -l) -ne 0 ]]")
|
||||||
|
|
||||||
|
with subtest("should have valid certificate on DoT endpoint"):
|
||||||
|
for node in dotServers:
|
||||||
|
node.wait_for_unit("acme-finished-securedns.${domain}.target")
|
||||||
|
nowhere.wait_until_succeeds("openssl </dev/null s_client -connect securedns.${domain}:853 -verify_return_error -strict -verify_hostname securedns.${domain}", timeout=60)
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in a new issue