From b400585885bb65cce0ecddb0f963c93669891373 Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Sat, 1 Jul 2023 18:51:48 +0100 Subject: [PATCH] tywin: setup restic server --- .../default.nix | 70 +++++++++++++++++- modules/tailscale.nix | 3 + secrets/restic/1.6T.age | 21 ++++++ secrets/restic/128G.age | Bin 0 -> 1013 bytes secrets/secrets.nix | 2 + 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 secrets/restic/1.6T.age create mode 100644 secrets/restic/128G.age diff --git a/hosts/tywin.storage.ts.hillion.co.uk/default.nix b/hosts/tywin.storage.ts.hillion.co.uk/default.nix index 40bb1b6..1fc312c 100644 --- a/hosts/tywin.storage.ts.hillion.co.uk/default.nix +++ b/hosts/tywin.storage.ts.hillion.co.uk/default.nix @@ -21,6 +21,8 @@ custom.tailscale = { enable = true; preAuthKeyFile = config.age.secrets."tailscale/tywin.storage.ts.hillion.co.uk".path; + ipv4Addr = "100.115.31.91"; + ipv6Addr = "fd7a:115c:a1e0:ab12:4843:cd96:6273:1f5b"; }; ## Filesystems @@ -67,6 +69,68 @@ in builtins.map (mkFolder) folderNames; + ## Restic + age.secrets."restic/128G.key" = { + file = ../../secrets/restic/128G.age; + owner = "restic"; + group = "restic"; + }; + age.secrets."restic/1.6T.key" = { + file = ../../secrets/restic/1.6T.age; + owner = "restic"; + group = "restic"; + }; + + services.restic.server = { + enable = true; + appendOnly = true; + extraFlags = [ "--no-auth" ]; + dataDir = "/data/backups/restic"; + listenAddress = "127.0.0.1:8000"; # TODO: can this be a Unix socket? + }; + services.caddy = { + enable = true; + virtualHosts."http://restic.tywin.storage.ts.hillion.co.uk".extraConfig = '' + bind ${config.custom.tailscale.ipv4Addr} ${config.custom.tailscale.ipv6Addr} + reverse_proxy http://localhost:8000 + ''; + }; + services.restic.backups."prune-128G" = { + repository = "/data/backups/restic/128G"; + user = "restic"; + passwordFile = config.age.secrets."restic/128G.key".path; + + timerConfig = { + Persistent = true; + OnCalendar = "02:30"; + RandomizedDelaySec = "1h"; + }; + + pruneOpts = [ + "--keep-within-hourly 7d" + "--keep-within-daily 1m" + "--keep-within-weekly 6m" + "--keep-within-monthly 24m" + ]; + }; + services.restic.backups."prune-1.6T" = { + repository = "/data/backups/restic/1.6T"; + user = "restic"; + passwordFile = config.age.secrets."restic/1.6T.key".path; + + timerConfig = { + Persistent = true; + OnCalendar = "Wed, 02:30"; + RandomizedDelaySec = "4h"; + }; + + pruneOpts = [ + "--keep-within-daily 14d" + "--keep-within-weekly 2m" + "--keep-within-monthly 18m" + ]; + }; + ## Chia age.secrets."chia/farmer.key" = { file = ../../secrets/chia/farmer.key.age; @@ -135,6 +199,10 @@ }; }; - networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ 14002 14003 ]; + networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ + 80 # Caddy (restic.tywin.storage.ts.) + 14002 # Storj Dashboard (zfs.) + 14003 # Storj Dashboard (d0.) + ]; }; } diff --git a/modules/tailscale.nix b/modules/tailscale.nix index 60bde7d..198c645 100644 --- a/modules/tailscale.nix +++ b/modules/tailscale.nix @@ -20,6 +20,9 @@ in type = lib.types.bool; default = false; }; + + ipv4Addr = lib.mkOption { type = lib.types.str; }; + ipv6Addr = lib.mkOption { type = lib.types.str; }; }; config = lib.mkIf cfg.enable { diff --git a/secrets/restic/1.6T.age b/secrets/restic/1.6T.age new file mode 100644 index 0000000..8be9b97 --- /dev/null +++ b/secrets/restic/1.6T.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-rsa GxPFJQ +r/uFxmFhyAqk0NAFNsK5Pcl3Qwoa3g7lGjpy8qIEijJnRgM5Sp59z1+S1ORdJAWX +lYs3R5RB5J//ewpCubFngjoT04xuCHrQPp22NjaY7j+vCV791D3t0hrwv/oOK4nT +SV7Dxq+wHJb6Ba39+tsFGSnt79FnVYNPBuyljkeuG0wZGTbHajT0GVIi6jNuHN6U +/D7hAS5ZztMRxWgsxqLnX6IO7QSN0CY6e/JkShnA7ITYbcs0NCkKMjvJsjZTtuOW +3ks9BjflTj0lmIxC+I9fOWT0H3rokdkjUqexPJff8XnwWQRnvMz+TFfW1exts2pp +GRGxHulQBHeNCaoSxyzogw +-> ssh-rsa K9mW1w +ouKP/bdJHpsdqgGzCngHEiCcwp/iu79BDfPOnlVakr7Wc2zJCEYfFkxH1ytjhF2R +RPdtU/reY3/8Vi3RsSJ7VbOFtj29Qi59DZvFDb/W30vMixogiQoKWNngHDCs/qhQ +r8UubFRJJDkGxqYpw1NOhs03XWvRx4kbJoNnVv1N68ftit7lWp0HhL+TyX0jBNWo +xl4OdjkyHclKyOwOV0GlR/Znf+Q+hgQbcU0VWDSzEurZHIC5/2zvK7boFwiuiNeZ +ybIh5TgF2LrlOuMLlWPbyeXSgxu8tx4MaHUZ0kM+RIOOppizyeA/ZDRythPa391Z +RMf7UJWJecN5bBUWbgiNIA +-> ssh-ed25519 nWv9MA R/SpgfolcQRgt78ZWcm0WCMNjBsAf9bNpr771ADYXnU +EKcbEG8uhK2NOXnwINU3j4l0liRM+MPa/gHg4Yor1+A +-> 5Of6-grease m5 @Vd}HP CRP'( +gK3pW6/TOo2NPw +--- pM3+d/SPME2u9Xy64Ev4TsBXSEkeJFoC1UmudUafeyI +[_ M@OW bO@ڊÈEʽ yvlɵC0~rL#wM` \ No newline at end of file diff --git a/secrets/restic/128G.age b/secrets/restic/128G.age new file mode 100644 index 0000000000000000000000000000000000000000..f34e2cd82bd88ed33a593c4f836b4f375115fdbb GIT binary patch literal 1013 zcmYk(I}fW=0KoA(^Bu0~pR=KY`c9_znK~{gX1E=GUxw-rM?i{pi+|OwUo%k0%&c(*`FKYxL&} zNO}5+4eL(!ZE|#h8H_ZZZMjByVs*Vf_1&yBr4mWINyOr>25LWd|8 zVn(!PqJlJ+yWlJi5IokQB=tIA67}YHY_V3Iv@05KJv*m_3}V^Gwj8T)(A|i7#K?7K zd-g6{UaRRwa6vI5Sppu)`(&iM++cZ2TLe-^;yEF#5Zj5eazrH#mci~p#Y?M3H+Rk{ zsrVQ|r>B=g&OeLRAgMk_i!?~=mcJNL)&a(Zr!>}yik=JMY1M%yI}|UMwik`SB-SP| zVxhKa>s&Pr()sPJGAvn2z-B8LoNQdz3=IZSWbAl>NM8e6lw+zj8tu5{=I2FTEi70D zHv$0szqYGhB5t6Z+cK=e1SOkTJ?AA>d>@qQS zcFc8kU)}+^P(FJ(*!k&tfOe7I)Ov&n?zLv)1|yrU=(gHoyeS@=d2z4!S*tpx7IvFw zk;I(mSL%sMwMw~+higIKJ7t}w9h1YPv7rwaa(Z@_k^)p&yF=dPrE#T2r7iC+O<_j7 zANe`dsBIaGOd&jI8KF5RcP)8fV%&3IiVR_GCaio?Nr=Wr=^TTW$y@}i+j`}5A$t`H zvY-I!ISVI*Ei!(A%+ZC1xoK!1=F+M$^r0#hxe8R}QA@jF+%ENOKT7rXykh#BzbSO; z-js2Q=`#>q;2ddB*vV_}KkfWD6Gcv)T%%s~w22)0!ujm=NVawz!VF2enhEU)8}_ZN z;gF0{=r^|AMl8iE=zR*KntWi5#Y{VzIu^u($%$TV_iEa0EK~NoeWl=k-#Qup$*b`7 zv~2PO=aXTEAEk#UFn5?$6VY)muou X_|E_7tKa|n^qXJUpWnWgKmX$&fa6d; literal 0 HcmV?d00001 diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 6a1d429..f0fdf6a 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -64,6 +64,8 @@ in # Restic Secrets "restic/b2-backups-matrix.age".publicKeys = jake_users ++ [ ts.strangervm.vm ]; + "restic/128G.age".publicKeys = jake_users ++ [ ts.storage.tywin ]; + "restic/1.6T.age".publicKeys = jake_users ++ [ ts.storage.tywin ]; # Spotify Secrets "spotify/11132032266.age".publicKeys = jake_users ++ [ ts.terminals.jakehillion.gendry ];