migrate away from hetzner storagebox and get rid of some gaming and media stuff

This commit is contained in:
chaos 2024-07-06 17:20:28 +01:00
parent 727173a44f
commit c4714964d1
No known key found for this signature in database
51 changed files with 152 additions and 1149 deletions

View file

@ -12,7 +12,10 @@
homeManagerLib = inputs.home-manager.lib.hm; homeManagerLib = inputs.home-manager.lib.hm;
fontSizesAll = { fontSizesAll = {
"lappy-t495" = { small = "10"; medium = "12"; }; "lappy-t495" = {
small = "10";
medium = "12";
};
default = { default = {
small = "14"; small = "14";
medium = "16"; medium = "16";

View file

@ -1,12 +1,8 @@
{ {
pkgs, pkgs,
tree, tree,
nixosConfig,
... ...
}: let }: {
# Requires secrets.{restic_music_env}
inherit (nixosConfig.services.secrets) secrets;
in {
imports = with tree; [ imports = with tree; [
home.apps.rclone home.apps.rclone
home.apps.musicutil home.apps.musicutil
@ -14,11 +10,6 @@ in {
home.packages = [ home.packages = [
pkgs.nodePackages.html-minifier pkgs.nodePackages.html-minifier
(pkgs.writeShellScriptBin "restic-music" ''
env $(cat ${secrets.restic_music_env.path}) \
${pkgs.restic}/bin/restic $@
'')
]; ];
home.file."Music/music-sync-check.sh" = { home.file."Music/music-sync-check.sh" = {
@ -82,7 +73,6 @@ in {
cd "''${SCRIPT_DIR}" cd "''${SCRIPT_DIR}"
rclone sync -P . Storage:Music --exclude "/*.sh" rclone sync -P . Storage:Music --exclude "/*.sh"
restic-music backup $(fd -t d --max-depth=1 && fd -t f --max-depth=1)
bash $HOME/Music/music-gen-listing.sh bash $HOME/Music/music-gen-listing.sh
''; '';

View file

@ -1,5 +1,5 @@
{pkgs, ...}: { {pkgs, ...}: {
programs.vscode-mod.extensions = with pkgs; [vscode-extensions.matklad.rust-analyzer]; programs.vscode-mod.extensions = with pkgs; [vscode-extensions.rust-lang.rust-analyzer];
home.packages = with pkgs; [rustc cargo clippy rust-analyzer rustfmt]; home.packages = with pkgs; [rustc cargo clippy rust-analyzer rustfmt];
home.sessionVariables = {RUST_SRC_PATH = pkgs.rustPlatform.rustLibSrc;}; home.sessionVariables = {RUST_SRC_PATH = pkgs.rustPlatform.rustLibSrc;};
} }

View file

@ -1,33 +1,21 @@
{ {
self, self,
pkgs,
config, config,
... ...
}: let }: let
backupSchedules = import "${self}/data/backupSchedules.nix"; backupSchedules = import "${self}/data/backupSchedules.nix";
inherit (config.services.secrets) secrets; inherit (config.services.secrets) secrets;
in { in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-caldav" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.caldav = { services.restic.backups.caldav = {
user = "root"; user = "root";
paths = [ paths = [
"/var/lib/radicale" "/var/lib/radicale"
]; ];
# repository is overrided in environmentFile to contain auth repository = "s3:s3.eu-central-003.backblazeb2.com/Chaos-Backups/Restic/CalDAV";
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/CalDAV";
passwordFile = "${secrets.restic_password.path}"; passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}"; environmentFile = "${secrets.restic_env.path}";
createWrapper = true;
pruneOpts = ["--keep-last 50"]; pruneOpts = ["--keep-last 50"];
timerConfig = backupSchedules.restic.high; timerConfig = backupSchedules.restic.high;

View file

@ -11,13 +11,9 @@
loginUsername = "hetzner-arm-container-caldav"; loginUsername = "hetzner-arm-container-caldav";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"api-keys/data/caldav" "api-keys/data/caldav"
"api-keys/data/storage/restic/CalDAV" "api-keys/data/backblaze/Chaos-Backups"
"private-public-keys/data/restic/CalDAV" "private-public-keys/data/restic/CalDAV"
]; ];
@ -51,8 +47,10 @@
}; };
restic_env = { restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/CalDAV" .restic) cat << EOF > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/CalDAV" > "$secretFile" AWS_ACCESS_KEY_ID=$(simple_get "/api-keys/backblaze/Chaos-Backups" .keyID)
AWS_SECRET_ACCESS_KEY=$(simple_get "/api-keys/backblaze/Chaos-Backups" .applicationKey)
EOF
''; '';
}; };
}; };

View file

@ -1,33 +1,21 @@
{ {
self, self,
pkgs,
config, config,
... ...
}: let }: let
backupSchedules = import "${self}/data/backupSchedules.nix"; backupSchedules = import "${self}/data/backupSchedules.nix";
inherit (config.services.secrets) secrets; inherit (config.services.secrets) secrets;
in { in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-forgejo" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.forgejo = { services.restic.backups.forgejo = {
user = "root"; user = "root";
paths = [ paths = [
"/var/lib/forgejo" "/var/lib/forgejo"
]; ];
# repository is overrided in environmentFile to contain auth repository = "s3:s3.eu-central-003.backblazeb2.com/Chaos-Backups/Restic/Forgejo";
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/Forgejo";
passwordFile = "${secrets.restic_password.path}"; passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}"; environmentFile = "${secrets.restic_env.path}";
createWrapper = true;
pruneOpts = ["--keep-last 50"]; pruneOpts = ["--keep-last 50"];
timerConfig = backupSchedules.restic.high; timerConfig = backupSchedules.restic.high;

View file

@ -7,12 +7,8 @@
loginUsername = "hetzner-arm-container-forgejo"; loginUsername = "hetzner-arm-container-forgejo";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"api-keys/data/storage/restic/Forgejo" "api-keys/data/backblaze/Chaos-Backups"
"private-public-keys/data/restic/Forgejo" "private-public-keys/data/restic/Forgejo"
]; ];
@ -28,8 +24,10 @@
}; };
restic_env = { restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Forgejo" .restic) cat << EOF > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Forgejo" > "$secretFile" AWS_ACCESS_KEY_ID=$(simple_get "/api-keys/backblaze/Chaos-Backups" .keyID)
AWS_SECRET_ACCESS_KEY=$(simple_get "/api-keys/backblaze/Chaos-Backups" .applicationKey)
EOF
''; '';
}; };
}; };

View file

@ -1,33 +1,21 @@
{ {
self, self,
pkgs,
config, config,
... ...
}: let }: let
inherit (config.services.secrets) secrets; inherit (config.services.secrets) secrets;
backupSchedules = import "${self}/data/backupSchedules.nix"; backupSchedules = import "${self}/data/backupSchedules.nix";
in { in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-grocy" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.grocy = { services.restic.backups.grocy = {
user = "root"; user = "root";
paths = [ paths = [
"/var/lib/grocy" "/var/lib/grocy"
]; ];
# repository is overrided in environmentFile to contain auth repository = "s3:s3.eu-central-003.backblazeb2.com/Chaos-Backups/Restic/Grocy";
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/Grocy";
passwordFile = "${secrets.restic_password.path}"; passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}"; environmentFile = "${secrets.restic_env.path}";
createWrapper = true;
pruneOpts = ["--keep-last 30"]; pruneOpts = ["--keep-last 30"];
timerConfig = backupSchedules.restic.high; timerConfig = backupSchedules.restic.high;

View file

