blob: fea9345ba708026fe7321a8b063aee1b50533d48 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.services.remoteDiskUnlock;
unlockScript = pkgs.writeShellScript "remote-disk-unlock" ''
#!/usr/bin/env bash
set -euo pipefail
SSH_KEY="$CREDENTIALS_DIRECTORY/ssh-key"
PASSPHRASE_FILE="$CREDENTIALS_DIRECTORY/passphrase"
for server in ${concatStringsSep " " cfg.hosts}; do
echo "Probing host $server on port 22"
if ${pkgs.netcat}/bin/nc -z -w 5 "$server" 22 2>/dev/null; then
echo "Host $server is already unlocked, skipping"
continue
fi
echo "No response on port 22, probing host $server on port 911"
if ${pkgs.netcat}/bin/nc -z -w 5 "$server" 911 2>/dev/null; then
echo "Host $server is waiting for unlock - unlocking"
${pkgs.openssh}/bin/ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null \
-i "$SSH_KEY" -p 911 "root@$server" < "$PASSPHRASE_FILE" || true
else
echo "Host $server is down, retry later"
fi
done
'';
in
{
options.services.remoteDiskUnlock = {
enable = mkEnableOption "remote disk unlock service";
hosts = mkOption {
type = types.listOf types.str;
default = [ ];
description = "List of hostnames/IPs to monitor and unlock";
example = [
"server1.local"
"192.168.1.100"
];
};
sshKeyPath = mkOption {
type = types.path;
description = "Path to SSH private key";
example = "/run/agenix/disk-unlock-key";
};
passphrasePath = mkOption {
type = types.path;
description = "Path to disk passphrase file";
example = "/run/agenix/disk-passphrase";
};
interval = mkOption {
type = types.str;
default = "10min";
description = "How often to check hosts (systemd timer format)";
};
};
config = mkIf cfg.enable {
systemd.services.remote-disk-unlock = {
description = "Unlock remote encrypted disks";
serviceConfig = {
Type = "oneshot";
ExecStart = "${unlockScript}";
DynamicUser = true;
LoadCredential = [
"ssh-key:${cfg.sshKeyPath}"
"passphrase:${cfg.passphrasePath}"
];
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
NoNewPrivileges = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
RestrictNamespaces = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
};
};
systemd.timers.remote-disk-unlock = {
description = "Check and unlock remote disks periodically";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1min";
OnUnitActiveSec = cfg.interval;
Persistent = false;
};
};
};
}
|