moved storage host to a container inside hetzner-vm

This commit is contained in:
Chaos 2022-12-15 14:33:39 +00:00
parent 39ab88cf0c
commit 0471cbb9df
No known key found for this signature in database
20 changed files with 780 additions and 787 deletions

View file

@ -1,4 +1,4 @@
{}: { {...}: {
rclone_serve_webdav_main = 4242; rclone_serve_webdav_main = 4242;
rclone_serve_webdav_media = 4243; rclone_serve_webdav_media = 4243;
rclone_serve_webdav_music_ro = 4244; rclone_serve_webdav_music_ro = 4244;

View file

@ -0,0 +1,21 @@
{
pkgs,
config,
...
}: let
secrets = config.services.secrets.secrets;
in {
systemd.services.auto-secrets = {
wantedBy = ["multi-user.target"];
after = ["network.target"];
path = with pkgs; [bash vault getent];
script = let
vault_username = "storage";
vault_password_file = "${secrets.vault_password.path}";
in ''
VAULT_ADDR="https://vault.owo.monster" \
vault login -no-print -method=userpass username=${vault_username} password=$(cat ${vault_password_file})
/run/current-system/sw/bin/secrets-init
'';
};
}

View file

@ -0,0 +1,13 @@
{config, ...}: let
secrets = config.services.secrets.secrets;
in {
systemd.tmpfiles.rules = [
"d /root/.config - root root"
"d /root/.config/rclone - root root"
"L /root/.config/rclone/rclone.conf - - - - ${secrets.rclone_config.path}"
"d /home/storage/.config - storage storage"
"d /home/storage/.config/rclone - storage storage"
"L /home/storage/.config/rclone/rclone.conf - - - - ${secrets.rclone_config.path}"
];
}

View file

@ -1,6 +1,6 @@
{config, ...}: let {config, ...}: let
secrets = config.services.secrets.secrets; secrets = config.services.secrets.secrets;
ports = import ../ports.nix {}; ports = import ../data/ports.nix {};
in { in {
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /caches - storage storage" "d /caches - storage storage"
@ -10,8 +10,8 @@ in {
services.rclone-serve = let services.rclone-serve = let
serviceConfig = { serviceConfig = {
after = ["secrets-init.service"]; after = ["auto-secrets.service"];
partOf = ["secrets-init.service"]; partOf = ["auto-secrets.service"];
}; };
in { in {
enable = true; enable = true;
@ -21,7 +21,7 @@ in {
remote = "StorageBox:"; remote = "StorageBox:";
type = "webdav"; type = "webdav";
extraArgs = [ extraArgs = [
"--addr=:${toString ports.rclone_serve_webdav_main}" "--addr=0.0.0.0:${toString ports.rclone_serve_webdav_main}"
"--htpasswd=${secrets.webdav_main_htpasswd.path}" "--htpasswd=${secrets.webdav_main_htpasswd.path}"
"--baseurl=/main/" "--baseurl=/main/"
"--cache-dir=/caches/main_webdav_serve" "--cache-dir=/caches/main_webdav_serve"
@ -34,7 +34,7 @@ in {
remote = "Media-Combine-Serve:"; remote = "Media-Combine-Serve:";
type = "webdav"; type = "webdav";
extraArgs = [ extraArgs = [
"--addr=:${toString ports.rclone_serve_webdav_media}" "--addr=0.0.0.0:${toString ports.rclone_serve_webdav_media}"
"--htpasswd=${secrets.webdav_media_htpasswd.path}" "--htpasswd=${secrets.webdav_media_htpasswd.path}"
"--baseurl=/media/" "--baseurl=/media/"
"--cache-dir=/caches/media_webdav_serve" "--cache-dir=/caches/media_webdav_serve"
@ -49,7 +49,7 @@ in {
remote = "StorageBox:Music"; remote = "StorageBox:Music";
type = "webdav"; type = "webdav";
extraArgs = [ extraArgs = [
"--addr=:${toString ports.rclone_serve_webdav_music_ro}" "--addr=0.0.0.0:${toString ports.rclone_serve_webdav_music_ro}"
"--read-only" "--read-only"
"--baseurl=/music_ro/" "--baseurl=/music_ro/"
]; ];
@ -60,7 +60,7 @@ in {
remote = "StorageBox:Music"; remote = "StorageBox:Music";
type = "http"; type = "http";
extraArgs = [ extraArgs = [
"--addr=:${toString ports.rclone_serve_http_music}" "--addr=0.0.0.0:${toString ports.rclone_serve_http_music}"
"--baseurl=/Music/" "--baseurl=/Music/"
"--read-only" "--read-only"
]; ];
@ -71,7 +71,7 @@ in {
remote = "StorageBox:Public"; remote = "StorageBox:Public";
type = "http"; type = "http";
extraArgs = [ extraArgs = [
"--addr=:${toString ports.rclone_serve_http_public}" "--addr=0.0.0.0:${toString ports.rclone_serve_http_public}"
"--baseurl=/Public/" "--baseurl=/Public/"
"--read-only" "--read-only"
]; ];
@ -82,7 +82,7 @@ in {
remote = "StorageBox:Backups/Restic/HetznerVM"; remote = "StorageBox:Backups/Restic/HetznerVM";
type = "restic"; type = "restic";
extraArgs = [ extraArgs = [
"--addr=:${toString ports.rclone_serve_restic_hvm}" "--addr=0.0.0.0:${toString ports.rclone_serve_restic_hvm}"
"--htpasswd=${secrets.restic_hetznervm_htpasswd.path}" "--htpasswd=${secrets.restic_hetznervm_htpasswd.path}"
"--baseurl=/HetznerVM/" "--baseurl=/HetznerVM/"
]; ];
@ -93,7 +93,7 @@ in {
remote = "StorageBox:Backups/Restic/Music"; remote = "StorageBox:Backups/Restic/Music";
type = "restic"; type = "restic";
extraArgs = [ extraArgs = [
"--addr=:${toString ports.rclone_serve_restic_music}" "--addr=0.0.0.0:${toString ports.rclone_serve_restic_music}"
"--htpasswd=${secrets.restic_music_htpasswd.path}" "--htpasswd=${secrets.restic_music_htpasswd.path}"
"--baseurl=/Music/" "--baseurl=/Music/"
]; ];
@ -104,7 +104,7 @@ in {
remote = "StorageBox:Backups/Restic/Vault"; remote = "StorageBox:Backups/Restic/Vault";
type = "restic"; type = "restic";
extraArgs = [ extraArgs = [
"--addr=:${toString ports.rclone_serve_restic_vault}" "--addr=0.0.0.0:${toString ports.rclone_serve_restic_vault}"
"--htpasswd=${secrets.restic_vault_htpasswd.path}" "--htpasswd=${secrets.restic_vault_htpasswd.path}"
"--baseurl=/Vault/" "--baseurl=/Vault/"
]; ];
@ -112,37 +112,4 @@ in {
} }
]; ];
}; };
networking.firewall.allowedTCPPorts = [80 443];
services.nginx.clientMaxBodySize = "${toString (8192 * 4)}m";
services.nginx.virtualHosts."storage-webdav.owo.monster" = {
forceSSL = true;
enableACME = true;
locations = {
"/main/".proxyPass = "http://localhost:${toString ports.rclone_serve_webdav_main}";
"/media/".proxyPass = "http://localhost:${toString ports.rclone_serve_webdav_media}";
"/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}";
};
};
} }

View file

@ -1,7 +1,7 @@
{lib, ...}: { {lib, ...}: {
services.rclone-sync = let services.rclone-sync = let
sync_defaults = { sync_defaults = {
serviceConfig = {after = ["secrets-init.service"];}; serviceConfig = {after = ["auto-secrets.service"];};
timerConfig = { timerConfig = {
OnStartupSec = "60"; OnStartupSec = "60";
OnCalendar = "4h"; OnCalendar = "4h";

View file

@ -59,7 +59,7 @@ hard_delete = true
[B2-Phoenix-Cryptidz-Storage] [B2-Phoenix-Cryptidz-Storage]
type = alias type = alias
remote = B2-Phoenix-Cryptidz-Storage-Source: remote = B2-Phoenix-Cryptidz-Storage-Source:Phoenix-Cryptidz-Storage
[PutIO-WebDAV] [PutIO-WebDAV]
type = webdav type = webdav

View file

@ -0,0 +1,21 @@
{
pkgs,
config,
...
}: let
secrets = config.services.secrets.secrets;
in {
systemd.services.storage-mount = {
wantedBy = ["multi-user.target"];
after = ["network.target" "auto-secrets.service"];
partOf = ["auto-secrets.service"];
path = with pkgs; [bash rclone mount umount];
script = ''
set -e
umount /storage -fl || true
sleep 2
rclone --config ${secrets.rclone_config.path} mount StorageBox: /storage --allow-non-empty
'';
};
}

View file

@ -0,0 +1,7 @@
{...}: {
users.groups.storage = {};
users.users.storage = {
isNormalUser = true;
extraGroups = ["storage"];
};
}

View file

@ -0,0 +1,105 @@
{
tree,
lib,
inputs,
...
}: let
hostIP = "192.168.100.10";
containerIP = "192.168.100.11";
ports = import ./data/ports.nix {};
in {
networking.nat = {
enable = true;
internalInterfaces = ["ve-+"];
externalInterface = "eth0";
};
containers.storage = {
autoStart = true;
privateNetwork = true;
hostAddress = hostIP;
localAddress = containerIP;
config = {
config,
pkgs,
...
}: let
secrets = config.services.secrets.secrets;
in {
_module.args = {
inherit inputs;
inherit tree;
};
imports = with tree;
[
profiles.base
inputs.home-manager-unstable.nixosModules.home-manager
profiles.sshd
modules.nixos.rclone-serve
modules.nixos.rclone-sync
modules.nixos.secrets
users.root
]
++ (with hosts.hetzner-vm.containers.storage; [
profiles.secrets
profiles.auto-secrets
profiles.rclone-configs
profiles.rclone-serve
profiles.rclone-sync
profiles.storage-mount
profiles.users
]);
home-manager.users.root = {
imports = with tree; [home.base home.dev.small];
home.packages = with pkgs; [vault];
home.stateVersion = "22.05";
};
networking.firewall = {
enable = true;
allowedTCPPorts = [22] ++ lib.mapAttrsToList (_name: value: value) ports;
};
# Manually configure nameserver. Using resolved inside the container seems to fail
# currently
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
system.stateVersion = "22.05";
};
};
services.nginx.clientMaxBodySize = "${toString (8192 * 4)}m";
services.nginx.virtualHosts."storage-webdav.owo.monster" = {
forceSSL = true;
enableACME = true;
locations = {
"/main/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_webdav_main}";
"/media/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_webdav_media}";
"/music_ro/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_webdav_music_ro}";
};
};
services.nginx.virtualHosts."storage-http.owo.monster" = {
forceSSL = true;
enableACME = true;
locations = {
"/Music/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_http_music}";
"/Public/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_http_public}";
};
};
services.nginx.virtualHosts."storage-restic.owo.monster" = {
forceSSL = true;
enableACME = true;
locations = {
"/HetznerVM/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_hvm}";
"/Music/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_music}";
"/Vault/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_vault}";
};
};
}

View file

@ -10,6 +10,8 @@
profiles.nginx profiles.nginx
profiles.nix-gc profiles.nix-gc
./containers/storage/storage.nix
hosts.hetzner-vm.profiles.restic hosts.hetzner-vm.profiles.restic
#hosts.hetzner-vm.profiles.invidious #hosts.hetzner-vm.profiles.invidious
hosts.hetzner-vm.profiles.piped hosts.hetzner-vm.profiles.piped

View file

@ -44,12 +44,6 @@ in {
modules = defaultModules ++ [./hetzner-vm/hetzner-vm.nix]; modules = defaultModules ++ [./hetzner-vm/hetzner-vm.nix];
}; };
storage = nixosUnstableSystem {
specialArgs = defaultSpecialArgs;
system = "x86_64-linux";
modules = defaultModules ++ [./storage/storage.nix];
};
vault = nixosUnstableSystem { vault = nixosUnstableSystem {
specialArgs = defaultSpecialArgs; specialArgs = defaultSpecialArgs;
system = "x86_64-linux"; system = "x86_64-linux";

View file

@ -1,11 +0,0 @@
{modulesPath, ...}: {
imports = [(modulesPath + "/profiles/qemu-guest.nix")];
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.initrd.kernelModules = ["nvme"];
fileSystems."/" = {
device = "/dev/sda1";
fsType = "ext4";
};
}

View file

@ -1,19 +0,0 @@
{lib, ...}: {
systemd.services.systemd-networkd-wait-online.enable = lib.mkForce false;
networking.firewall.enable = true;
networking.firewall.allowPing = true;
networking.firewall.allowedTCPPorts = [22];
networking.enableIPv6 = true;
networking.usePredictableInterfaceNames = false;
networking.dhcpcd.enable = true;
systemd.network = {
enable = true;
networks.eth0 = {
name = "eth0";
address = ["2a01:4f9:c010:3e92::1/64"];
gateway = ["fe80::1"];
};
};
}

View file

@ -1,42 +0,0 @@
{config, ...}: let
secrets = config.services.secrets.secrets;
in {
networking.wg-quick.interfaces = {
wg0 = {
address = ["10.69.42.4/32"];
listenPort = 51820;
privateKeyFile = "${secrets.wg_privkey.path}";
peers = [
# hetzner-vm
{
publicKey = "UJr+EmUM7KWkIy0nk0JA38ibvcLC++6iuOKkHdrx9Dc=";
presharedKeyFile = "${secrets.wg_preshared_hetzner-vm.path}";
allowedIPs = ["10.69.42.1/32"];
endpoint = "hetzner-vm.servers.genderfucked.monster:51820";
persistentKeepalive = 25;
}
# tablet
{
publicKey = "jXA0DeprEaL/ARQ3K81l8xWuUI5C/90DcY3bIfcIjz8=";
presharedKeyFile = "${secrets.wg_preshared_tablet.path}";
allowedIPs = ["10.69.42.2/32"];
}
# vault
{
publicKey = "IGq+WanFM/bKNUkwjO/0AAtDhJLvtvU+mVxH27QyHTc=";
presharedKeyFile = "${secrets.wg_preshared_vault.path}";
endpoint = "vault.servers.genderfucked.monster:51820";
allowedIPs = ["10.69.42.3/32"];
}
# iphone8
{
publicKey = "2BgT08bDKh8WlFFSeRArI9a1GpFgUyqEApvJy4KgAmw=";
presharedKeyFile = "${secrets.wg_preshared_iphone8.path}";
allowedIPs = ["10.69.42.5/32"];
}
];
};
};
networking.firewall.allowedUDPPorts = [51820];
}

View file

@ -1,86 +0,0 @@
{
tree,
config,
pkgs,
...
}: let
secrets = config.services.secrets.secrets;
in {
imports = with tree; [
users.root
profiles.base
profiles.sshd
profiles.nix-gc
profiles.nginx
hosts.storage.profiles.wireguard
hosts.storage.profiles.rclone-serve
hosts.storage.profiles.rclone-sync
./hardware.nix
./networking.nix
./secrets.nix
];
systemd.tmpfiles.rules = [
"d /root/.config - root root"
"d /root/.config/rclone - root root"
"L /root/.config/rclone/rclone.conf - - - - ${secrets.rclone_config.path}"
"d /home/storage/.config - storage storage"
"d /home/storage/.config/rclone - storage storage"
"L /home/storage/.config/rclone/rclone.conf - - - - ${secrets.rclone_config.path}"
];
home-manager.users.root = {
imports = with tree; [home.base home.dev.small];
home.stateVersion = "22.05";
};
users.groups.storage = {};
users.users.storage = {
isNormalUser = true;
extraGroups = ["storage"];
};
systemd.services.init-secrets = {
wantedBy = ["multi-user.target"];
after = ["network.target"];
path = with pkgs; [bash vault getent];
script = let
vault_username = "storage";
vault_password_file = "${secrets.vault_password.path}";
in ''
VAULT_ADDR="https://vault.owo.monster" \
vault login -no-print -method=userpass username=${vault_username} password=$(cat ${vault_password_file})
/run/current-system/sw/bin/secrets-init
'';
};
systemd.services.storage-mount = {
wantedBy = ["multi-user.target"];
after = ["network.target" "secrets-init.service"];
partOf = ["secrets-init.service"];
path = with pkgs; [bash rclone mount umount];
script = ''
set -e
umount /storage -fl || true
sleep 2
rclone --config ${secrets.rclone_config.path} mount StorageBox: /storage --allow-non-empty
'';
};
environment.systemPackages = with pkgs; [
rclone
cifs-utils
apacheHttpd
restic
];
networking.hostName = "storage";
time.timeZone = "Europe/London";
system.stateVersion = "22.05";
}

View file

@ -1,4 +1,10 @@
{ fetchurl, fetchgit, linkFarm, runCommand, gnutar }: rec { {
fetchurl,
fetchgit,
linkFarm,
runCommand,
gnutar,
}: rec {
offline_cache = linkFarm "offline" packages; offline_cache = linkFarm "offline" packages;
packages = [ packages = [
{ {

View file

@ -21,5 +21,9 @@ with lib; {
useUserPackages = true; useUserPackages = true;
sharedModules = with tree; [modules.home.vscode-mod-module]; sharedModules = with tree; [modules.home.vscode-mod-module];
}; };
systemd.tmpfiles.rules = lib.mkIf config.boot.isContainer (lib.flatten (lib.forEach (builtins.attrNames config.home-manager.users) (user: [
"d /nix/var/nix/profiles/per-user/${user} - ${config.users.users."${user}".group} - - -"
"d /nix/var/nix/gcroots/per-user/${user} - ${config.users.users."${user}".group} - - -"
])));
}; };
} }

View file

@ -11,6 +11,5 @@ HOSTNAME=$(hostname)
[ "${NO_REBUILD}" == "" ] && ./scripts/rebuild.sh $@ [ "${NO_REBUILD}" == "" ] && ./scripts/rebuild.sh $@
[ "${HOSTNAME}" != "hetzner-vm" ] && deploy -s ".#hetzner-vm" -- $@ [ "${HOSTNAME}" != "hetzner-vm" ] && deploy -s ".#hetzner-vm" -- $@
[ "${HOSTNAME}" != "vault" ] && deploy -s ".#vault" -- $@ [ "${HOSTNAME}" != "vault" ] && deploy -s ".#vault" -- $@
[ "${HOSTNAME}" != "storage" ] && deploy -s ".#storage" -- $@
[ "${HOSTNAME}" != "buildbox" ] && deploy -s ".#buildbox" -- $@ [ "${HOSTNAME}" != "buildbox" ] && deploy -s ".#buildbox" -- $@

View file

@ -1,14 +1,22 @@
{}: { {}: {
folder = ./.; folder = ./.;
config = { config = {
# Data Files & Nix Generated Scripts
"data/*".functor.enable = true;
"extras/*".functor.enable = true; "extras/*".functor.enable = true;
"hosts/*/services".functor.enable = true; # Per host home-manager, profiles & containers
"hosts/hetzner-vm/modules/mailserver".functor.enable = true; "hosts/*".functor.enable = true;
"hosts/hetzner-vm/modules/piped".functor.enable = true;
"hosts/raspberry/services/music-friend".functor.enable = true;
"hosts/*/home".functor.enable = true; "hosts/*/home".functor.enable = true;
"hosts/*/profiles".functor.enable = true; "hosts/*/profiles".functor.enable = true;
"hosts/*/containers".functor.enable = true;
# Extra modules/home/profiles/containers
"hosts/hetzner-vm/modules/mailserver".functor.enable = true;
"hosts/hetzner-vm/modules/piped".functor.enable = true;
"hosts/hetzner-vm/containers/storage/profiles".functor.enable = true;
# Profiles
"profiles/*".functor.enable = true; "profiles/*".functor.enable = true;
"profiles/sound/*".functor.enable = true; "profiles/sound/*".functor.enable = true;
"profiles/sound/pulseaudio/*".functor.enable = true; "profiles/sound/pulseaudio/*".functor.enable = true;
@ -17,7 +25,10 @@
"profiles/gui/environments/*".functor.enable = true; "profiles/gui/environments/*".functor.enable = true;
"profiles/firewall-allow/*".functor.enable = true; "profiles/firewall-allow/*".functor.enable = true;
# Users
"users/*".functor.enable = true; "users/*".functor.enable = true;
# Home-Manager
"home/*".functor.enable = true; "home/*".functor.enable = true;
"home/gui/environments/*".functor.enable = true; "home/gui/environments/*".functor.enable = true;
"home/apps/*".functor.enable = true; "home/apps/*".functor.enable = true;
@ -26,6 +37,7 @@
"home/gaming/platforms/*".functor.enable = true; "home/gaming/platforms/*".functor.enable = true;
"home/programming/languages/*".functor.enable = true; "home/programming/languages/*".functor.enable = true;
# Presets
"presets/nixos/*".functor.enable = true; "presets/nixos/*".functor.enable = true;
"modules/nixos" = { "modules/nixos" = {