@ -7,12 +7,8 @@
loginUsername = "hetzner-arm-container-grocy"; loginUsername = "hetzner-arm-container-grocy";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"api-keys/data/storage/restic/Grocy" "api-keys/data/backblaze/Chaos-Backups"
"private-public-keys/data/restic/Grocy" "private-public-keys/data/restic/Grocy"
]; ];
@ -28,8 +24,10 @@
}; };
restic_env = { restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Grocy" .restic) cat << EOF > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Grocy" > "$secretFile" AWS_ACCESS_KEY_ID=$(simple_get "/api-keys/backblaze/Chaos-Backups" .keyID)
AWS_SECRET_ACCESS_KEY=$(simple_get "/api-keys/backblaze/Chaos-Backups" .applicationKey)
EOF
''; '';
}; };
}; };

View file

@ -1,33 +1,21 @@
{ {
self, self,
pkgs,
config, config,
... ...
}: let }: let
inherit (config.services.secrets) secrets; inherit (config.services.secrets) secrets;
backupSchedules = import "${self}/data/backupSchedules.nix"; backupSchedules = import "${self}/data/backupSchedules.nix";
in { in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-jellyfin" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.jellyfin = { services.restic.backups.jellyfin = {
user = "root"; user = "root";
paths = [ paths = [
"/var/lib/jellyfin" "/var/lib/jellyfin"
]; ];
# repository is overrided in environmentFile to contain auth repository = "s3:s3.eu-central-003.backblazeb2.com/Chaos-Backups/Restic/Jellyfin";
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/Jellyfin";
passwordFile = "${secrets.restic_password.path}"; passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}"; environmentFile = "${secrets.restic_env.path}";
createWrapper = true;
pruneOpts = ["--keep-last 10"]; pruneOpts = ["--keep-last 10"];
timerConfig = backupSchedules.restic.low; timerConfig = backupSchedules.restic.low;

View file

@ -44,16 +44,11 @@
loginUsername = "hetzner-arm-container-jellyfin"; loginUsername = "hetzner-arm-container-jellyfin";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"api-keys/data/backblaze/Chaos-Media" "api-keys/data/backblaze/Chaos-Media"
"api-keys/data/putio" "api-keys/data/putio"
"private-public-keys/data/rclone/Chaos-Media-Crypt" "private-public-keys/data/rclone/Chaos-Media-Crypt"
"api-keys/data/storage/restic/Jellyfin"
"private-public-keys/data/restic/Jellyfin" "private-public-keys/data/restic/Jellyfin"
]; ];
@ -85,8 +80,10 @@
}; };
restic_env = { restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Jellyfin" .restic) cat << EOF > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Jellyfin" > "$secretFile" AWS_ACCESS_KEY_ID=$(simple_get "/api-keys/backblaze/Chaos-Backups" .keyID)
AWS_SECRET_ACCESS_KEY=$(simple_get "/api-keys/backblaze/Chaos-Backups" .applicationKey)
EOF
''; '';
}; };
}; };

View file

@ -1,6 +1,5 @@
{ {
self, self,
pkgs,
config, config,
... ...
}: let }: let
@ -9,16 +8,6 @@
mailConfig = config.services.mailserver; mailConfig = config.services.mailserver;
in { in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-mail" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.mail = { services.restic.backups.mail = {
user = "root"; user = "root";
paths = [ paths = [
@ -27,11 +16,10 @@ in {
mailConfig.dkim.directory mailConfig.dkim.directory
]; ];
# repository is overrided in environmentFile to contain auth repository = "s3:s3.eu-central-003.backblazeb2.com/Chaos-Backups/Restic/Mail";
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/Mail";
passwordFile = "${secrets.restic_password.path}"; passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}"; environmentFile = "${secrets.restic_env.path}";
createWrapper = true;
pruneOpts = ["--keep-last 60"]; pruneOpts = ["--keep-last 60"];
timerConfig = backupSchedules.restic.medium; timerConfig = backupSchedules.restic.medium;

View file

@ -7,12 +7,8 @@
loginUsername = "hetzner-arm-container-mail"; loginUsername = "hetzner-arm-container-mail";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"api-keys/data/storage/restic/Mail" "api-keys/data/backblaze/Chaos-Backups"
"api-keys/data/chaos_mail/system" "api-keys/data/chaos_mail/system"
"api-keys/data/chaos_mail/gotosocial" "api-keys/data/chaos_mail/gotosocial"
"passwords/data/mail" "passwords/data/mail"
@ -36,8 +32,10 @@
}; };
restic_env = { restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Mail" .restic) cat << EOF > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Mail" > "$secretFile" AWS_ACCESS_KEY_ID=$(simple_get "/api-keys/backblaze/Chaos-Backups" .keyID)
AWS_SECRET_ACCESS_KEY=$(simple_get "/api-keys/backblaze/Chaos-Backups" .applicationKey)
EOF
''; '';
}; };
private_mail_aliases = { private_mail_aliases = {

View file

@ -14,7 +14,6 @@ in {
mpc_cli mpc_cli
]; ];
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /Music - mpd mpd" "d /Music - mpd mpd"
]; ];

View file

@ -7,10 +7,6 @@
loginUsername = "hetzner-arm-container-music"; loginUsername = "hetzner-arm-container-music";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"api-keys/data/mpd" "api-keys/data/mpd"
"api-keys/data/music-stream" "api-keys/data/music-stream"

View file

@ -1,74 +0,0 @@
{
self,
hostPath,
tree,
inputs,
pkgs,
config,
...
}: let
containerName = "owncast";
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
hostIP = containerAddresses.host;
containerIP = containerAddresses.containers.${containerName};
in {
containers.owncast = {
autoStart = true;
privateNetwork = true;
hostAddress = hostIP;
localAddress = containerIP;
specialArgs = {
inherit inputs;
inherit tree;
inherit self;
inherit hostPath;
};
config = {...}: {
nixpkgs.pkgs = pkgs;
imports = with tree;
[
presets.nixos.containerBase
./secrets.nix
]
++ (with hosts.hetzner-arm.containers.owncast.profiles; [
owncast
restic
]);
networking.firewall.allowedTCPPorts = [
1935
8080
];
home-manager.users.root.home.stateVersion = "24.05";
system.stateVersion = "24.05";
};
};
services.nginx.virtualHosts."stream.owo.monster" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://${containerIP}:8080";
proxyWebsockets = true;
};
};
networking = {
nat.forwardPorts = [
{
sourcePort = 1935;
destination = "${containerIP}\:1935";
}
];
firewall.allowedTCPPorts = [
1935
];
};
}

View file

@ -1,8 +0,0 @@
{...}: {
services.owncast = {
enable = true;
listen = "0.0.0.0";
port = 8080;
rtmp-port = 1935;
};
}

View file

@ -1,35 +0,0 @@
{
self,
pkgs,
config,
...
}: let
backupSchedules = import "${self}/data/backupSchedules.nix";
inherit (config.services.secrets) secrets;
in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-owncast" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.owncast = {
user = "root";
paths = [
"/var/lib/owncast"
];
# repository is overrided in environmentFile to contain auth
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/Owncast";
passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}";
pruneOpts = ["--keep-last 5"];
timerConfig = backupSchedules.restic.low;
};
}

View file

@ -1,37 +0,0 @@
{...}: {
services.secrets = {
enable = true;
vaultLogin = {
enable = true;
loginUsername = "hetzner-arm-container-owncast";
};
autoSecrets = {
enable = true;
};
requiredVaultPaths = [
"api-keys/data/storage/restic/Owncast"
"private-public-keys/data/restic/Owncast"
];
secrets = {
vault_password = {
manual = true;
};
restic_password = {
fetchScript = ''
simple_get "/private-public-keys/restic/Owncast" .password > "$secretFile"
'';
};
restic_env = {
fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Owncast" .restic)
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Owncast" > "$secretFile"
'';
};
};
};
}

View file

