move storage to using secrets module
This commit is contained in:
parent
0a2aae3a43
commit
5a3628dac0
|
@ -1,49 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -ex -o pipefail
|
|
||||||
|
|
||||||
kv_get() {
|
|
||||||
vault kv get -format json ${1}
|
|
||||||
}
|
|
||||||
|
|
||||||
simple_get() {
|
|
||||||
kv_get ${1} | jq .data.data${2} -r
|
|
||||||
}
|
|
||||||
|
|
||||||
simple_get_obscure() {
|
|
||||||
rclone obscure $(simple_get $@)
|
|
||||||
}
|
|
||||||
|
|
||||||
simple_get_replace_b2() {
|
|
||||||
account=$(simple_get ${1} .keyID)
|
|
||||||
key=$(simple_get ${1} .applicationKey | sed "s#/#\\\/#")
|
|
||||||
sed -i "s/${2}_ACCOUNT/${account}/" ${3}
|
|
||||||
sed -i "s/${2}_KEY/${key}/" ${3}
|
|
||||||
}
|
|
||||||
|
|
||||||
VAULT_USERNAME=$1
|
|
||||||
VAULT_PASSWORD_FILE=$2
|
|
||||||
TEMPLATE_FILE=$3
|
|
||||||
OUTPUT_FILE=$4
|
|
||||||
|
|
||||||
vault login -no-print -method=userpass username=${VAULT_USERNAME} password=$(cat ${VAULT_PASSWORD_FILE})
|
|
||||||
|
|
||||||
TMP_DIR="$(mktemp -d)"
|
|
||||||
|
|
||||||
cp ${TEMPLATE_FILE} "${TMP_DIR}/template"
|
|
||||||
|
|
||||||
pushd "${TMP_DIR}"
|
|
||||||
STORAGEBOX_PASSWORD=$(simple_get_obscure /api-keys/hetzner/storagebox .password)
|
|
||||||
sed -i "s/STORAGEBOX_PASSWORD/${STORAGEBOX_PASSWORD}/" ./template
|
|
||||||
|
|
||||||
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Backups" "B2_CHAOS_BACKUPS" ./template
|
|
||||||
|
|
||||||
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Photos" "B2_CHAOS_PHOTOS" ./template
|
|
||||||
|
|
||||||
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Music" "B2_CHAOS_MUSIC" ./template
|
|
||||||
|
|
||||||
simple_get_replace_b2 "/api-keys/backblaze/Phoenix-Cryptidz-Storage" "B2_PHOENIX_CRYPTIDZ_STORAGE" ./template
|
|
||||||
popd
|
|
||||||
|
|
||||||
cat "${TMP_DIR}/template" > "${OUTPUT_FILE}"
|
|
||||||
rm -rf "${TMP_DIR}"
|
|
132
hosts/storage/profiles/rclone-serve.nix
Normal file
132
hosts/storage/profiles/rclone-serve.nix
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
{ config, ... }:
|
||||||
|
let
|
||||||
|
secrets = config.services.secrets.secrets;
|
||||||
|
ports = (import ../ports.nix { });
|
||||||
|
in {
|
||||||
|
services.rclone-serve = let
|
||||||
|
serviceConfig = {
|
||||||
|
after = [ "secrets-init.service" ];
|
||||||
|
partOf = [ "secrets-init.service" ];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
remotes = [
|
||||||
|
{
|
||||||
|
user = "storage";
|
||||||
|
remote = "StorageBox:";
|
||||||
|
type = "webdav";
|
||||||
|
extraArgs = [
|
||||||
|
"--addr=:${toString ports.rclone_serve_webdav_main}"
|
||||||
|
"--htpasswd=${secrets.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.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.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.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}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
44
hosts/storage/profiles/rclone-sync.nix
Normal file
44
hosts/storage/profiles/rclone-sync.nix
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
let secrets = config.services.secrets.secrets;
|
||||||
|
in {
|
||||||
|
services.rclone-sync = let
|
||||||
|
sync_defaults = {
|
||||||
|
serviceConfig = { after = [ "secrets-init.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";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
{ ... }:
|
{ config, ... }:
|
||||||
let secrets-db = (import ./secrets-db.nix { });
|
let secrets = config.services.secrets.secrets;
|
||||||
in {
|
in {
|
||||||
networking.wg-quick.interfaces = {
|
networking.wg-quick.interfaces = {
|
||||||
wg0 = {
|
wg0 = {
|
||||||
address = [ "10.69.42.4/32" ];
|
address = [ "10.69.42.4/32" ];
|
||||||
listenPort = 51820;
|
listenPort = 51820;
|
||||||
privateKeyFile = "${secrets-db.wg_priv.path}";
|
privateKeyFile = "${secrets.wg_privkey.path}";
|
||||||
|
|
||||||
peers = [
|
peers = [
|
||||||
# hetzner-vm
|
# hetzner-vm
|
||||||
{
|
{
|
||||||
publicKey = "UJr+EmUM7KWkIy0nk0JA38ibvcLC++6iuOKkHdrx9Dc=";
|
publicKey = "UJr+EmUM7KWkIy0nk0JA38ibvcLC++6iuOKkHdrx9Dc=";
|
||||||
presharedKeyFile = "${secrets-db.wg_preshared_hetzner-vm.path}";
|
presharedKeyFile = "${secrets.wg_preshared_hetzner-vm.path}";
|
||||||
allowedIPs = [ "10.69.42.1/32" ];
|
allowedIPs = [ "10.69.42.1/32" ];
|
||||||
endpoint = "hetzner-vm.servers.genderfucked.monster:51820";
|
endpoint = "hetzner-vm.servers.genderfucked.monster:51820";
|
||||||
persistentKeepalive = 25;
|
persistentKeepalive = 25;
|
||||||
|
@ -19,20 +19,20 @@ in {
|
||||||
# tablet
|
# tablet
|
||||||
{
|
{
|
||||||
publicKey = "jXA0DeprEaL/ARQ3K81l8xWuUI5C/90DcY3bIfcIjz8=";
|
publicKey = "jXA0DeprEaL/ARQ3K81l8xWuUI5C/90DcY3bIfcIjz8=";
|
||||||
presharedKeyFile = "${secrets-db.wg_preshared_tablet.path}";
|
presharedKeyFile = "${secrets.wg_preshared_tablet.path}";
|
||||||
allowedIPs = [ "10.69.42.2/32" ];
|
allowedIPs = [ "10.69.42.2/32" ];
|
||||||
}
|
}
|
||||||
# vault
|
# vault
|
||||||
{
|
{
|
||||||
publicKey = "IGq+WanFM/bKNUkwjO/0AAtDhJLvtvU+mVxH27QyHTc=";
|
publicKey = "IGq+WanFM/bKNUkwjO/0AAtDhJLvtvU+mVxH27QyHTc=";
|
||||||
presharedKeyFile = "${secrets-db.wg_preshared_vault.path}";
|
presharedKeyFile = "${secrets.wg_preshared_vault.path}";
|
||||||
endpoint = "vault.servers.genderfucked.monster:51820";
|
endpoint = "vault.servers.genderfucked.monster:51820";
|
||||||
allowedIPs = [ "10.69.42.3/32" ];
|
allowedIPs = [ "10.69.42.3/32" ];
|
||||||
}
|
}
|
||||||
# iphone8
|
# iphone8
|
||||||
{
|
{
|
||||||
publicKey = "2BgT08bDKh8WlFFSeRArI9a1GpFgUyqEApvJy4KgAmw=";
|
publicKey = "2BgT08bDKh8WlFFSeRArI9a1GpFgUyqEApvJy4KgAmw=";
|
||||||
presharedKeyFile = "${secrets-db.wg_preshared_iphone8.path}";
|
presharedKeyFile = "${secrets.wg_preshared_iphone8.path}";
|
||||||
allowedIPs = [ "10.69.42.5/32" ];
|
allowedIPs = [ "10.69.42.5/32" ];
|
||||||
}
|
}
|
||||||
];
|
];
|
|
@ -1,62 +0,0 @@
|
||||||
{ }: {
|
|
||||||
restic_hetznervm_htpasswd = {
|
|
||||||
user = "storage";
|
|
||||||
group = "storage";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/restic_hetznervm_htpasswd";
|
|
||||||
};
|
|
||||||
restic_music_htpasswd = {
|
|
||||||
user = "storage";
|
|
||||||
group = "storage";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/restic_music_htpasswd";
|
|
||||||
};
|
|
||||||
restic_vault_htpasswd = {
|
|
||||||
user = "storage";
|
|
||||||
group = "storage";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/restic_vault_htpasswd";
|
|
||||||
};
|
|
||||||
webdav_main_htpasswd = {
|
|
||||||
user = "storage";
|
|
||||||
group = "storage";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/webdav_main_htpasswd";
|
|
||||||
};
|
|
||||||
vault_password = {
|
|
||||||
user = "root";
|
|
||||||
group = "root";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/vault_password";
|
|
||||||
};
|
|
||||||
wg_priv = {
|
|
||||||
user = "root";
|
|
||||||
group = "root";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/wg_priv";
|
|
||||||
};
|
|
||||||
wg_preshared_hetzner-vm = {
|
|
||||||
user = "root";
|
|
||||||
group = "root";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/wg_preshared_hetzner-vm";
|
|
||||||
};
|
|
||||||
wg_preshared_tablet = {
|
|
||||||
user = "root";
|
|
||||||
group = "root";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/wg_preshared_tablet";
|
|
||||||
};
|
|
||||||
wg_preshared_vault = {
|
|
||||||
user = "root";
|
|
||||||
group = "root";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/wg_preshared_vault";
|
|
||||||
};
|
|
||||||
wg_preshared_iphone8 = {
|
|
||||||
user = "root";
|
|
||||||
group = "root";
|
|
||||||
permissions = "660";
|
|
||||||
path = "/secrets/wg_preshared_iphone8";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,93 +1,127 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }: {
|
||||||
let secrets-db = (import ./secrets-db.nix { });
|
|
||||||
in {
|
|
||||||
systemd.tmpfiles.rules = [ "d /secrets - root root" ];
|
|
||||||
environment.systemPackages = [
|
|
||||||
(pkgs.writeShellScriptBin "init-secrets" ''
|
|
||||||
set -e -o pipefail
|
|
||||||
|
|
||||||
VAULT_ADDR_DEFAULT="https://vault.owo.monster"
|
services.secrets = {
|
||||||
[ -n "$VAULT_ADDR" ] && export VAULT_ADDR="$VAULT_ADDR_DEFAULT"
|
enable = true;
|
||||||
|
|
||||||
export PATH=$PATH:${pkgs.vault}/bin
|
extraPackages = with pkgs; [
|
||||||
export PATH=$PATH:${pkgs.jq}/bin
|
# for music & mail passwd files
|
||||||
export PATH=$PATH:${pkgs.apacheHttpd}/bin
|
apacheHttpd
|
||||||
|
# for rclone obscure config file
|
||||||
|
rclone
|
||||||
|
];
|
||||||
|
|
||||||
kv_get() {
|
extraFunctions = ''
|
||||||
vault kv get -format json $1
|
simple_get_obscure() {
|
||||||
|
rclone obscure "$(simple_get "$@")"
|
||||||
}
|
}
|
||||||
|
|
||||||
simple_get() {
|
simple_get_replace_b2() {
|
||||||
kv_get $1 | jq .data.data$2 -r
|
api_account=$(simple_get "$1" .keyID)
|
||||||
}
|
api_key=$(simple_get "$1" .applicationKey | sed "s#/#\\\/#")
|
||||||
|
|
||||||
file=${secrets-db.restic_hetznervm_htpasswd.path}
|
replace_account=''${2}_ACCOUNT
|
||||||
echo $file
|
replace_key=''${2}_KEY
|
||||||
|
|
||||||
|
sed -i "s/$replace_account/$api_account/" "$3"
|
||||||
|
sed -i "s/$replace_key/$api_key/" "$3"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
secrets = {
|
||||||
|
vault_password = { manual = true; };
|
||||||
|
|
||||||
|
restic_hetznervm_htpasswd = {
|
||||||
|
user = "storage";
|
||||||
|
group = "storage";
|
||||||
|
fetchScript = ''
|
||||||
username=$(simple_get "/api-keys/storage/restic/HetznerVM" .username)
|
username=$(simple_get "/api-keys/storage/restic/HetznerVM" .username)
|
||||||
password=$(simple_get "/api-keys/storage/restic/HetznerVM" .password)
|
password=$(simple_get "/api-keys/storage/restic/HetznerVM" .password)
|
||||||
htpasswd -bc $file "$username" "$password"
|
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||||
chown ${secrets-db.restic_hetznervm_htpasswd.user}:${secrets-db.restic_hetznervm_htpasswd.group} $file
|
'';
|
||||||
chmod ${secrets-db.restic_hetznervm_htpasswd.permissions} $file
|
};
|
||||||
|
restic_music_htpasswd = {
|
||||||
file=${secrets-db.restic_music_htpasswd.path}
|
user = "storage";
|
||||||
echo $file
|
group = "storage";
|
||||||
|
fetchScript = ''
|
||||||
username=$(simple_get "/api-keys/storage/restic/Music" .username)
|
username=$(simple_get "/api-keys/storage/restic/Music" .username)
|
||||||
password=$(simple_get "/api-keys/storage/restic/Music" .password)
|
password=$(simple_get "/api-keys/storage/restic/Music" .password)
|
||||||
htpasswd -bc $file "$username" "$password"
|
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||||
chown ${secrets-db.restic_music_htpasswd.user}:${secrets-db.restic_music_htpasswd.group} $file
|
'';
|
||||||
chmod ${secrets-db.restic_music_htpasswd.permissions} $file
|
};
|
||||||
|
restic_vault_htpasswd = {
|
||||||
file=${secrets-db.restic_vault_htpasswd.path}
|
user = "storage";
|
||||||
echo $file
|
group = "storage";
|
||||||
|
fetchScript = ''
|
||||||
username=$(simple_get "/api-keys/storage/restic/Vault" .username)
|
username=$(simple_get "/api-keys/storage/restic/Vault" .username)
|
||||||
password=$(simple_get "/api-keys/storage/restic/Vault" .password)
|
password=$(simple_get "/api-keys/storage/restic/Vault" .password)
|
||||||
htpasswd -bc $file "$username" "$password"
|
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||||
chown ${secrets-db.restic_vault_htpasswd.user}:${secrets-db.restic_vault_htpasswd.group} $file
|
'';
|
||||||
chmod ${secrets-db.restic_vault_htpasswd.permissions} $file
|
};
|
||||||
|
webdav_main_htpasswd = {
|
||||||
file=${secrets-db.webdav_main_htpasswd.path}
|
user = "storage";
|
||||||
echo $file
|
group = "storage";
|
||||||
|
fetchScript = ''
|
||||||
username=$(simple_get "/api-keys/storage/webdav/main" .username)
|
username=$(simple_get "/api-keys/storage/webdav/main" .username)
|
||||||
password=$(simple_get "/api-keys/storage/webdav/main" .password)
|
password=$(simple_get "/api-keys/storage/webdav/main" .password)
|
||||||
htpasswd -bc $file "$username" "$password"
|
htpasswd -bc "$secretFile" "$username" "$password" 2>&1
|
||||||
chown ${secrets-db.webdav_main_htpasswd.user}:${secrets-db.webdav_main_htpasswd.group} $file
|
'';
|
||||||
chmod ${secrets-db.webdav_main_htpasswd.permissions} $file
|
};
|
||||||
|
|
||||||
file=${secrets-db.vault_password.path}
|
rclone_config = {
|
||||||
echo $file
|
user = "storage";
|
||||||
simple_get "/vault-users/storage" .password > $file
|
group = "storage";
|
||||||
chown ${secrets-db.vault_password.user}:${secrets-db.vault_password.group} $file
|
fetchScript = ''
|
||||||
chmod ${secrets-db.vault_password.permissions} $file
|
TMP_DIR="$(mktemp -d)"
|
||||||
|
|
||||||
file=${secrets-db.wg_priv.path}
|
cp ${./rclone_config.template} "$TMP_DIR/template"
|
||||||
echo $file
|
|
||||||
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .private > $file
|
|
||||||
chown ${secrets-db.wg_priv.user}:${secrets-db.wg_priv.group} $file
|
|
||||||
chmod ${secrets-db.wg_priv.permissions} $file
|
|
||||||
|
|
||||||
file=${secrets-db.wg_preshared_hetzner-vm.path}
|
pushd "$TMP_DIR"
|
||||||
echo $file
|
|
||||||
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .preshared_keys.hetzner_vm > $file
|
|
||||||
chown ${secrets-db.wg_preshared_hetzner-vm.user}:${secrets-db.wg_preshared_hetzner-vm.group} $file
|
|
||||||
chmod ${secrets-db.wg_preshared_hetzner-vm.permissions} $file
|
|
||||||
|
|
||||||
file=${secrets-db.wg_preshared_tablet.path}
|
STORAGEBOX_PASSWORD=$(simple_get_obscure /api-keys/hetzner/storagebox .password)
|
||||||
echo $file
|
sed -i "s/STORAGEBOX_PASSWORD/$STORAGEBOX_PASSWORD/" ./template
|
||||||
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .preshared_keys.tablet > $file
|
|
||||||
chown ${secrets-db.wg_preshared_tablet.user}:${secrets-db.wg_preshared_tablet.group} $file
|
|
||||||
chmod ${secrets-db.wg_preshared_tablet.permissions} $file
|
|
||||||
|
|
||||||
file=${secrets-db.wg_preshared_vault.path}
|
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Backups" "B2_CHAOS_BACKUPS" ./template
|
||||||
echo $file
|
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Photos" "B2_CHAOS_PHOTOS" ./template
|
||||||
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .preshared_keys.vault > $file
|
simple_get_replace_b2 "/api-keys/backblaze/Chaos-Music" "B2_CHAOS_MUSIC" ./template
|
||||||
chown ${secrets-db.wg_preshared_vault.user}:${secrets-db.wg_preshared_vault.group} $file
|
simple_get_replace_b2 "/api-keys/backblaze/Phoenix-Cryptidz-Storage" "B2_PHOENIX_CRYPTIDZ_STORAGE" ./template
|
||||||
chmod ${secrets-db.wg_preshared_vault.permissions} $file
|
|
||||||
|
|
||||||
file=${secrets-db.wg_preshared_iphone8.path}
|
cp ./template $secretFile
|
||||||
echo $file
|
|
||||||
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .preshared_keys.iphone8 > $file
|
popd
|
||||||
chown ${secrets-db.wg_preshared_iphone8.user}:${secrets-db.wg_preshared_iphone8.group} $file
|
|
||||||
chmod ${secrets-db.wg_preshared_iphone8.permissions} $file
|
rm -rf "$TMP_DIR"
|
||||||
'')
|
'';
|
||||||
];
|
};
|
||||||
|
|
||||||
|
wg_privkey = {
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .private > $secretFile
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
wg_preshared_hetzner-vm = {
|
||||||
|
path = "/secrets/wg_preshared_hetzner-vm";
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .preshared_keys.hetzner_vm > $secretFile
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
wg_preshared_tablet = {
|
||||||
|
path = "/secrets/wg_preshared_tablet";
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .preshared_keys.tablet > $secretFile
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
wg_preshared_vault = {
|
||||||
|
path = "/secrets/wg_preshared_vault";
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .preshared_keys.vault > $secretFile
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
wg_preshared_iphone8 = {
|
||||||
|
path = "/secrets/wg_preshared_iphone8";
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/wireguard/chaos-internal/storage" .preshared_keys.iphone8 > $secretFile
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{ modulesPath, tree, config, pkgs, lib, ... }:
|
{ modulesPath, tree, config, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
secrets-db = (import ./secrets-db.nix { });
|
secrets = config.services.secrets.secrets;
|
||||||
ports = (import ./ports.nix { });
|
ports = (import ./ports.nix { });
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
@ -12,14 +12,16 @@ in {
|
||||||
profiles.nix-gc
|
profiles.nix-gc
|
||||||
profiles.nginx
|
profiles.nginx
|
||||||
|
|
||||||
|
hosts.storage.profiles.wireguard
|
||||||
|
hosts.storage.profiles.rclone-serve
|
||||||
|
hosts.storage.profiles.rclone-sync
|
||||||
|
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
./networking.nix
|
./networking.nix
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
./wireguard.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /storage - root root"
|
|
||||||
"d /caches - storage storage"
|
"d /caches - storage storage"
|
||||||
"d /caches/main_webdav_serve - storage storage"
|
"d /caches/main_webdav_serve - storage storage"
|
||||||
];
|
];
|
||||||
|
@ -30,33 +32,31 @@ in {
|
||||||
extraGroups = [ "storage" ];
|
extraGroups = [ "storage" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.populate-rclone-config = {
|
systemd.services.init-secrets = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
path = with pkgs; [ bash rclone vault getent jq ];
|
path = with pkgs; [ bash vault getent ];
|
||||||
script = let
|
script = let
|
||||||
vault_username = "storage";
|
vault_username = "storage";
|
||||||
vault_password_file = "${secrets-db.vault_password.path}";
|
vault_password_file = "${secrets.vault_password.path}";
|
||||||
|
|
||||||
config_dir = "/home/storage/.config/rclone";
|
config_dir = "/home/storage/.config/rclone";
|
||||||
config_file = "/home/storage/.config/rclone/rclone.conf";
|
config_file = "/home/storage/.config/rclone/rclone.conf";
|
||||||
in ''
|
in ''
|
||||||
mkdir -p ${config_dir}
|
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
|
||||||
|
|
||||||
VAULT_ADDR="https://vault.owo.monster" bash ${
|
mkdir -p ${config_dir}
|
||||||
./populate-rclone-config.sh
|
rm ${config_file} || true
|
||||||
} ${vault_username} ${vault_password_file} ${
|
ln -s ${secrets.rclone_config.path} ${config_file}
|
||||||
./rclone_config.template
|
|
||||||
} ${config_file}
|
|
||||||
chown storage:storage ${config_file}
|
|
||||||
chmod 660 ${config_file}
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.storage-mount = {
|
systemd.services.storage-mount = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" "populate-rclone-config.service" ];
|
after = [ "network.target" "secrets-init.service" ];
|
||||||
partOf = [ "populate-rclone-config.service" ];
|
partOf = [ "secrets-init.service" ];
|
||||||
|
|
||||||
path = with pkgs; [ bash rclone mount umount ];
|
path = with pkgs; [ bash rclone mount umount ];
|
||||||
script = ''
|
script = ''
|
||||||
|
@ -67,174 +67,6 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
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; [
|
environment.systemPackages = with pkgs; [
|
||||||
rclone
|
rclone
|
||||||
cifs-utils
|
cifs-utils
|
||||||
|
|
|
@ -115,7 +115,9 @@ in {
|
||||||
${scriptBase}
|
${scriptBase}
|
||||||
|
|
||||||
VAULT_ADDR_DEFAULT="${cfg.vaultURL}"
|
VAULT_ADDR_DEFAULT="${cfg.vaultURL}"
|
||||||
[ -n "$VAULT_ADDR" ] && export VAULT_ADDR="$VAULT_ADDR_DEFAULT"
|
set +u
|
||||||
|
[ -z "$VAULT_ADDR" ] && export VAULT_ADDR="$VAULT_ADDR_DEFAULT"
|
||||||
|
set -u
|
||||||
|
|
||||||
kv_get() {
|
kv_get() {
|
||||||
vault kv get -format json "$1"
|
vault kv get -format json "$1"
|
||||||
|
|
Loading…
Reference in a new issue