naemon = ./naemon;
php-application = ./websites/php-application.nix;
+ zrepl = ./zrepl.nix;
websites = ./websites;
} // (if builtins.pathExists ./private then import ./private else {})
};
};
};
+ zrepl_backup = mkOption {
+ type = submodule {
+ options = {
+ ssh_key = mkOption {
+ description = "SSH key information";
+ type = submodule {
+ options = {
+ public = mkOption { type = str; description = "Public part of the key"; };
+ private = mkOption { type = lines; description = "Private part of the key"; };
+ };
+ };
+ };
+ mysql = mkMysqlOptions "Zrepl" {};
+ };
+ };
+ };
rsync_backup = mkOption {
description =''
Rsync backup configuration from controlled host
programs.zsh.enable = true;
users.users.backup = {
- home = "/var/lib/backup";
- createHome = true;
hashedPassword = "!";
isSystemUser = true;
+ extraGroups = [ "keys" ];
shell = pkgs.bashInteractive;
openssh.authorizedKeys.keys = let
+ zreplConfig = config.secrets.fullPaths."zrepl/zrepl.yml";
in
- ["command=\"${pkgs.rrsync_sudo}/bin/rrsync /var/lib/backup/eldiron/\" ${config.myEnv.rsync_backup.ssh_key.public}"];
+ ["command=\"${pkgs.zrepl}/bin/zrepl stdinserver --config ${zreplConfig} eldiron\",restrict ${config.myEnv.zrepl_backup.ssh_key.public}"];
};
security.sudo.extraRules = pkgs.lib.mkAfter [
- {
- commands = [
- { command = "${pkgs.rsync}/bin/rsync"; options = [ "NOPASSWD" ]; }
- ];
- users = [ "backup" ];
- runAs = "root";
- }
{
commands = [
{ command = "/home/immae/.nix-profile/root_scripts/*"; options = [ "NOPASSWD" ]; }
];
boot.kernel.sysctl."vm.nr_hugepages" = 256; # for xmr-stak
- system.activationScripts.backup_home = ''
- chown root:root /var/lib/backup
- install -m 0750 -o backup -g root -d /var/lib/backup/eldiron
- '';
-
system.activationScripts.libvirtd_exports = ''
install -m 0755 -o root -g root -d /var/lib/caldance
'';
};
};
+ systemd.services.zrepl.serviceConfig.RuntimeDirectory = lib.mkForce "zrepl zrepl/stdinserver";
+ systemd.services.zrepl.serviceConfig.User = "backup";
+ # zfs allow backup create,mount,receive,destroy,rename,snapshot,hold,bookmark,release zpool/backup
+ services.zrepl = {
+ enable = true;
+ config = ''
+ global:
+ control:
+ sockpath: /run/zrepl/control
+ serve:
+ stdinserver:
+ sockdir: /run/zrepl/stdinserver
+ jobs:
+ - type: sink
+ # must not change
+ name: "backup-from-eldiron"
+ root_fs: "zpool/backup"
+ serve:
+ type: stdinserver
+ client_identities:
+ - eldiron
+ '';
+ };
# This value determines the NixOS release with which your system is
# to be compatible, in order to avoid breaking some software such as
# database servers. You should change this only after NixOS release
};
services.zfs = {
- autoSnapshot = {
- enable = true;
- };
autoScrub = {
enable = true;
};
secrets.keys = [
{
- dest = "rsync_backup/identity";
+ dest = "zrepl_backup/identity";
user = "root";
group = "root";
permissions = "0400";
- text = config.myEnv.rsync_backup.ssh_key.private;
+ text = config.myEnv.zrepl_backup.ssh_key.private;
}
];
programs.ssh.knownHosts.dilion = {
mailto = "cron@immae.eu";
systemCronJobs = [
''
- # The star after /var/lib/* avoids deleting all folders in case of problem
- 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
0 0 * * * root journalctl -q --since="25 hours ago" -u postfix -t postfix/smtpd -g "immae.eu.*Recipient address rejected"
# Need a way to blacklist properly
# 0 0 * * * root journalctl -q --since="25 hours ago" -u postfix -t postfix/smtpd -g "NOQUEUE:"
};
environment.systemPackages = [ pkgs.bindfs ];
+ services.zrepl = {
+ enable = true;
+ config = let
+ redis_dump = pkgs.writeScript "redis-dump" ''
+ #! ${pkgs.stdenv.shell}
+ ${pkgs.redis}/bin/redis-cli bgsave
+ '';
+ in ''
+ jobs:
+ - type: push
+ # must not change
+ name: "backup-to-dilion"
+ filesystems:
+ "zpool/root": true
+ "zpool/root/etc": true
+ "zpool/root/var<": true
+ connect:
+ type: ssh+stdinserver
+ host: dilion.immae.eu
+ user: backup
+ port: 22
+ identity_file: ${config.secrets.fullPaths."zrepl_backup/identity"}
+ snapshotting:
+ type: periodic
+ prefix: zrepl_
+ interval: 15m
+ hooks:
+ - type: mysql-lock-tables
+ dsn: "${config.myEnv.zrepl_backup.mysql.user}:${config.myEnv.zrepl_backup.mysql.password}@tcp(localhost)/"
+ filesystems:
+ "zpool/root/var": true
+ - type: command
+ path: ${redis_dump}
+ err_is_fatal: false
+ filesystems:
+ "zpool/root/var": true
+ send:
+ encrypted: true
+ pruning:
+ keep_sender:
+ - type: not_replicated
+ - type: regex
+ regex: "^manual_.*"
+ - type: grid
+ grid: 1x1h(keep=all) | 24x1h | 7x1d | 4x7d | 6x30d
+ regex: "^zrepl_.*"
+ keep_receiver:
+ - type: regex
+ regex: "^manual_.*"
+ - type: grid
+ grid: 1x1h(keep=all) | 24x1h | 7x1d | 4x7d | 6x30d
+ regex: "^zrepl_.*"
+ '';
+ };
# This value determines the NixOS release with which your system is
# to be compatible, in order to avoid breaking some software such as
# database servers. You should change this only after NixOS release
--- /dev/null
+{ config, lib, pkgs, ... }:
+let
+ cfg = config.services.zrepl;
+in
+{
+ options = {
+ services.zrepl = {
+ enable = lib.mkEnableOption "Enable the zrepl daemon";
+
+ config = lib.mkOption {
+ type = lib.types.lines;
+ default = "";
+ description = "Configuration";
+ };
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ secrets.keys = [
+ {
+ dest = "zrepl/zrepl.yml";
+ permissions = "0400";
+ text = cfg.config;
+ user = config.systemd.services.zrepl.serviceConfig.User or "root";
+ group = config.systemd.services.zrepl.serviceConfig.Group or "root";
+ }
+ ];
+ services.filesWatcher.zrepl = {
+ restart = true;
+ paths = [ config.secrets.fullPaths."zrepl/zrepl.yml" ];
+ };
+ systemd.services.zrepl = {
+ description = "zrepl daemon";
+ wantedBy = [ "multi-user.target" ];
+ path = [ pkgs.zfs pkgs.openssh ];
+ serviceConfig = {
+ ExecStart =
+ let configFile = config.secrets.fullPaths."zrepl/zrepl.yml";
+ in "${pkgs.zrepl}/bin/zrepl daemon --config ${configFile}";
+ Type = "simple";
+ RuntimeDirectory= "zrepl";
+ RuntimeDirectoryMode= "0700";
+ };
+ };
+ };
+}
-Subproject commit d34d5490226809ff9863ce4e66bd59a68ead861c
+Subproject commit 79b991028b09aa59f719059de8dc1fba7d6b04fd
};
fiche = callPackage ./fiche { inherit mylibs; };
+ zrepl = callPackage ./zrepl {};
}
--- /dev/null
+{ buildGoModule, fetchFromGitHub }:
+buildGoModule rec {
+ name = "zrepl-${version}";
+ version = "0.3.0";
+ src = fetchFromGitHub {
+ owner = "zrepl";
+ repo = "zrepl";
+ rev = "v${version}";
+ sha256 = "11wfdvi3f4yw7kdapf0l38illnnn7jgi5cp4whrg5zsqyc0wqrym";
+ };
+ modSha256 = "0gh0x8321dhk1nhg1as0bl1bxlblrrcxxl1rb1d8825ly8bhcdkb";
+ vendorSha256 = "0gh0x8321dhk1nhg1as0bl1bxlblrrcxxl1rb1d8825ly8bhcdkb";
+ subPackages = [ "." ];
+}