@ -13,27 +13,16 @@
'') '')
}/bin/backupPrepareCommand"; }/bin/backupPrepareCommand";
in { in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-postgresql" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.postgresql = { services.restic.backups.postgresql = {
user = "root"; user = "root";
paths = [ paths = [
"/var/backup/postgresql" "/var/backup/postgresql"
]; ];
# repository is overrided in environmentFile to contain auth repository = "s3:s3.eu-central-003.backblazeb2.com/Chaos-Backups/Restic/PostgreSQL";
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/PostgreSQL";
passwordFile = "${secrets.restic_password.path}"; passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}"; environmentFile = "${secrets.restic_env.path}";
createWrapper = true;
pruneOpts = ["--keep-last 10"]; pruneOpts = ["--keep-last 10"];
timerConfig = backupSchedules.restic.high; timerConfig = backupSchedules.restic.high;

View file

@ -7,12 +7,8 @@
loginUsername = "hetzner-arm-container-postgresql"; loginUsername = "hetzner-arm-container-postgresql";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"api-keys/data/storage/restic/PostgreSQL" "api-keys/data/backblaze/Chaos-Backups"
"private-public-keys/data/restic/PostgreSQL" "private-public-keys/data/restic/PostgreSQL"
]; ];
@ -28,8 +24,10 @@
}; };
restic_env = { restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/PostgreSQL" .restic) cat << EOF > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/PostgreSQL" > "$secretFile" AWS_ACCESS_KEY_ID=$(simple_get "/api-keys/backblaze/Chaos-Backups" .keyID)
AWS_SECRET_ACCESS_KEY=$(simple_get "/api-keys/backblaze/Chaos-Backups" .applicationKey)
EOF
''; '';
}; };
}; };

View file

@ -1,74 +0,0 @@
{
self,
hostPath,
tree,
inputs,
config,
pkgs,
...
}: let
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
hostIP = containerAddresses.host;
containerIP = containerAddresses.containers.rss;
in {
containers.rss = {
autoStart = true;
privateNetwork = true;
hostAddress = hostIP;
localAddress = containerIP;
specialArgs = {
inherit inputs;
inherit tree;
inherit self;
inherit hostPath;
};
config = {...}: {
nixpkgs.pkgs = pkgs;
imports = with tree;
[
presets.nixos.containerBase
./secrets.nix
]
++ (with hosts.hetzner-arm.containers.rss.profiles; [
freshrss
restic
]);
networking.firewall.allowedTCPPorts = [80];
home-manager.users.root.home.stateVersion = "24.05";
system.stateVersion = "24.05";
};
};
services.nginx = {
enable = true;
virtualHosts."freshrss.owo.monster" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${containerIP}:80/";
recommendedProxySettings = false;
extraConfig = ''
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_read_timeout 90;
# Forward the Authorization header for the Google Reader API.
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
'';
};
};
};
}

View file

@ -1,11 +0,0 @@
{config, ...}: let
inherit (config.services.secrets) secrets;
in {
services.freshrss = {
enable = true;
defaultUser = "chaos";
baseUrl = "127.0.0.1";
virtualHost = "127.0.0.1";
passwordFile = secrets.chaos_password.path;
};
}

View file

@ -1,35 +0,0 @@
{
self,
pkgs,
config,
...
}: let
backupSchedules = import "${self}/data/backupSchedules.nix";
inherit (config.services.secrets) secrets;
in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-rss" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.rss = {
user = "root";
paths = [
"/var/lib/freshrss"
];
# repository is overrided in environmentFile to contain auth
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/RSS";
passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}";
pruneOpts = ["--keep-last 50"];
timerConfig = backupSchedules.restic.high;
};
}

View file

@ -1,49 +0,0 @@
{pkgs, ...}: {
services.secrets = {
enable = true;
packages = with pkgs; [
apacheHttpd
];
vaultLogin = {
enable = true;
loginUsername = "hetzner-arm-container-rss";
};
autoSecrets = {
enable = true;
};
requiredVaultPaths = [
"passwords/data/freshrss"
"api-keys/data/storage/restic/RSS"
"private-public-keys/data/restic/RSS"
];
secrets = {
vault_password = {
manual = true;
};
chaos_password = {
fetchScript = ''
simple_get "/passwords/freshrss" .password > "$secretFile"
'';
};
restic_password = {
fetchScript = ''
simple_get "/private-public-keys/restic/RSS" .password > "$secretFile"
'';
};
restic_env = {
fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/RSS" .restic)
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/TSS" > "$secretFile"
'';
};
};
};
}

View file

@ -35,27 +35,16 @@
rm /var/lib/gotosocial/gts-export.json || true rm /var/lib/gotosocial/gts-export.json || true
'')}/bin/backupCleanupCommand"; '')}/bin/backupCleanupCommand";
in { in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-social" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.social = { services.restic.backups.social = {
user = "root"; user = "root";
paths = [ paths = [
"/var/lib/gotosocial" "/var/lib/gotosocial"
]; ];
# repository is overrided in environmentFile to contain auth repository = "s3:s3.eu-central-003.backblazeb2.com/Chaos-Backups/Restic/Social";
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/Social";
passwordFile = "${secrets.restic_password.path}"; passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}"; environmentFile = "${secrets.restic_env.path}";
createWrapper = true;
pruneOpts = ["--keep-last 10"]; pruneOpts = ["--keep-last 10"];
# Don't want to cause too much downtime and take too long to prune media # Don't want to cause too much downtime and take too long to prune media

View file

