From 8bf83d7a27c08599820f145c073d979744b81c63 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Isma=C3=ABl=20Bouya?= Date: Thu, 13 Feb 2020 13:07:06 +0100 Subject: [PATCH] Add rsync backup via dilion --- modules/private/system/dilion.nix | 25 +++++++++++++++++++++++++ modules/private/system/eldiron.nix | 19 ++++++++++++++++++- pkgs/default.nix | 1 + pkgs/rrsync_sudo/default.nix | 8 ++++++++ pkgs/rrsync_sudo/sudo.patch | 20 ++++++++++++++++++++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 pkgs/rrsync_sudo/default.nix create mode 100644 pkgs/rrsync_sudo/sudo.patch diff --git a/modules/private/system/dilion.nix b/modules/private/system/dilion.nix index 258506b..dbfd38f 100644 --- a/modules/private/system/dilion.nix +++ b/modules/private/system/dilion.nix @@ -41,6 +41,31 @@ programs.zsh.enable = true; + users.users.backup = { + home = "/var/lib/backup"; + createHome = true; + hashedPassword = "!"; + isSystemUser = true; + shell = pkgs.bashInteractive; + openssh.authorizedKeys.keys = let + in + ["command=\"${pkgs.rrsync_sudo}/bin/rrsync /var/lib/backup/eldiron/\" ${config.myEnv.rsync_backup.ssh_key.public}"]; + }; + security.sudo.extraRules = [ + { + commands = [ + { command = "${pkgs.rsync}/bin/rsync"; options = [ "NOPASSWD" ]; } + ]; + users = [ "backup" ]; + runAs = "root"; + } + ]; + + system.activationScripts.backup_home = '' + chown root:root /var/lib/backup + install -m 0750 -o backup -g root -d /var/lib/backup/eldiron + ''; + time.timeZone = "Europe/Paris"; nix = { useSandbox = "relaxed"; diff --git a/modules/private/system/eldiron.nix b/modules/private/system/eldiron.nix index 5e3d45c..ab48ab4 100644 --- a/modules/private/system/eldiron.nix +++ b/modules/private/system/eldiron.nix @@ -39,6 +39,23 @@ services.duplyBackup.enable = true; services.duplyBackup.profiles.oldies.rootDir = "/var/lib/oldies"; + secrets.keys = [ + { + dest = "rsync_backup/identity"; + user = "root"; + group = "root"; + permissions = "0400"; + text = config.myEnv.rsync_backup.ssh_key.private; + } + ]; + programs.ssh.knownHosts.dilion = { + hostNames = ["dilion.immae.eu"]; + publicKey = let + profile = config.myEnv.rsync_backup.profiles.dilion; + in + "${profile.host_key_type} ${profile.host_key}"; + }; + deployment = { targetEnv = "hetzner"; hetzner = { @@ -65,7 +82,7 @@ systemCronJobs = [ '' # The star after /var/lib/* avoids deleting all folders in case of problem - 0 3,9,15,21 * * * root rsync -e "ssh -i /root/.ssh/id_charon_vpn" --new-compress -aAXv --delete --numeric-ids --super --rsync-path="sudo rsync" /var/lib/* immae@immae.eu: > /dev/null + 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 -g "immae.eu.*Recipient address rejected" '' ]; diff --git a/pkgs/default.nix b/pkgs/default.nix index 2ad79a2..b6f9eae 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -24,6 +24,7 @@ rec { pg_activity = callPackage ../pkgs/pg_activity { inherit mylibs; }; pgloader = callPackage ../pkgs/pgloader {}; predixy = callPackage ../pkgs/predixy { inherit mylibs; }; + rrsync_sudo = callPackage ../pkgs/rrsync_sudo {}; telegram-cli = callPackage ../pkgs/telegram-cli { inherit mylibs; }; telegram-history-dump = callPackage ../pkgs/telegram-history-dump { inherit mylibs; }; telegramircd = callPackage ../pkgs/telegramircd { inherit mylibs; telethon = callPackage ../pkgs/telethon_sync {}; }; diff --git a/pkgs/rrsync_sudo/default.nix b/pkgs/rrsync_sudo/default.nix new file mode 100644 index 0000000..7a47320 --- /dev/null +++ b/pkgs/rrsync_sudo/default.nix @@ -0,0 +1,8 @@ +{ rrsync }: + +rrsync.overrideAttrs(old: { + patches = old.patches or [] ++ [ ./sudo.patch ]; + postPatch = old.postPatch + '' + substituteInPlace support/rrsync --replace /usr/bin/sudo /run/wrappers/bin/sudo + ''; +}) diff --git a/pkgs/rrsync_sudo/sudo.patch b/pkgs/rrsync_sudo/sudo.patch new file mode 100644 index 0000000..6de9cc9 --- /dev/null +++ b/pkgs/rrsync_sudo/sudo.patch @@ -0,0 +1,20 @@ +--- a/support/rrsync 2015-09-14 01:23:54.000000000 +0200 ++++ b/support/rrsync 2020-02-08 13:55:14.302163313 +0100 +@@ -48,7 +48,7 @@ + + my $command = $ENV{SSH_ORIGINAL_COMMAND}; + die "$0: Not invoked via sshd\n$Usage" unless defined $command; +-die "$0: SSH_ORIGINAL_COMMAND='$command' is not rsync\n" unless $command =~ s/^rsync\s+//; ++die "$0: SSH_ORIGINAL_COMMAND='$command' is not rsync\n" unless $command =~ s/^sudo rsync\s+//; + die "$0: --server option is not first\n" unless $command =~ /^--server\s/; + our $am_sender = $command =~ /^--server\s+--sender\s/; # Restrictive on purpose! + die "$0 sending to read-only server not allowed\n" if $only eq 'r' && !$am_sender; +@@ -227,7 +227,7 @@ + } + + # Note: This assumes that the rsync protocol will not be maliciously hijacked. +-exec(RSYNC, @opts, @args) or die "exec(rsync @opts @args) failed: $? $!"; ++exec("/usr/bin/sudo", RSYNC, @opts, @args) or die "exec(sudo rsync @opts @args) failed: $? $!"; + + sub check_arg + { -- 2.41.0