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 { pkgs, lib, config, ... }:
{
dns.zones."ctu.cx".subdomains."restic.${config.networking.hostName}".CNAME = [ "${config.networking.hostName}.ctu.cx." ];
users.groups.rclone-restic-server = {};
users.users.rclone-restic-server = {
isSystemUser = true;
home = "/var/lib/rclone-restic-server";
group = "rclone-restic-server";
};
age.secrets = {
rclone-config = {
file = ../../secrets/wanderduene/rclone-config.age;
owner = "rclone-restic-server";
};
restic-server-htpasswd = {
file = ../../secrets/wanderduene/restic-server-htpasswd.age;
owner = "nginx";
};
};
systemd.services.rclone-restic-server = {
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
onFailure = [ "email-notify@%i.service" ];
serviceConfig = {
User = "rclone-restic-server";
Group = "rclone-restic-server";
Restart = "always";
RestartSec = "5";
KillMode = "mixed";
KillSignal = "SIGTERM";
TimeoutStopSec = "5s";
ExecReload = "/bin/kill -USR1 $MAINPID";
ExecStart = "${pkgs.rclone}/bin/rclone --config ${config.age.secrets.rclone-config.path} serve restic --append-only --addr [::1]:8000 hetzner-storage:";
PrivateTmp = true;
PrivateDevices = true;
ProtectHome = true;
ProtectSystem = "full";
CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
NoNewPrivileges = true;
};
};
services.nginx = {
enable = true;
virtualHosts."restic.${config.networking.hostName}.ctu.cx" = {
enableACME = true;
forceSSL = true;
kTLS = true;
locations."/" = {
proxyPass = "http://[::1]:8000/";
extraConfig = ''
client_max_body_size 10G;
auth_basic Auth;
auth_basic_user_file ${config.age.secrets.restic-server-htpasswd.path};
'';
};
};
};
}