@ -7,14 +7,10 @@
loginUsername = "hetzner-arm-container-social"; loginUsername = "hetzner-arm-container-social";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"private-public-keys/data/restic/Social" "private-public-keys/data/restic/Social"
"api-keys/data/storage/restic/Social" "api-keys/data/backblaze/Chaos-Backups"
"api-keys/data/chaos_mail/gotosocial" "api-keys/data/chaos_mail/gotosocial"
]; ];
@ -31,8 +27,10 @@
}; };
restic_env = { restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Social" .restic) cat << EOF > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Social" > "$secretFile" AWS_ACCESS_KEY_ID=$(simple_get "/api-keys/backblaze/Chaos-Backups" .keyID)
AWS_SECRET_ACCESS_KEY=$(simple_get "/api-keys/backblaze/Chaos-Backups" .applicationKey)
EOF
''; '';
}; };
env_secrets = { env_secrets = {

View file

@ -1,27 +1,11 @@
let let
webdav = 4200; webdav = 4200;
restic = 4300; http = 4300;
http = 4400;
in { in {
webdav_main = webdav + 0; webdav_main = webdav + 0;
webdav_media = webdav + 1; webdav_music_ro = webdav + 1;
webdav_music_ro = webdav + 2; webdav_uploads = webdav + 2;
webdav_public = webdav + 3; webdav_notes = webdav + 3;
webdav_uploads = webdav + 4;
webdav_gaming = webdav + 5;
webdav_notes = webdav + 6;
restic_music = restic + 0;
restic_vault = restic + 1;
restic_social = restic + 2;
restic_postgresql = restic + 3;
restic_mail = restic + 4;
restic_forgejo = restic + 5;
restic_caldav = restic + 6;
restic_owncast = restic + 7;
restic_jellyfin = restic + 8;
restic_grocy = restic + 9;
restic_lappy_t495 = restic + 10;
http_music = http + 0; http_music = http + 0;
http_public = http + 1; http_public = http + 1;

View file

@ -1,162 +1,74 @@
[StorageBox-Remote-WebDAV] [Storage]
type = webdav type = combine
vendor = other upstreams = "Backups=B2-Chaos-Backups:Chaos-Backups" "Photos=B2-Chaos-Photos:Chaos-Photos" "Music=B2-Chaos-Music:Chaos-Music" "Public=B2-Chaos-Public:Chaos-Public" "Notes=Notes:" "Media=Media:" "Personal=B2-Chaos-Personal:Chaos-Personal" "Uploads=B2-Chaos-Uploads:Chaos-Uploads"
host = u323231.your-storagebox.de
url = https://u323231.your-storagebox.de
user = u323231
pass = STORAGEBOX_PASSWORD
[StorageBox-Remote-SFTP] [B2-Chaos-Backups]
type = sftp
host = u323231.your-storagebox.de
user = u323231
port = 23
pass = STORAGEBOX_PASSWORD
shell_type = unix
md5sum_command = md5 -r
sha1sum_command = sha1 -r
# Can change which protocol to use at runtime by editing config
# after deploy or redeploying with different alias if storagebox breaks
[StorageBox-Remote]
type = alias
remote = StorageBox-Remote-WebDAV:
[StorageBox-Hasher]
type = hasher
remote = StorageBox-Remote:
hashes = sha1,md5
max_age = off
[StorageBox]
type = alias
remote = StorageBox-Hasher:
[B2-Chaos-Backups-Source]
type = b2 type = b2
account = B2_CHAOS_BACKUPS_ACCOUNT account = B2_CHAOS_BACKUPS_ACCOUNT
key = B2_CHAOS_BACKUPS_KEY key = B2_CHAOS_BACKUPS_KEY
hard_delete = true hard_delete = true
[B2-Chaos-Backups] [B2-Chaos-Photos]
type = alias
remote = B2-Chaos-Backups-Source:Chaos-Backups
[B2-Chaos-Photos-Source]
type = b2 type = b2
account = B2_CHAOS_PHOTOS_ACCOUNT account = B2_CHAOS_PHOTOS_ACCOUNT
key = B2_CHAOS_PHOTOS_KEY key = B2_CHAOS_PHOTOS_KEY
hard_delete = true hard_delete = true
[B2-Chaos-Photos] [B2-Chaos-Music]
type = alias
remote = B2-Chaos-Photos-Source:Chaos-Photos
[B2-Chaos-Music-Source]
type = b2 type = b2
account = B2_CHAOS_MUSIC_ACCOUNT account = B2_CHAOS_MUSIC_ACCOUNT
key = B2_CHAOS_MUSIC_KEY key = B2_CHAOS_MUSIC_KEY
hard_delete = true hard_delete = true
[B2-Chaos-Music] [B2-Chaos-Personal]
type = alias
remote = B2-Chaos-Music-Source:Chaos-Music
[B2-Chaos-Personal-Source]
type = b2 type = b2
account = B2_CHAOS_PERSONAL_ACCOUNT account = B2_CHAOS_PERSONAL_ACCOUNT
key = B2_CHAOS_PERSONAL_KEY key = B2_CHAOS_PERSONAL_KEY
hard_delete = true hard_delete = true
[B2-Chaos-Personal] [B2-Chaos-Public]
type = alias
remote = B2-Chaos-Personal-Source:Chaos-Personal
[B2-Chaos-Public-Source]
type = b2 type = b2
account = B2_CHAOS_PUBLIC_ACCOUNT account = B2_CHAOS_PUBLIC_ACCOUNT
key = B2_CHAOS_PUBLIC_KEY key = B2_CHAOS_PUBLIC_KEY
hard_delete = true hard_delete = true
[B2-Chaos-Public] [B2-Chaos-Notes]
type = alias
remote = B2-Chaos-Public-Source:Chaos-Public
[B2-Chaos-Notes-Source]
type = b2 type = b2
account = B2_CHAOS_NOTES_ACCOUNT account = B2_CHAOS_NOTES_ACCOUNT
key = B2_CHAOS_NOTES_KEY key = B2_CHAOS_NOTES_KEY
hard_delete = true hard_delete = true
[B2-Chaos-Notes] [B2-Chaos-Media]
type = alias
remote = B2-Chaos-Notes-Source:Chaos-Notes
[B2-Phoenix-Cryptidz-Storage-Source]
type = b2
account = B2_PHOENIX_CRYPTIDZ_STORAGE_ACCOUNT
key = B2_PHOENIX_CRYPTIDZ_STORAGE_KEY
hard_delete = true
[B2-Phoenix-Cryptidz-Storage]
type = alias
remote = B2-Phoenix-Cryptidz-Storage-Source:Phoenix-Cryptidz-Storage
[PutIO-WebDAV]
type = webdav
url = https://webdav.put.io
vendor = other
user = chaoticryptidz
pass = PUTIO_PASSWORD
[B2-Media-Source]
type = b2 type = b2
account = B2_CHAOS_MEDIA_ACCOUNT account = B2_CHAOS_MEDIA_ACCOUNT
key = B2_CHAOS_MEDIA_KEY key = B2_CHAOS_MEDIA_KEY
hard_delete = true hard_delete = true
[B2-Media] [B2-Chaos-Uploads]
type = alias type = b2
remote = B2-Media-Source:Chaos-Media account = B2_CHAOS_UPLOADS_ACCOUNT
key = B2_CHAOS_UPLOADS_KEY
hard_delete = true
[Media-Source] [B2-Phoenix-Cryptidz-Storage]
type = b2
account = B2_PHOENIX_CRYPTIDZ_STORAGE_ACCOUNT
key = B2_PHOENIX_CRYPTIDZ_STORAGE_KEY
hard_delete = true
[Media-Crypt]
type = crypt type = crypt
remote = B2-Media: remote = B2-Chaos-Media:Chaos-Media
password = STORAGE_MEDIA_CRYPT_PASSWORD password = STORAGE_MEDIA_CRYPT_PASSWORD
password2 = STORAGE_MEDIA_CRYPT_SALT password2 = STORAGE_MEDIA_CRYPT_SALT
[Media] [Media]
type = chunker type = chunker
remote = Media-Source: remote = Media-Crypt:
chunk_size = 256Mi chunk_size = 256Mi
[Media-Combine]
type = combine
upstreams = "Media=Media:" "PutIO=PutIO-WebDAV:"
[B2-Gaming-Source]
type = b2
account = B2_CHAOS_GAMING_ACCOUNT
key = B2_CHAOS_GAMING_KEY
hard_delete = true
[B2-Gaming]
type = alias
remote = B2-Gaming-Source:Chaos-Gaming
[Gaming-Source]
type = crypt
remote = B2-Gaming:
password = STORAGE_GAMING_CRYPT_PASSWORD
password2 = STORAGE_GAMING_CRYPT_SALT
[Gaming]
type = chunker
remote = Gaming-Source:
chunk_size = 128Mi
[Notes] [Notes]
type = crypt type = crypt
remote = StorageBox:Notes remote = B2-Chaos-Notes:Chaos-Notes
password = STORAGE_NOTES_CRYPT_PASSWORD password = STORAGE_NOTES_CRYPT_PASSWORD
password2 = STORAGE_NOTES_CRYPT_SALT password2 = STORAGE_NOTES_CRYPT_SALT

View file

@ -86,11 +86,8 @@ in {
enableACME = true; enableACME = true;
locations = { locations = {
"/Main/".proxyPass = "http://${containerIP}:${toString ports.webdav_main}"; "/Main/".proxyPass = "http://${containerIP}:${toString ports.webdav_main}";
"/Media/".proxyPass = "http://${containerIP}:${toString ports.webdav_media}";
"/MusicRO/".proxyPass = "http://${containerIP}:${toString ports.webdav_music_ro}"; "/MusicRO/".proxyPass = "http://${containerIP}:${toString ports.webdav_music_ro}";
"/Public/".proxyPass = "http://${containerIP}:${toString ports.webdav_public}";
"/Uploads/".proxyPass = "http://${containerIP}:${toString ports.webdav_uploads}"; "/Uploads/".proxyPass = "http://${containerIP}:${toString ports.webdav_uploads}";
"/Gaming/".proxyPass = "http://${containerIP}:${toString ports.webdav_gaming}";
"/Notes/".proxyPass = "http://${containerIP}:${toString ports.webdav_notes}"; "/Notes/".proxyPass = "http://${containerIP}:${toString ports.webdav_notes}";
}; };
extraConfig = '' extraConfig = ''
@ -110,25 +107,4 @@ in {
client_max_body_size ${clientMaxBodySize}; client_max_body_size ${clientMaxBodySize};
''; '';
}; };
services.nginx.virtualHosts."storage-restic.owo.monster" = {
forceSSL = true;
enableACME = true;
locations = {
"/Music/".proxyPass = "http://${containerIP}:${toString ports.restic_music}";
"/Vault/".proxyPass = "http://${containerIP}:${toString ports.restic_vault}";
"/Social/".proxyPass = "http://${containerIP}:${toString ports.restic_social}";
"/PostgreSQL/".proxyPass = "http://${containerIP}:${toString ports.restic_postgresql}";
"/Mail/".proxyPass = "http://${containerIP}:${toString ports.restic_mail}";
"/Forgejo/".proxyPass = "http://${containerIP}:${toString ports.restic_forgejo}";
"/CalDAV/".proxyPass = "http://${containerIP}:${toString ports.restic_caldav}";
"/Owncast/".proxyPass = "http://${containerIP}:${toString ports.restic_owncast}";
"/Jellyfin/".proxyPass = "http://${containerIP}:${toString ports.restic_jellyfin}";
"/Grocy/".proxyPass = "http://${containerIP}:${toString ports.restic_grocy}";
"/Lappy-T495/".proxyPass = "http://${containerIP}:${toString ports.restic_lappy_t495}";
};
extraConfig = ''
client_max_body_size ${clientMaxBodySize};
'';
};
} }

View file

@ -6,7 +6,6 @@ in {
"d /caches - storage storage" "d /caches - storage storage"
"d /caches/main_webdav_serve - storage storage" "d /caches/main_webdav_serve - storage storage"
"d /caches/media_webdav_serve - storage storage" "d /caches/media_webdav_serve - storage storage"
"d /caches/gaming_webdav_serve - storage storage"
]; ];
services.rclone-serve = { services.rclone-serve = {
@ -14,16 +13,11 @@ in {
remotes = map (remote: remotes = map (remote:
{ {
user = "storage"; user = "storage";
serviceConfig = {
after = ["auto-secrets.service"];
wants = ["auto-secrets.service"];
partOf = ["auto-secrets.service"];
};
} }
// remote) [ // remote) [
{ {
id = "main"; id = "main";
remote = "StorageBox:"; remote = "Storage:";
type = "webdav"; type = "webdav";
extraArgs = [ extraArgs = [
"--addr=0.0.0.0:${toString ports.webdav_main}" "--addr=0.0.0.0:${toString ports.webdav_main}"
@ -33,25 +27,9 @@ in {
"--vfs-cache-mode=full" "--vfs-cache-mode=full"
]; ];
} }
{
# This isn't really being directly used anymore but its nice as a backup
# Jellyfin directly mounts from StorageBox instead
id = "media-combine";
remote = "Media-Combine:";
type = "webdav";
extraArgs = [
"--addr=0.0.0.0:${toString ports.webdav_media}"
"--htpasswd=${secrets.webdav_media_htpasswd.path}"
"--baseurl=/Media/"
"--cache-dir=/caches/media_webdav_serve"
"--vfs-cache-max-age=120m"
"--vfs-cache-max-size=5g"
"--vfs-cache-mode=full"
];
}
{ {
id = "music-ro"; id = "music-ro";
remote = "StorageBox:Music"; remote = "Storage:Music";
type = "webdav"; type = "webdav";
extraArgs = [ extraArgs = [
"--addr=0.0.0.0:${toString ports.webdav_music_ro}" "--addr=0.0.0.0:${toString ports.webdav_music_ro}"
@ -59,19 +37,9 @@ in {
"--baseurl=/MusicRO/" "--baseurl=/MusicRO/"
]; ];
} }
{
id = "public";
remote = "StorageBox:Public";
type = "webdav";
extraArgs = [
"--addr=0.0.0.0:${toString ports.webdav_public}"
"--htpasswd=${secrets.webdav_media_htpasswd.path}"
"--baseurl=/Public/"
];
}
{ {
id = "uploads"; id = "uploads";
remote = "StorageBox:Uploads"; remote = "Storage:Uploads";
type = "webdav"; type = "webdav";
extraArgs = [ extraArgs = [
"--addr=0.0.0.0:${toString ports.webdav_uploads}" "--addr=0.0.0.0:${toString ports.webdav_uploads}"
@ -79,20 +47,6 @@ in {
"--baseurl=/Uploads/" "--baseurl=/Uploads/"
]; ];
} }
{
id = "gaming";
remote = "Gaming:";
type = "webdav";
extraArgs = [
"--addr=0.0.0.0:${toString ports.webdav_gaming}"
"--htpasswd=${secrets.webdav_gaming_htpasswd.path}"
"--baseurl=/Gaming/"
"--cache-dir=/caches/gaming_webdav_serve"
"--vfs-cache-max-age=5m"
"--vfs-cache-max-size=1g"
"--vfs-cache-mode=full"
];
}
{ {
id = "notes"; id = "notes";
remote = "Notes:"; remote = "Notes:";
@ -105,7 +59,7 @@ in {
} }
{ {
id = "music-ro"; id = "music-ro";
remote = "StorageBox:Music"; remote = "Storage:Music";
type = "http"; type = "http";
extraArgs = [ extraArgs = [
"--addr=0.0.0.0:${toString ports.http_music}" "--addr=0.0.0.0:${toString ports.http_music}"
@ -115,7 +69,7 @@ in {
} }
{ {
id = "public"; id = "public";
remote = "StorageBox:Public"; remote = "Storage:Public";
type = "http"; type = "http";
extraArgs = [ extraArgs = [
"--addr=0.0.0.0:${toString ports.http_public}" "--addr=0.0.0.0:${toString ports.http_public}"
@ -125,7 +79,7 @@ in {
} }
{ {
id = "uploads-public"; id = "uploads-public";
remote = "StorageBox:Uploads/Public"; remote = "Storage:Uploads/Public";
type = "http"; type = "http";
extraArgs = [ extraArgs = [
"--addr=0.0.0.0:${toString ports.http_uploads_public}" "--addr=0.0.0.0:${toString ports.http_uploads_public}"
@ -133,116 +87,6 @@ in {
"--read-only" "--read-only"
]; ];
} }
{
id = "restic-music";
remote = "StorageBox:Backups/Restic/Music";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_music}"
"--htpasswd=${secrets.restic_music_htpasswd.path}"
"--baseurl=/Music/"
];
}
{
id = "restic-vault";
remote = "StorageBox:Backups/Restic/Vault";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_vault}"
"--htpasswd=${secrets.restic_vault_htpasswd.path}"
"--baseurl=/Vault/"
];
}
{
id = "restic-social";
remote = "StorageBox:Backups/Restic/Social";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_social}"
"--htpasswd=${secrets.restic_social_htpasswd.path}"
"--baseurl=/Social/"
];
}
{
id = "restic-postgresql";
remote = "StorageBox:Backups/Restic/PostgreSQL";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_postgresql}"
"--htpasswd=${secrets.restic_postgresql_htpasswd.path}"
"--baseurl=/PostgreSQL/"
];
}
{
id = "restic-caldav";
remote = "StorageBox:Backups/Restic/CalDAV";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_caldav}"
"--htpasswd=${secrets.restic_caldav_htpasswd.path}"
"--baseurl=/CalDAV/"
];
}
{
id = "restic-mail";
remote = "StorageBox:Backups/Restic/Mail";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_mail}"
"--htpasswd=${secrets.restic_mail_htpasswd.path}"
"--baseurl=/Mail/"
];
}
{
id = "restic-forgejo";
remote = "StorageBox:Backups/Restic/Forgejo";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_forgejo}"
"--htpasswd=${secrets.restic_forgejo_htpasswd.path}"
"--baseurl=/Forgejo/"
];
}
{
id = "restic-owncast";
remote = "StorageBox:Backups/Restic/Owncast";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_owncast}"
"--htpasswd=${secrets.restic_owncast_htpasswd.path}"
"--baseurl=/Owncast/"
];
}
{
id = "restic-jellyfin";
remote = "StorageBox:Backups/Restic/Jellyfin";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_jellyfin}"
"--htpasswd=${secrets.restic_jellyfin_htpasswd.path}"
"--baseurl=/Jellyfin/"
];
}
{
id = "restic-grocy";
remote = "StorageBox:Backups/Restic/Grocy";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_grocy}"
"--htpasswd=${secrets.restic_grocy_htpasswd.path}"
"--baseurl=/Grocy/"
];
}
{
id = "restic-lappy-t495";
remote = "StorageBox:Backups/Restic/Lappy-T495";
type = "restic";
extraArgs = [
"--addr=0.0.0.0:${toString ports.restic_lappy_t495}"
"--htpasswd=${secrets.restic_lappy_t495_htpasswd.path}"
"--baseurl=/Lappy-T495/"
];
}
]; ];
}; };
} }

