{ modulesPath, tree, config, pkgs, lib, ... }: { imports = with tree; [ users.root profiles.base profiles.sshd profiles.nix-gc profiles.nginx ./hardware.nix ./networking.nix ]; systemd.tmpfiles.rules = [ "d /secrets - root root" # "d /storage - root root" ]; 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/vault_password"; in '' mkdir -p /home/storage/.config/rclone VAULT_ADDR="https://vault.owo.monster" bash ${ ./populate-rclone-config.sh } ${vault_username} ${vault_password_file} ${ ./rclone_config.template } /home/storage/.config/rclone/rclone.conf chown storage:storage /home/storage/.config/rclone/rclone.conf chmod 660 /home/storage/.config/rclone/rclone.conf ''; }; systemd.services.storage-mount = { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; wants = [ "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 = { enable = true; remotes = [ { user = "storage"; remote = "StorageBox:"; type = "webdav"; wants = [ "populate-rclone-config.service" ]; extraArgs = [ "--addr=:4242" "--htpasswd=/secrets/webdav_htpasswd" ]; } { user = "storage"; remote = "StorageBox:Chaos-Backups/Restic/HetznerVM"; type = "restic"; wants = [ "populate-rclone-config.service" ]; extraArgs = [ "--addr=:4243" "--htpasswd=/secrets/restic_hetznervm_htpasswd" "--baseurl=/HetznerVM/" ]; } { user = "storage"; remote = "StorageBox:Chaos-Backups/Restic/Music"; type = "restic"; wants = [ "populate-rclone-config.service" ]; extraArgs = [ "--addr=:4244" "--htpasswd=/secrets/restic_music_htpasswd" "--baseurl=/Music/" ]; } { user = "storage"; remote = "StorageBox:Chaos-Backups/Restic/Vault"; type = "restic"; wants = [ "populate-rclone-config.service" ]; extraArgs = [ "--addr=:4245" "--htpasswd=/secrets/restic_vault_htpasswd" "--baseurl=/Vault/" ]; } ]; }; networking.firewall.allowedTCPPorts = [ 80 443 ]; services.nginx.virtualHosts."storage-webdav.owo.monster" = { forceSSL = true; enableACME = true; locations = { "/".proxyPass = "http://localhost:4242"; }; }; services.nginx.virtualHosts."storage-restic.owo.monster" = { forceSSL = true; enableACME = true; locations = { "/HetznerVM/".proxyPass = "http://localhost:4243"; "/Music/".proxyPass = "http://localhost:4244"; "/Vault/".proxyPass = "http://localhost:4245"; }; }; services.rclone-sync = { enable = true; user = "storage"; sync_jobs = [ { source = "StorageBox:Chaos-Backups"; dest = "B2-Chaos-Backups:"; wants = [ "populate-rclone-config.service" ]; timerConfig = { OnStartupSec = "60"; OnCalendar = "4h"; }; } { source = "StorageBox:Chaos-Photos"; dest = "B2-Chaos-Photos:"; wants = [ "populate-rclone-config.service" ]; timerConfig = { OnStartupSec = "60"; OnCalendar = "4h"; }; } ]; }; 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"; }