nixos: Working ACME certs
This commit is contained in:
parent
b472f4fe2e
commit
7da7458a34
@ -176,7 +176,7 @@
|
|||||||
}
|
}
|
||||||
table inet nat {
|
table inet nat {
|
||||||
chain prerouting {
|
chain prerouting {
|
||||||
iifname wan meta l4proto { udp, tcp } th dport domain redirect to :5353
|
${matchInet "meta l4proto { udp, tcp } th dport domain redirect to :5353" "estuary"}
|
||||||
}
|
}
|
||||||
chain postrouting {
|
chain postrouting {
|
||||||
ip saddr ${lib.my.colony.prefixes.all.v4} masquerade
|
ip saddr ${lib.my.colony.prefixes.all.v4} masquerade
|
||||||
|
@ -13,14 +13,14 @@ let
|
|||||||
|
|
||||||
pdns-file-record = pkgs.writeShellApplication {
|
pdns-file-record = pkgs.writeShellApplication {
|
||||||
name = "pdns-file-record";
|
name = "pdns-file-record";
|
||||||
runtimeInputs = [ pkgs.gnused ];
|
runtimeInputs = with pkgs; [ gnused pdns ];
|
||||||
text = ''
|
text = ''
|
||||||
die() {
|
die() {
|
||||||
echo "$@" >&2
|
echo "$@" >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
usage() {
|
usage() {
|
||||||
die "usage: $0 <add|del> <fqdn> [content]"
|
die "usage: $0 <zone> <add|del> <fqdn> [content]"
|
||||||
}
|
}
|
||||||
|
|
||||||
add() {
|
add() {
|
||||||
@ -47,11 +47,14 @@ let
|
|||||||
dir=/run/pdns/file-records
|
dir=/run/pdns/file-records
|
||||||
mkdir -p "$dir"
|
mkdir -p "$dir"
|
||||||
|
|
||||||
if [ $# -lt 1 ]; then
|
if [ $# -lt 2 ]; then
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
|
zone="$1"
|
||||||
|
shift
|
||||||
cmd="$1"
|
cmd="$1"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
add)
|
add)
|
||||||
add "$@";;
|
add "$@";;
|
||||||
@ -60,11 +63,48 @@ let
|
|||||||
*)
|
*)
|
||||||
usage;;
|
usage;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# TODO: This feels pretty hacky?
|
||||||
|
zDat=/var/lib/pdns/bind-zones/"$zone".dat
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "$zDat"
|
||||||
|
((serial++))
|
||||||
|
sed -i "s/^serial=.*$/serial=$serial/g" "$zDat"
|
||||||
|
sed "s/@@SERIAL@@/$serial/g" < /etc/pdns/bind-zones/"$zone".zone > /run/pdns/bind-zones/"$zone".zone
|
||||||
|
pdns_control bind-reload-now "$zone"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
|
users = {
|
||||||
|
users = {
|
||||||
|
"pdns-file-records" =
|
||||||
|
let
|
||||||
|
script = pkgs.writeShellScript "pdns-file-records-ssh.sh" ''
|
||||||
|
read -r -a args <<< "$SSH_ORIGINAL_COMMAND"
|
||||||
|
exec ${pdns-file-record}/bin/pdns-file-record "''${args[@]}"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
group = "pdns";
|
||||||
|
isSystemUser = true;
|
||||||
|
shell = pkgs.bashInteractive;
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
''command="${script}" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBSvcgbEesOgvKJLt3FLXPaLOcCIuOUYtZXXtEv6k4Yd''
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
services = {
|
||||||
|
pdns.preStart = ''
|
||||||
|
install -d -m 775 /run/pdns/file-records
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.pdns-recursor = {
|
services.pdns-recursor = {
|
||||||
enable = true;
|
enable = true;
|
||||||
dns = {
|
dns = {
|
||||||
@ -164,7 +204,7 @@ in
|
|||||||
wildcardPtr6Z = wildcardPtr6 ptrDots6;
|
wildcardPtr6Z = wildcardPtr6 ptrDots6;
|
||||||
|
|
||||||
fileRecScript = pkgs.writeText "file-record.lua" ''
|
fileRecScript = pkgs.writeText "file-record.lua" ''
|
||||||
local path = "/run/pdns/file-records/" .. qname:toStringNoDot() .. ".txt"
|
local path = "/run/pdns/file-records/" .. string.lower(qname:toStringNoDot()) .. ".txt"
|
||||||
if not os.execute("test -e " .. path) then
|
if not os.execute("test -e " .. path) then
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
@ -195,8 +235,10 @@ in
|
|||||||
|
|
||||||
@ IN ALIAS ${config.networking.fqdn}.
|
@ IN ALIAS ${config.networking.fqdn}.
|
||||||
|
|
||||||
|
$TTL 3
|
||||||
_acme-challenge IN LUA TXT ${fileRecVal}
|
_acme-challenge IN LUA TXT ${fileRecVal}
|
||||||
|
|
||||||
|
$TTL 60
|
||||||
${intRecords}
|
${intRecords}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
configuration = { lib, config, assignments, allAssignments, ... }:
|
configuration = { lib, pkgs, config, assignments, allAssignments, ... }:
|
||||||
let
|
let
|
||||||
inherit (lib) mkMerge mkIf;
|
inherit (lib) mkMerge mkIf;
|
||||||
inherit (lib.my) networkdAssignment;
|
inherit (lib.my) networkdAssignment;
|
||||||
@ -29,7 +29,13 @@
|
|||||||
|
|
||||||
secrets = {
|
secrets = {
|
||||||
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAuvP9DEsffop53Fsh7xIdeVyQSF6tSKrOUs2faq6rip";
|
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAuvP9DEsffop53Fsh7xIdeVyQSF6tSKrOUs2faq6rip";
|
||||||
files."dhparams.pem" = {};
|
files = {
|
||||||
|
"dhparams.pem" = {};
|
||||||
|
"pdns-file-records.key" = {
|
||||||
|
owner = "acme";
|
||||||
|
group = "acme";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
firewall = {
|
firewall = {
|
||||||
@ -44,6 +50,51 @@
|
|||||||
network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal;
|
network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
security = {
|
||||||
|
acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
defaults = {
|
||||||
|
email = "dev@nul.ie";
|
||||||
|
server = "https://acme-staging-v02.api.letsencrypt.org/directory";
|
||||||
|
reloadServices = [ "nginx" ];
|
||||||
|
dnsResolver = "8.8.8.8";
|
||||||
|
};
|
||||||
|
|
||||||
|
certs = {
|
||||||
|
"${config.networking.domain}" = {
|
||||||
|
extraDomainNames = [
|
||||||
|
"*.${config.networking.domain}"
|
||||||
|
];
|
||||||
|
dnsProvider = "exec";
|
||||||
|
credentialsFile =
|
||||||
|
let
|
||||||
|
script = pkgs.writeShellScript "lego-update-int.sh" ''
|
||||||
|
case "$1" in
|
||||||
|
present)
|
||||||
|
cmd=add;;
|
||||||
|
cleanup)
|
||||||
|
cmd=del;;
|
||||||
|
*)
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "$@"
|
||||||
|
exec ${pkgs.openssh}/bin/ssh \
|
||||||
|
-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
|
||||||
|
-i ${config.age.secrets."pdns-file-records.key".path} \
|
||||||
|
pdns-file-records@estuary-vm "${config.networking.domain}" "$cmd" "$2" "$3"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
pkgs.writeText "lego-exec-vars.conf" ''
|
||||||
|
EXEC_PROPAGATION_TIMEOUT=60
|
||||||
|
EXEC_POLLING_INTERVAL=2
|
||||||
|
EXEC_PATH=${script}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
nginx = {
|
nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -128,11 +128,10 @@ in
|
|||||||
|
|
||||||
table inet nat {
|
table inet nat {
|
||||||
chain prerouting {
|
chain prerouting {
|
||||||
type nat hook prerouting priority 0;
|
type nat hook prerouting priority dstnat;
|
||||||
}
|
}
|
||||||
|
|
||||||
chain postrouting {
|
chain postrouting {
|
||||||
type nat hook postrouting priority 100;
|
type nat hook postrouting priority srcnat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +156,9 @@ in
|
|||||||
mkdir -p /var/lib/pdns/bind-zones
|
mkdir -p /var/lib/pdns/bind-zones
|
||||||
loadZones start
|
loadZones start
|
||||||
'';
|
'';
|
||||||
|
postStart = ''
|
||||||
|
chmod -R g+w /run/pdns /var/lib/pdns
|
||||||
|
'';
|
||||||
|
|
||||||
# pdns reloads existing zones, so the only trigger will be if the zone files themselves change. If any new zones
|
# pdns reloads existing zones, so the only trigger will be if the zone files themselves change. If any new zones
|
||||||
# are added or removed, named.conf will change, in turn changing the overall pdns settings and causing pdns to
|
# are added or removed, named.conf will change, in turn changing the overall pdns settings and causing pdns to
|
||||||
|
@ -225,6 +225,16 @@ in
|
|||||||
my.tmproot.persistence.config.files =
|
my.tmproot.persistence.config.files =
|
||||||
concatMap (k: [ k.path "${k.path}.pub" ]) config.services.openssh.hostKeys;
|
concatMap (k: [ k.path "${k.path}.pub" ]) config.services.openssh.hostKeys;
|
||||||
})
|
})
|
||||||
|
(mkIf (config.security.acme.certs != { }) {
|
||||||
|
my.tmproot.persistence.config.directories = [
|
||||||
|
{
|
||||||
|
directory = "/var/lib/acme";
|
||||||
|
mode = "0750";
|
||||||
|
user = "acme";
|
||||||
|
group = "acme";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
})
|
||||||
(mkIf config.my.build.isDevVM {
|
(mkIf config.my.build.isDevVM {
|
||||||
fileSystems = mkVMOverride {
|
fileSystems = mkVMOverride {
|
||||||
# Hijack the "root" device for persistence in the VM
|
# Hijack the "root" device for persistence in the VM
|
||||||
|
Binary file not shown.
BIN
secrets/pdns-file-records.key.age
Normal file
BIN
secrets/pdns-file-records.key.age
Normal file
Binary file not shown.
Binary file not shown.
@ -1,9 +1,12 @@
|
|||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 Lqn0Yw 8O/4DNOBVj9N2QBh4iAcpQPFYKK884dVYBGii6QvMFs
|
-> ssh-ed25519 Lqn0Yw ybVbnUjgm3QGOZPv9A/q6zPXjZbuYe4krqe+qjrkziw
|
||||||
enBLaFlBILu61uFQwV6v8PyWG0M0JkmSfpk/tztrLls
|
SIEEGlziouUT3pzxw+C7p2IO2sDJ3xmaTrHaDGFgLOs
|
||||||
-> X25519 6X2M/VOMrMTIdgg9dRlVQmF2LWq5W53rNLzZ8UAJWVM
|
-> X25519 bq/2lRh9a3BwhwR6o9TXeuXA5AGdtlrQm8/JOyAzUEU
|
||||||
xFEKeZD+w68RyK+jlyFB82oQ6a6+FCBmYcjvc/8Wg9M
|
I5xRPDb6rUcNBXqOXefFkO2HvlYIJAG+OFkZygywkqg
|
||||||
-> uVBC-grease
|
-> 0g#WDK-grease .DWBEk*
|
||||||
70cjnfhD0khuuiGtBG7MwE2CSEgmClW9/wQeZhAdOQ4
|
Vf8DHmVCY3bfTT+CPPm5dELSid+aZJquOxjEccmkZXVKtefHlwLRx6Dh3HT5IZqR
|
||||||
--- hykfNiGB0dkhlbOabguSHtVFYtAtlFK6ld7GU8E3+WI
|
Pl2j/4SQvVf1MrPjtbkMwBhxh9zPZa7WQIBGeF6oB2kl9vyc65lXpaxRSMs2eVsv
|
||||||
Låú;sâ‹É5MÄ%²u «Ó††3#%5«#‰1gõuû¡Újt¦ËïÜc“7<E2809C><37>™žì9¬r^ìªOȸߥ´É—·bcobvÊNæ¼éƒ‘©`½Rù»÷ŠÌ;èƒØ6æ?ʱ!'â<>ªØ
|
|
||||||
|
--- /eCT0Rqu+we6CXUSP3dpd+blpQxwOG0t5rDiGfffXPs
|
||||||
|
F‚Õ
|
||||||
|
ðf<EFBFBD>§¯<19>~"[®ù%?—}Âí1ÿP~½äÒ‹$ÑNrnh*y¢ _É…÷ùï!ë¨*™©h\Ž‡è…ÀMÖú¶ õß‘…x•sÞ”ëFdÀ3¯u/$9ô½ þ¢ÜâŠºÖ Ð §è&ði¥v
|
Loading…
Reference in New Issue
Block a user