View file

@ -7,10 +7,6 @@ in {
syncJobs = map (syncJob: syncJobs = map (syncJob:
syncJob syncJob
// { // {
serviceConfig = {
after = ["auto-secrets.service"];
wants = ["auto-secrets.service"];
};
timerConfig = backupSchedules.remoteBackups; timerConfig = backupSchedules.remoteBackups;
extraArgs = [ extraArgs = [
"--fast-list" "--fast-list"
@ -21,66 +17,35 @@ in {
"--bwlimit 80M" "--bwlimit 80M"
]; ];
}) [ }) [
# My B2
{
source = "StorageBox:Backups";
dest = "B2-Chaos-Backups:";
id = "chaos_b2_backups";
}
{
source = "StorageBox:Photos";
dest = "B2-Chaos-Photos:";
id = "chaos_b2_photos";
}
{
source = "StorageBox:Music";
dest = "B2-Chaos-Music:";
id = "chaos_b2_music";
}
{
source = "StorageBox:Personal";
dest = "B2-Chaos-Personal:";
id = "chaos_b2_personal";
}
{
source = "StorageBox:Public";
dest = "B2-Chaos-Public:";
id = "chaos_b2_public";
}
{
source = "StorageBox:Notes";
dest = "B2-Chaos-Notes:";
id = "chaos_notes";
}
# Pheonix System's B2 # Pheonix System's B2
{ {
source = "StorageBox:Backups"; source = "Storage:Backups";
dest = "B2-Phoenix-Cryptidz-Storage:Backups"; dest = "B2-Phoenix-Cryptidz-Storage:Phoenix-Cryptidz-Storage/Backups";
id = "phoenix_b2_backups"; id = "phoenix_b2_backups";
} }
{ {
source = "StorageBox:Photos"; source = "Storage:Photos";
dest = "B2-Phoenix-Cryptidz-Storage:Photos"; dest = "B2-Phoenix-Cryptidz-Storage:Phoenix-Cryptidz-Storage/Photos";
id = "phoenix_b2_photos"; id = "phoenix_b2_photos";
} }
{ {
source = "StorageBox:Music"; source = "Storage:Music";
dest = "B2-Phoenix-Cryptidz-Storage:Music"; dest = "B2-Phoenix-Cryptidz-Storage:Phoenix-Cryptidz-Storage/Music";
id = "phoenix_b2_music"; id = "phoenix_b2_music";
} }
{ {
source = "StorageBox:Personal"; source = "Storage:Personal";
dest = "B2-Phoenix-Cryptidz-Storage:Personal"; dest = "B2-Phoenix-Cryptidz-Storage:Phoenix-Cryptidz-Storage/Personal";
id = "phoenix_b2_personal"; id = "phoenix_b2_personal";
} }
{ {
source = "StorageBox:Public"; source = "Storage:Public";
dest = "B2-Phoenix-Cryptidz-Storage:Public"; dest = "B2-Phoenix-Cryptidz-Storage:Phoenix-Cryptidz-Storage/Public";
id = "phoenix_b2_public"; id = "phoenix_b2_public";
} }
{ {
source = "StorageBox:Notes"; source = "B2-Chaos-Notes:Chaos-Notes:Notes";
dest = "B2-Phoenix-Cryptidz-Storage:Notes"; dest = "B2-Phoenix-Cryptidz-Storage:Phoenix-Cryptidz-Storage/Notes";
id = "phoenix_b2_notes"; id = "phoenix_b2_notes";
} }
]; ];

