aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2020-09-02 00:23:50 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2020-09-02 00:23:50 +0200
commit5dda316b382211733cda7163b33bf388dd052671 (patch)
tree9b3487e6455dbd445f1cc5048ee16aba78f69e53
parent740a6506f419bdcfb082f1cfde7553735dfd0570 (diff)
downloadNix-5dda316b382211733cda7163b33bf388dd052671.tar.gz
Nix-5dda316b382211733cda7163b33bf388dd052671.tar.zst
Nix-5dda316b382211733cda7163b33bf388dd052671.zip
Use zrepl to make zfs backups
-rw-r--r--modules/default.nix1
-rw-r--r--modules/private/environment.nix16
-rw-r--r--modules/private/system/dilion.nix41
-rw-r--r--modules/private/system/eldiron.nix63
-rw-r--r--modules/zrepl.nix46
m---------nixops/secrets0
-rw-r--r--pkgs/default.nix1
-rw-r--r--pkgs/zrepl/default.nix14
8 files changed, 160 insertions, 22 deletions
diff --git a/modules/default.nix b/modules/default.nix
index a503f92..03b9adc 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -19,5 +19,6 @@
19 naemon = ./naemon; 19 naemon = ./naemon;
20 20
21 php-application = ./websites/php-application.nix; 21 php-application = ./websites/php-application.nix;
22 zrepl = ./zrepl.nix;
22 websites = ./websites; 23 websites = ./websites;
23} // (if builtins.pathExists ./private then import ./private else {}) 24} // (if builtins.pathExists ./private then import ./private else {})
diff --git a/modules/private/environment.nix b/modules/private/environment.nix
index 6a2cea0..0f6f3e2 100644
--- a/modules/private/environment.nix
+++ b/modules/private/environment.nix
@@ -462,6 +462,22 @@ in
462 }; 462 };
463 }; 463 };
464 }; 464 };
465 zrepl_backup = mkOption {
466 type = submodule {
467 options = {
468 ssh_key = mkOption {
469 description = "SSH key information";
470 type = submodule {
471 options = {
472 public = mkOption { type = str; description = "Public part of the key"; };
473 private = mkOption { type = lines; description = "Private part of the key"; };
474 };
475 };
476 };
477 mysql = mkMysqlOptions "Zrepl" {};
478 };
479 };
480 };
465 rsync_backup = mkOption { 481 rsync_backup = mkOption {
466 description ='' 482 description =''
467 Rsync backup configuration from controlled host 483 Rsync backup configuration from controlled host
diff --git a/modules/private/system/dilion.nix b/modules/private/system/dilion.nix
index 14155ef..cc4297e 100644
--- a/modules/private/system/dilion.nix
+++ b/modules/private/system/dilion.nix
@@ -59,25 +59,18 @@
59 programs.zsh.enable = true; 59 programs.zsh.enable = true;
60 60
61 users.users.backup = { 61 users.users.backup = {
62 home = "/var/lib/backup";
63 createHome = true;
64 hashedPassword = "!"; 62 hashedPassword = "!";
65 isSystemUser = true; 63 isSystemUser = true;
64 extraGroups = [ "keys" ];
66 shell = pkgs.bashInteractive; 65 shell = pkgs.bashInteractive;
67 openssh.authorizedKeys.keys = let 66 openssh.authorizedKeys.keys = let
67 zreplConfig = config.secrets.fullPaths."zrepl/zrepl.yml";
68 in 68 in
69 ["command=\"${pkgs.rrsync_sudo}/bin/rrsync /var/lib/backup/eldiron/\" ${config.myEnv.rsync_backup.ssh_key.public}"]; 69 ["command=\"${pkgs.zrepl}/bin/zrepl stdinserver --config ${zreplConfig} eldiron\",restrict ${config.myEnv.zrepl_backup.ssh_key.public}"];
70 }; 70 };
71 security.sudo.extraRules = pkgs.lib.mkAfter [ 71 security.sudo.extraRules = pkgs.lib.mkAfter [
72 { 72 {
73 commands = [ 73 commands = [
74 { command = "${pkgs.rsync}/bin/rsync"; options = [ "NOPASSWD" ]; }
75 ];
76 users = [ "backup" ];
77 runAs = "root";
78 }
79 {
80 commands = [
81 { command = "/home/immae/.nix-profile/root_scripts/*"; options = [ "NOPASSWD" ]; } 74 { command = "/home/immae/.nix-profile/root_scripts/*"; options = [ "NOPASSWD" ]; }
82 ]; 75 ];
83 users = [ "immae" ]; 76 users = [ "immae" ];
@@ -86,11 +79,6 @@
86 ]; 79 ];
87 80
88 boot.kernel.sysctl."vm.nr_hugepages" = 256; # for xmr-stak 81 boot.kernel.sysctl."vm.nr_hugepages" = 256; # for xmr-stak
89 system.activationScripts.backup_home = ''
90 chown root:root /var/lib/backup
91 install -m 0750 -o backup -g root -d /var/lib/backup/eldiron
92 '';
93
94 system.activationScripts.libvirtd_exports = '' 82 system.activationScripts.libvirtd_exports = ''
95 install -m 0755 -o root -g root -d /var/lib/caldance 83 install -m 0755 -o root -g root -d /var/lib/caldance
96 ''; 84 '';
@@ -192,6 +180,29 @@
192 }; 180 };
193 }; 181 };
194 182
183 systemd.services.zrepl.serviceConfig.RuntimeDirectory = lib.mkForce "zrepl zrepl/stdinserver";
184 systemd.services.zrepl.serviceConfig.User = "backup";
185 # zfs allow backup create,mount,receive,destroy,rename,snapshot,hold,bookmark,release zpool/backup
186 services.zrepl = {
187 enable = true;
188 config = ''
189 global:
190 control:
191 sockpath: /run/zrepl/control
192 serve:
193 stdinserver:
194 sockdir: /run/zrepl/stdinserver
195 jobs:
196 - type: sink
197 # must not change
198 name: "backup-from-eldiron"
199 root_fs: "zpool/backup"
200 serve:
201 type: stdinserver
202 client_identities:
203 - eldiron
204 '';
205 };
195 # This value determines the NixOS release with which your system is 206 # This value determines the NixOS release with which your system is
196 # to be compatible, in order to avoid breaking some software such as 207 # to be compatible, in order to avoid breaking some software such as
197 # database servers. You should change this only after NixOS release 208 # database servers. You should change this only after NixOS release
diff --git a/modules/private/system/eldiron.nix b/modules/private/system/eldiron.nix
index 8a5d11c..83e52b8 100644
--- a/modules/private/system/eldiron.nix
+++ b/modules/private/system/eldiron.nix
@@ -19,9 +19,6 @@
19 }; 19 };
20 20
21 services.zfs = { 21 services.zfs = {
22 autoSnapshot = {
23 enable = true;
24 };
25 autoScrub = { 22 autoScrub = {
26 enable = true; 23 enable = true;
27 }; 24 };
@@ -64,11 +61,11 @@
64 61
65 secrets.keys = [ 62 secrets.keys = [
66 { 63 {
67 dest = "rsync_backup/identity"; 64 dest = "zrepl_backup/identity";
68 user = "root"; 65 user = "root";
69 group = "root"; 66 group = "root";
70 permissions = "0400"; 67 permissions = "0400";
71 text = config.myEnv.rsync_backup.ssh_key.private; 68 text = config.myEnv.zrepl_backup.ssh_key.private;
72 } 69 }
73 ]; 70 ];
74 programs.ssh.knownHosts.dilion = { 71 programs.ssh.knownHosts.dilion = {
@@ -104,8 +101,6 @@
104 mailto = "cron@immae.eu"; 101 mailto = "cron@immae.eu";
105 systemCronJobs = [ 102 systemCronJobs = [
106 '' 103 ''
107 # The star after /var/lib/* avoids deleting all folders in case of problem
108 0 3,9,15,21 * * * root rsync -e "ssh -i /var/secrets/rsync_backup/identity" --new-compress -aAXv --delete --numeric-ids --super --rsync-path="sudo rsync" /var/lib/* backup@dilion.immae.eu: > /dev/null
109 0 0 * * * root journalctl -q --since="25 hours ago" -u postfix -t postfix/smtpd -g "immae.eu.*Recipient address rejected" 104 0 0 * * * root journalctl -q --since="25 hours ago" -u postfix -t postfix/smtpd -g "immae.eu.*Recipient address rejected"
110 # Need a way to blacklist properly 105 # Need a way to blacklist properly
111 # 0 0 * * * root journalctl -q --since="25 hours ago" -u postfix -t postfix/smtpd -g "NOQUEUE:" 106 # 0 0 * * * root journalctl -q --since="25 hours ago" -u postfix -t postfix/smtpd -g "NOQUEUE:"
@@ -121,6 +116,60 @@
121 }; 116 };
122 environment.systemPackages = [ pkgs.bindfs ]; 117 environment.systemPackages = [ pkgs.bindfs ];
123 118
119 services.zrepl = {
120 enable = true;
121 config = let
122 redis_dump = pkgs.writeScript "redis-dump" ''
123 #! ${pkgs.stdenv.shell}
124 ${pkgs.redis}/bin/redis-cli bgsave
125 '';
126 in ''
127 jobs:
128 - type: push
129 # must not change
130 name: "backup-to-dilion"
131 filesystems:
132 "zpool/root": true
133 "zpool/root/etc": true
134 "zpool/root/var<": true
135 connect:
136 type: ssh+stdinserver
137 host: dilion.immae.eu
138 user: backup
139 port: 22
140 identity_file: ${config.secrets.fullPaths."zrepl_backup/identity"}
141 snapshotting:
142 type: periodic
143 prefix: zrepl_
144 interval: 15m
145 hooks:
146 - type: mysql-lock-tables
147 dsn: "${config.myEnv.zrepl_backup.mysql.user}:${config.myEnv.zrepl_backup.mysql.password}@tcp(localhost)/"
148 filesystems:
149 "zpool/root/var": true
150 - type: command
151 path: ${redis_dump}
152 err_is_fatal: false
153 filesystems:
154 "zpool/root/var": true
155 send:
156 encrypted: true
157 pruning:
158 keep_sender:
159 - type: not_replicated
160 - type: regex
161 regex: "^manual_.*"
162 - type: grid
163 grid: 1x1h(keep=all) | 24x1h | 7x1d | 4x7d | 6x30d
164 regex: "^zrepl_.*"
165 keep_receiver:
166 - type: regex
167 regex: "^manual_.*"
168 - type: grid
169 grid: 1x1h(keep=all) | 24x1h | 7x1d | 4x7d | 6x30d
170 regex: "^zrepl_.*"
171 '';
172 };
124 # This value determines the NixOS release with which your system is 173 # This value determines the NixOS release with which your system is
125 # to be compatible, in order to avoid breaking some software such as 174 # to be compatible, in order to avoid breaking some software such as
126 # database servers. You should change this only after NixOS release 175 # database servers. You should change this only after NixOS release
diff --git a/modules/zrepl.nix b/modules/zrepl.nix
new file mode 100644
index 0000000..cb74082
--- /dev/null
+++ b/modules/zrepl.nix
@@ -0,0 +1,46 @@
1{ config, lib, pkgs, ... }:
2let
3 cfg = config.services.zrepl;
4in
5{
6 options = {
7 services.zrepl = {
8 enable = lib.mkEnableOption "Enable the zrepl daemon";
9
10 config = lib.mkOption {
11 type = lib.types.lines;
12 default = "";
13 description = "Configuration";
14 };
15 };
16 };
17
18 config = lib.mkIf cfg.enable {
19 secrets.keys = [
20 {
21 dest = "zrepl/zrepl.yml";
22 permissions = "0400";
23 text = cfg.config;
24 user = config.systemd.services.zrepl.serviceConfig.User or "root";
25 group = config.systemd.services.zrepl.serviceConfig.Group or "root";
26 }
27 ];
28 services.filesWatcher.zrepl = {
29 restart = true;
30 paths = [ config.secrets.fullPaths."zrepl/zrepl.yml" ];
31 };
32 systemd.services.zrepl = {
33 description = "zrepl daemon";
34 wantedBy = [ "multi-user.target" ];
35 path = [ pkgs.zfs pkgs.openssh ];
36 serviceConfig = {
37 ExecStart =
38 let configFile = config.secrets.fullPaths."zrepl/zrepl.yml";
39 in "${pkgs.zrepl}/bin/zrepl daemon --config ${configFile}";
40 Type = "simple";
41 RuntimeDirectory= "zrepl";
42 RuntimeDirectoryMode= "0700";
43 };
44 };
45 };
46}
diff --git a/nixops/secrets b/nixops/secrets
Subproject d34d5490226809ff9863ce4e66bd59a68ead861 Subproject 79b991028b09aa59f719059de8dc1fba7d6b04f
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 702f4cf..4b3d4b3 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -70,4 +70,5 @@ rec {
70 }; 70 };
71 71
72 fiche = callPackage ./fiche { inherit mylibs; }; 72 fiche = callPackage ./fiche { inherit mylibs; };
73 zrepl = callPackage ./zrepl {};
73} 74}
diff --git a/pkgs/zrepl/default.nix b/pkgs/zrepl/default.nix
new file mode 100644
index 0000000..1e89098
--- /dev/null
+++ b/pkgs/zrepl/default.nix
@@ -0,0 +1,14 @@
1{ buildGoModule, fetchFromGitHub }:
2buildGoModule rec {
3 name = "zrepl-${version}";
4 version = "0.3.0";
5 src = fetchFromGitHub {
6 owner = "zrepl";
7 repo = "zrepl";
8 rev = "v${version}";
9 sha256 = "11wfdvi3f4yw7kdapf0l38illnnn7jgi5cp4whrg5zsqyc0wqrym";
10 };
11 modSha256 = "0gh0x8321dhk1nhg1as0bl1bxlblrrcxxl1rb1d8825ly8bhcdkb";
12 vendorSha256 = "0gh0x8321dhk1nhg1as0bl1bxlblrrcxxl1rb1d8825ly8bhcdkb";
13 subPackages = [ "." ];
14}