nixfiles/hosts/storage/storage.nix

256 lines
6.6 KiB
Nix

{ modulesPath, tree, config, pkgs, lib, ... }:
let
secrets-db = (import ./secrets-db.nix { });
ports = (import ./ports.nix { });
in {
imports = with tree; [
users.root
profiles.base
profiles.sshd
profiles.nix-gc
profiles.nginx
./hardware.nix
./networking.nix
./secrets.nix
./wireguard.nix
];
systemd.tmpfiles.rules = [
"d /storage - root root"
"d /caches - storage storage"
"d /caches/main_webdav_serve - storage storage"
];
users.groups.storage = { };
users.users.storage = {
isNormalUser = true;
extraGroups = [ "storage" ];
};
systemd.services.populate-rclone-config = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = with pkgs; [ bash rclone vault getent jq ];
script = let
vault_username = "storage";
vault_password_file = "${secrets-db.vault_password.path}";
config_dir = "/home/storage/.config/rclone";
config_file = "/home/storage/.config/rclone/rclone.conf";
in ''
mkdir -p ${config_dir}
VAULT_ADDR="https://vault.owo.monster" bash ${
./populate-rclone-config.sh
} ${vault_username} ${vault_password_file} ${
./rclone_config.template
} ${config_file}
chown storage:storage ${config_file}
chmod 660 ${config_file}
'';
};
systemd.services.storage-mount = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "populate-rclone-config.service" ];
partOf = [ "populate-rclone-config.service" ];
path = with pkgs; [ bash rclone mount umount ];
script = ''
set -e
umount /storage -fl || true
sleep 2
rclone --config /home/storage/.config/rclone/rclone.conf mount StorageBox: /storage --allow-non-empty
'';
};
services.rclone-serve = let
serviceConfig = {
after = [ "populate-rclone-config.service" ];
partOf = [ "populate-rclone-config.service" ];
};
in {
enable = true;
remotes = [
{
user = "storage";
remote = "StorageBox:";
type = "webdav";
extraArgs = [
"--addr=:${toString ports.rclone_serve_webdav_main}"
"--htpasswd=${secrets-db.webdav_main_htpasswd.path}"
"--baseurl=/main/"
"--cache-dir=/caches/main_webdav_serve"
"--vfs-cache-mode=full"
];
inherit serviceConfig;
}
{
user = "storage";
remote = "StorageBox:Music";
type = "webdav";
extraArgs = [
"--addr=:${toString ports.rclone_serve_webdav_music_ro}"
"--read-only"
"--baseurl=/music_ro/"
];
inherit serviceConfig;
}
{
user = "storage";
remote = "StorageBox:Music";
type = "http";
extraArgs = [
"--addr=:${toString ports.rclone_serve_http_music}"
"--baseurl=/Music/"
"--read-only"
];
inherit serviceConfig;
}
{
user = "storage";
remote = "StorageBox:Public";
type = "http";
extraArgs = [
"--addr=:${toString ports.rclone_serve_http_public}"
"--baseurl=/Public/"
"--read-only"
];
inherit serviceConfig;
}
{
user = "storage";
remote = "StorageBox:Backups/Restic/HetznerVM";
type = "restic";
extraArgs = [
"--addr=:${toString ports.rclone_serve_restic_hvm}"
"--htpasswd=${secrets-db.restic_hetznervm_htpasswd.path}"
"--baseurl=/HetznerVM/"
];
inherit serviceConfig;
}
{
user = "storage";
remote = "StorageBox:Backups/Restic/Music";
type = "restic";
extraArgs = [
"--addr=:${toString ports.rclone_serve_restic_music}"
"--htpasswd=${secrets-db.restic_music_htpasswd.path}"
"--baseurl=/Music/"
];
inherit serviceConfig;
}
{
user = "storage";
remote = "StorageBox:Backups/Restic/Vault";
type = "restic";
extraArgs = [
"--addr=:${toString ports.rclone_serve_restic_vault}"
"--htpasswd=${secrets-db.restic_vault_htpasswd.path}"
"--baseurl=/Vault/"
];
inherit serviceConfig;
}
];
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx.virtualHosts."storage-webdav.owo.monster" = {
forceSSL = true;
enableACME = true;
locations = {
"/main/".proxyPass =
"http://localhost:${toString ports.rclone_serve_webdav_main}";
"/music_ro/".proxyPass =
"http://localhost:${toString ports.rclone_serve_webdav_music_ro}";
};
};
services.nginx.virtualHosts."storage-http.owo.monster" = {
forceSSL = true;
enableACME = true;
locations = {
"/Music/".proxyPass =
"http://localhost:${toString ports.rclone_serve_http_music}";
"/Public/".proxyPass =
"http://localhost:${toString ports.rclone_serve_http_public}";
};
};
services.nginx.virtualHosts."storage-restic.owo.monster" = {
forceSSL = true;
enableACME = true;
locations = {
"/HetznerVM/".proxyPass =
"http://localhost:${toString ports.rclone_serve_restic_hvm}";
"/Music/".proxyPass =
"http://localhost:${toString ports.rclone_serve_restic_music}";
"/Vault/".proxyPass =
"http://localhost:${toString ports.rclone_serve_restic_vault}";
};
};
services.rclone-sync = let
sync_defaults = {
serviceConfig = { after = [ "populate-rclone-config.service" ]; };
timerConfig = {
OnStartupSec = "60";
OnCalendar = "4h";
};
};
in {
enable = true;
user = "storage";
sync_jobs = map (x: lib.mkMerge [ x sync_defaults ]) [
# My B2
{
source = "StorageBox:Backups";
dest = "B2-Chaos-Backups:";
}
{
source = "StorageBox:Photos";
dest = "B2-Chaos-Photos:";
}
{
source = "StorageBox:Music";
dest = "B2-Chaos-Music:";
}
# Pheonix System's B2
{
source = "StorageBox:Backups";
dest = "B2-Phoenix-Cryptidz-Storage:Backups";
}
{
source = "StorageBox:Photos";
dest = "B2-Phoenix-Cryptidz-Storage:Photos";
}
{
source = "StorageBox:Music";
dest = "B2-Phoenix-Cryptidz-Storage:Music";
}
];
};
environment.systemPackages = with pkgs; [
rclone
cifs-utils
apacheHttpd
restic
];
home-manager.users.root = {
imports = with tree; [ home.base home.dev.small ];
home.stateVersion = "22.05";
};
networking.hostName = "storage";
time.timeZone = "Europe/London";
system.stateVersion = "21.11";
}