View file

@ -7,46 +7,23 @@
loginUsername = "hetzner-arm-container-storage"; loginUsername = "hetzner-arm-container-storage";
}; };
autoSecrets = {
enable = true;
};
requiredVaultPaths = [ requiredVaultPaths = [
"api-keys/data/hetzner/storagebox"
"api-keys/data/putio"
"api-keys/data/backblaze/Chaos-Backups" "api-keys/data/backblaze/Chaos-Backups"
"api-keys/data/backblaze/Chaos-Photos" "api-keys/data/backblaze/Chaos-Photos"
"api-keys/data/backblaze/Chaos-Music" "api-keys/data/backblaze/Chaos-Music"
"api-keys/data/backblaze/Chaos-Personal" "api-keys/data/backblaze/Chaos-Personal"
"api-keys/data/backblaze/Chaos-Public" "api-keys/data/backblaze/Chaos-Public"
"api-keys/data/backblaze/Chaos-Media" "api-keys/data/backblaze/Chaos-Media"
"api-keys/data/backblaze/Chaos-Gaming"
"api-keys/data/backblaze/Chaos-Notes" "api-keys/data/backblaze/Chaos-Notes"
"api-keys/data/backblaze/Chaos-Uploads"
"api-keys/data/backblaze/Phoenix-Cryptidz-Storage" "api-keys/data/backblaze/Phoenix-Cryptidz-Storage"
"api-keys/data/storage/restic/Music"
"api-keys/data/storage/restic/Vault"
"api-keys/data/storage/restic/Social"
"api-keys/data/storage/restic/PostgreSQL"
"api-keys/data/storage/restic/Mail"
"api-keys/data/storage/restic/Forgejo"
"api-keys/data/storage/restic/CalDAV"
"api-keys/data/storage/restic/Owncast"
"api-keys/data/storage/restic/Jellyfin"
"api-keys/data/storage/restic/Grocy"
"api-keys/data/storage/restic/Lappy-T495"
"api-keys/data/storage/webdav/Main" "api-keys/data/storage/webdav/Main"
"api-keys/data/storage/webdav/Media"
"api-keys/data/storage/webdav/Public" "api-keys/data/storage/webdav/Public"
"api-keys/data/storage/webdav/Uploads" "api-keys/data/storage/webdav/Uploads"
"api-keys/data/storage/webdav/Gaming"
"api-keys/data/storage/webdav/Notes" "api-keys/data/storage/webdav/Notes"
"private-public-keys/data/rclone/Chaos-Media-Crypt" "private-public-keys/data/rclone/Chaos-Media-Crypt"
"private-public-keys/data/rclone/Chaos-Gaming-Crypt"
"private-public-keys/data/rclone/Chaos-Notes-Crypt" "private-public-keys/data/rclone/Chaos-Notes-Crypt"
]; ];
@ -108,92 +85,6 @@
manual = true; manual = true;
}; };
restic_music_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Music" "$secretFile"
'';
};
restic_vault_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Vault" "$secretFile"
'';
};
restic_social_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Social" "$secretFile"
'';
};
restic_postgresql_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/PostgreSQL" "$secretFile"
'';
};
restic_mail_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Mail" "$secretFile"
'';
};
restic_forgejo_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Forgejo" "$secretFile"
'';
};
restic_caldav_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/CalDAV" "$secretFile"
'';
};
restic_owncast_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Owncast" "$secretFile"
'';
};
restic_jellyfin_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Jellyfin" "$secretFile"
'';
};
restic_grocy_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Grocy" "$secretFile"
'';
};
restic_lappy_t495_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/restic/Lappy-T495" "$secretFile"
'';
};
webdav_main_htpasswd = { webdav_main_htpasswd = {
user = "storage"; user = "storage";
group = "storage"; group = "storage";
@ -201,20 +92,6 @@
simple_get_htpasswd "/api-keys/storage/webdav/Main" "$secretFile" simple_get_htpasswd "/api-keys/storage/webdav/Main" "$secretFile"
''; '';
}; };
webdav_media_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/webdav/Media" "$secretFile"
'';
};
webdav_public_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/webdav/Public" "$secretFile"
'';
};
webdav_uploads_htpasswd = { webdav_uploads_htpasswd = {
user = "storage"; user = "storage";
group = "storage"; group = "storage";
@ -222,13 +99,6 @@
simple_get_htpasswd "/api-keys/storage/webdav/Uploads" "$secretFile" simple_get_htpasswd "/api-keys/storage/webdav/Uploads" "$secretFile"
''; '';
}; };
webdav_gaming_htpasswd = {
user = "storage";
group = "storage";
fetchScript = ''
simple_get_htpasswd "/api-keys/storage/webdav/Gaming" "$secretFile"
'';
};
webdav_notes_htpasswd = { webdav_notes_htpasswd = {
user = "storage"; user = "storage";
group = "storage"; group = "storage";
@ -243,10 +113,6 @@
fetchScript = '' fetchScript = ''
cp ${./data/rclone_config.template} "$secretFile" cp ${./data/rclone_config.template} "$secretFile"
STORAGEBOX_PASSWORD=$(simple_get_obscure /api-keys/hetzner/storagebox .password)
sed -i "s/STORAGEBOX_PASSWORD/$STORAGEBOX_PASSWORD/" "$secretFile"
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Gaming" "B2_CHAOS_GAMING" "$secretFile"
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Media" "B2_CHAOS_MEDIA" "$secretFile" simple_get_replace_b2 "/api-keys/backblaze/Chaos-Media" "B2_CHAOS_MEDIA" "$secretFile"
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Backups" "B2_CHAOS_BACKUPS" "$secretFile" simple_get_replace_b2 "/api-keys/backblaze/Chaos-Backups" "B2_CHAOS_BACKUPS" "$secretFile"
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Photos" "B2_CHAOS_PHOTOS" "$secretFile" simple_get_replace_b2 "/api-keys/backblaze/Chaos-Photos" "B2_CHAOS_PHOTOS" "$secretFile"
@ -254,14 +120,10 @@
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Personal" "B2_CHAOS_PERSONAL" "$secretFile" simple_get_replace_b2 "/api-keys/backblaze/Chaos-Personal" "B2_CHAOS_PERSONAL" "$secretFile"
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Public" "B2_CHAOS_PUBLIC" "$secretFile" simple_get_replace_b2 "/api-keys/backblaze/Chaos-Public" "B2_CHAOS_PUBLIC" "$secretFile"
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Notes" "B2_CHAOS_NOTES" "$secretFile" simple_get_replace_b2 "/api-keys/backblaze/Chaos-Notes" "B2_CHAOS_NOTES" "$secretFile"
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Uploads" "B2_CHAOS_UPLOADS" "$secretFile"
simple_get_replace_b2 "/api-keys/backblaze/Phoenix-Cryptidz-Storage" "B2_PHOENIX_CRYPTIDZ_STORAGE" "$secretFile" simple_get_replace_b2 "/api-keys/backblaze/Phoenix-Cryptidz-Storage" "B2_PHOENIX_CRYPTIDZ_STORAGE" "$secretFile"
PUTIO_PASSWORD="token/$(simple_get /api-keys/putio .oauth_token)"
PUTIO_PASSWORD="$(rclone obscure "$PUTIO_PASSWORD")"
sed -i "s/PUTIO_PASSWORD/$PUTIO_PASSWORD/" "$secretFile"
simple_get_replace_crypt "/private-public-keys/rclone/Chaos-Media-Crypt" "STORAGE_MEDIA_CRYPT" "$secretFile" simple_get_replace_crypt "/private-public-keys/rclone/Chaos-Media-Crypt" "STORAGE_MEDIA_CRYPT" "$secretFile"
simple_get_replace_crypt "/private-public-keys/rclone/Chaos-Gaming-Crypt" "STORAGE_GAMING_CRYPT" "$secretFile"
simple_get_replace_crypt "/private-public-keys/rclone/Chaos-Notes-Crypt" "STORAGE_NOTES_CRYPT" "$secretFile" simple_get_replace_crypt "/private-public-keys/rclone/Chaos-Notes-Crypt" "STORAGE_NOTES_CRYPT" "$secretFile"
''; '';
}; };

