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";
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 = {
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"
''
];
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 {}; };
--- /dev/null
+{ rrsync }:
+
+rrsync.overrideAttrs(old: {
+ patches = old.patches or [] ++ [ ./sudo.patch ];
+ postPatch = old.postPatch + ''
+ substituteInPlace support/rrsync --replace /usr/bin/sudo /run/wrappers/bin/sudo
+ '';
+})
--- /dev/null
+--- 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
+ {