diff --git a/machines/fuuko/configuration.nix b/machines/fuuko/configuration.nix index 349133d..e09469a 100644 --- a/machines/fuuko/configuration.nix +++ b/machines/fuuko/configuration.nix @@ -17,7 +17,7 @@ nginx.hardening.enable = true; restic.system = { enable = true; - uploadLimit = 250; + qos = true; extraPaths = [ "/data" ]; diff --git a/machines/hitagi/configuration.nix b/machines/hitagi/configuration.nix index ea8e7d7..5855f2d 100644 --- a/machines/hitagi/configuration.nix +++ b/machines/hitagi/configuration.nix @@ -17,7 +17,7 @@ mullvad.enable = true; restic.system = { enable = true; - uploadLimit = 250; + qos = true; extraPaths = [ "/data" ]; diff --git a/machines/mayushii/configuration.nix b/machines/mayushii/configuration.nix index 82d26dc..8e24d2b 100644 --- a/machines/mayushii/configuration.nix +++ b/machines/mayushii/configuration.nix @@ -17,7 +17,7 @@ mullvad.enable = true; restic.system = { enable = true; - uploadLimit = 250; + qos = true; }; unfree.allowSoftware = true; wireguard.home.enable = true; diff --git a/machines/nunotaba/configuration.nix b/machines/nunotaba/configuration.nix index 6a7ed48..b773ecf 100644 --- a/machines/nunotaba/configuration.nix +++ b/machines/nunotaba/configuration.nix @@ -11,7 +11,7 @@ gui.enable = true; restic.system = { enable = true; - uploadLimit = 250; + qos = true; }; unfree.allowSoftware = true; wireguard.home.enable = true; diff --git a/machines/shinobu/services/router/rules.nft b/machines/shinobu/services/router/rules.nft index c3c00e8..64cfcf1 100644 --- a/machines/shinobu/services/router/rules.nft +++ b/machines/shinobu/services/router/rules.nft @@ -72,6 +72,9 @@ table inet tc { meta l4proto udp ip dscp af13 meta priority set 1:5 ip dscp set cs0 counter return comment "fuuko torrent" + ip daddr 168.119.176.53 tcp dport 443 ip dscp af12 meta priority set 1:9 counter return comment "restic (4)" + ip6 daddr 2a01:4f8:c012:2f4::1 tcp dport 443 ip6 dscp af12 meta priority set 1:9 counter return comment "restic (6)" + meta l4proto { tcp, udp } th dport 443 meta priority set 1:6 counter return comment "HTTPS" ip daddr 168.119.176.53 udp dport 51820 meta priority set 1:7 counter return comment "wg-home" diff --git a/modules/restic/system.nix b/modules/restic/system.nix index 87b730c..962fbf0 100644 --- a/modules/restic/system.nix +++ b/modules/restic/system.nix @@ -38,6 +38,25 @@ let --repo "${repository}" \ $@ ''; + + # HACK: NixOS’ nftables implementation runs nft -c inside the build sandbox, + # where the target host’s cgroups are not available, + # and therefore fails. + # This is there to allow my home router to put backup traffic into the right qdisc, + # as the ip address and port are also used for other things. + # This is somewhat of an abuse of the DSCP mark. + qosRules = pkgs.writeText "restic-qos.nft" '' + table inet restic + delete table inet restic + + table inet restic { + chain output { + type filter hook output priority mangle + ip version 4 socket cgroupv2 level 1 "restic.slice" ip dscp set af12 return + ip6 version 6 socket cgroupv2 level 1 "restic.slice" ip6 dscp set af12 return + } + } + ''; in { options.sbruder.restic.system = { @@ -62,6 +81,7 @@ in type = lib.types.nullOr lib.types.int; default = null; }; + qos = (lib.mkEnableOption "QoS marking (DSCP AF12) of outgoing packets") // { default = !(lib.isNull cfg.uploadLimit); }; prune = lib.mkEnableOption "pruning"; }; @@ -99,6 +119,13 @@ in "Nice" = 10; "IOSchedulingClass" = "best-effort"; "IOSchedulingPriority" = 7; + ExecStartPre = [ + "${pkgs.nftables}/bin/nft -f ${qosRules}" + ]; + ExecStopPost = [ + "${pkgs.nftables}/bin/nft delete table inet restic" + ]; + Slice = "restic.slice"; }; services.restic.backups.system-prune = lib.mkIf cfg.prune {