View file

@ -1,34 +0,0 @@
{
self,
pkgs,
config,
...
}: let
backupSchedules = import "${self}/data/backupSchedules.nix";
inherit (config.services.secrets) secrets;
in {
environment.systemPackages = with pkgs; [
restic
(pkgs.writeShellScriptBin "restic-vault" ''
env \
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
$(cat ${secrets.restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.vault = {
user = "root";
paths = [
"/var/lib/vault"
"/var/lib/private/step-ca"
];
timerConfig = backupSchedules.restic.high;
# repository is overrided in environmentFile to contain auth
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/Vault";
passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}";
};
}

View file

@ -9,9 +9,9 @@
}: let }: let
containerAddresses = import "${hostPath}/data/containerAddresses.nix"; containerAddresses = import "${hostPath}/data/containerAddresses.nix";
hostIP = containerAddresses.host; hostIP = containerAddresses.host;
containerIP = containerAddresses.containers.vault-ca; containerIP = containerAddresses.containers.vault;
in { in {
containers.vault-ca = { containers.vault = {
autoStart = true; autoStart = true;
privateNetwork = true; privateNetwork = true;
hostAddress = hostIP; hostAddress = hostIP;
@ -33,7 +33,7 @@ in {
presets.nixos.containerBase presets.nixos.containerBase
./secrets.nix ./secrets.nix
] ]
++ (with hosts.hetzner-arm.containers.vault-ca.profiles; [ ++ (with hosts.hetzner-arm.containers.vault.profiles; [
vault vault
#internalCA #internalCA
restic restic

View file

@ -0,0 +1,22 @@
{
self,
config,
...
}: let
backupSchedules = import "${self}/data/backupSchedules.nix";
inherit (config.services.secrets) secrets;
in {
services.restic.backups.vault = {
user = "root";
paths = [
"/var/lib/vault"
"/var/lib/private/step-ca"
];
timerConfig = backupSchedules.restic.high;
repository = "s3:s3.eu-central-003.backblazeb2.com/Chaos-Backups/Restic/Vault";
passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}";
createWrapper = true;
};
}

View file

@ -8,18 +8,13 @@
vaultLogin = { vaultLogin = {
enable = true; enable = true;
# TODO: change to hetzner-arm-container-vault-ca loginUsername = "hetzner-arm-container-vault";
loginUsername = "vault";
};
autoSecrets = {
enable = true;
}; };
requiredVaultPaths = [ requiredVaultPaths = [
"private-public-keys/data/restic/Vault" "private-public-keys/data/restic/Vault"
"api-keys/data/storage/restic/Vault" "api-keys/data/backblaze/Chaos-Backups"
"infra/data/internalCAPassword" "infra/data/internalCAPassword"
]; ];
@ -36,8 +31,10 @@
}; };
restic_env = { restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Vault" .restic) cat << EOF > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Vault" > "$secretFile" AWS_ACCESS_KEY_ID=$(simple_get "/api-keys/backblaze/Chaos-Backups" .keyID)
AWS_SECRET_ACCESS_KEY=$(simple_get "/api-keys/backblaze/Chaos-Backups" .applicationKey)
EOF
''; '';
}; };

View file

@ -11,6 +11,6 @@
jellyfin = "10.0.1.9"; jellyfin = "10.0.1.9";
grocy = "10.0.1.10"; grocy = "10.0.1.10";
rss = "10.0.1.11"; rss = "10.0.1.11";
vault-ca = "10.0.1.12"; vault = "10.0.1.12";
}; };
} }

View file

@ -28,10 +28,8 @@ in {
"caldav" "caldav"
"jellyfin" "jellyfin"
"grocy" "grocy"
"vault-ca" "vault"
"music" "music"
# "owncast"
# TODO: "rss"
] (name: ./containers + "/${name}")) ] (name: ./containers + "/${name}"))
++ (with hosts.hetzner-arm.profiles; [ ++ (with hosts.hetzner-arm.profiles; [
staticSites staticSites

View file

@ -7,13 +7,6 @@
loginUsername = "hetzner-arm"; loginUsername = "hetzner-arm";
}; };
autoSecrets = {
enable = true;
affectedSystemdServices = [
"wg-quick-wg0"
];
};
requiredVaultPaths = [ requiredVaultPaths = [
"private-public-keys/data/ssh/root@hetzner-arm" "private-public-keys/data/ssh/root@hetzner-arm"
"private-public-keys/data/ssh/root@hetzner-arm-decrypt" "private-public-keys/data/ssh/root@hetzner-arm-decrypt"

View file

@ -13,34 +13,6 @@
simple_get "/api-keys/music-stream" .password > "$secretFile" simple_get "/api-keys/music-stream" .password > "$secretFile"
''; '';
}; };
# Required for home.apps.manualBackupApps
restic_music_env = {
user = "chaos";
fetchScript = ''
api_username=restic
api_password=$(simple_get "/api-keys/storage/restic/Music" ".$api_username")
restic_password=$(simple_get "/private-public-keys/restic/Music" .password)
echo > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://$api_username:$api_password@storage-restic.owo.monster/Music" >> "$secretFile"
echo "RESTIC_PASSWORD=''${restic_password}" >> "$secretFile"
'';
};
#restic_backups_password = {
# fetchScript = ''
# simple_get "/private-public-keys/restic/Lappy-Surface" .password > "$secretFile"
# '';
#};
#restic_backups_repository_file = {
# fetchScript = ''
# api_username=restic
# api_password=$(simple_get "/api-keys/storage/restic/Lappy-Surface" ".$api_username")
# echo "rest:https://$api_username:$api_password@storage-restic.owo.monster/Lappy-Surface" > "$secretFile"
# '';
#};
}; };
}; };
} }

View file

@ -14,8 +14,6 @@
profiles.gaming.steam profiles.gaming.steam
hosts.lappy-t495.profiles.restic
./secrets.nix ./secrets.nix
]; ];

View file

@ -1,28 +0,0 @@
{config, ...}: let
inherit (config.services.secrets) secrets;
in {
services.restic.backups.lappy-t495 = {
user = "root";
createWrapper = true;
paths = [
"/etc/NetworkManager/system-connections"
"/home/chaos/Projects"
];
extraBackupArgs = [
"--exclude-caches"
"--exclude=node_modules"
"--exclude=/home/chaos/Projects/*/target"
];
repositoryFile = "${secrets.restic_backups_repository_file.path}";
passwordFile = "${secrets.restic_backups_password.path}";
pruneOpts = ["--keep-within=14d"];
timerConfig = {
OnStartupSec = "5m";
OnUnitActiveSec = "30m";
};
};
}

View file

@ -13,35 +13,6 @@
simple_get "/api-keys/music-stream" .password > "$secretFile" simple_get "/api-keys/music-stream" .password > "$secretFile"
''; '';
}; };
# Required for home.apps.manualBackupApps
restic_music_env = {
user = "chaos";
fetchScript = ''
api_username=restic
api_password=$(simple_get "/api-keys/storage/restic/Music" ".$api_username")
restic_password=$(simple_get "/private-public-keys/restic/Music" .password)
echo > "$secretFile"
echo "RESTIC_REPOSITORY=rest:https://$api_username:$api_password@storage-restic.owo.monster/Music" >> "$secretFile"
echo "RESTIC_PASSWORD=''${restic_password}" >> "$secretFile"
'';
};
restic_backups_password = {
fetchScript = ''
simple_get "/private-public-keys/restic/Lappy-T495" .password > "$secretFile"
'';
};
restic_backups_repository_file = {
fetchScript = ''
api_username=restic
api_password=$(simple_get "/api-keys/storage/restic/Lappy-T495" ".$api_username")
echo "rest:https://$api_username:$api_password@storage-restic.owo.monster/Lappy-T495" > "$secretFile"
'';
};
}; };
}; };
} }

View file

@ -7,11 +7,6 @@
loginUsername = "raspberry"; loginUsername = "raspberry";
}; };
autoSecrets = {
enable = true;
affectedSystemdServices = ["wg-quick-wg0"];
};
# some are also added from wireguard internal config # some are also added from wireguard internal config
requiredVaultPaths = [ requiredVaultPaths = [
"private-public-keys/data/cryptsetup/raspberry-ext-drive" # used dynamically "private-public-keys/data/cryptsetup/raspberry-ext-drive" # used dynamically

View file

@ -13,6 +13,8 @@ final: prev: rec {
cp -r ${./kitty-terminfo}/* $out/share cp -r ${./kitty-terminfo}/* $out/share
''; '';
vault = prev.vault-bin;
mpd-headless = mpd-headless =
(prev.mpdWithFeatures.override { (prev.mpdWithFeatures.override {
ffmpeg = final.ffmpeg_6-headless; ffmpeg = final.ffmpeg_6-headless;

View file

@ -66,19 +66,15 @@ in {
routes = [ routes = [
# v4 # v4
{ {
routeConfig = { Destination = gateway;
Destination = gateway;
};
} }
{ {
routeConfig = { Gateway = gateway;
Gateway = gateway; GatewayOnLink = true;
GatewayOnLink = true;
};
} }
# v6 # v6
{ {
routeConfig.Gateway = "fe80::1"; Gateway = "fe80::1";
} }
]; ];
}; };

View file

@ -34,6 +34,8 @@ in {
Lists all failed units in host and containers Lists all failed units in host and containers
- restart-service-all - restart-service-all
Restarts a service on host and all containers Restarts a service on host and all containers
- run-command-all
Runs a command on host and all containers
- shell-enter-`$name` - shell-enter-`$name`
Opens an interactive shell with container Opens an interactive shell with container
''} ''}
@ -63,6 +65,14 @@ in {
systemctl -M ${name} restart $@ systemctl -M ${name} restart $@
''))} ''))}
'') '')
(writeShellScriptBin "run-command-all" ''
echo "Host: "
$@
${concatStringsSep "\n" (forEach containerNames (name: ''
echo "Container: ${name}"
machinectl shell ${name} $@
''))}
'')
] ]
++ forEach containerNames (name: (writeShellScriptBin "journalctl-vaccum-${name}" '' ++ forEach containerNames (name: (writeShellScriptBin "journalctl-vaccum-${name}" ''
journalctl --vacuum-size=${vaccumSize} --root /var/lib/nixos-containers/${name} journalctl --vacuum-size=${vaccumSize} --root /var/lib/nixos-containers/${name}