This commit is contained in:
Chaos 2022-11-02 11:32:03 +00:00
parent 974c444b7a
commit 5b4d27b07c
No known key found for this signature in database
16 changed files with 235 additions and 141 deletions

View file

@ -0,0 +1,13 @@
{ 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

@ -3,15 +3,14 @@
{
imports = with tree; [
users.root
users.chaos
profiles.base
profiles.tailscale
profiles.sshd
profiles.nginx
profiles.nix-gc
hosts.hetzner-vm.services.restic
hosts.hetzner-vm.services.nginx
hosts.hetzner-vm.services.invidious
hosts.hetzner-vm.services.quassel
hosts.hetzner-vm.services.mpd
@ -21,7 +20,8 @@
hosts.hetzner-vm.services.lappy-dev
hosts.hetzner-vm.services.misskey
(modulesPath + "/profiles/qemu-guest.nix")
./networking.nix
./hardware.nix
];
networking.firewall.allowedTCPPorts = [ 80 443 ];
@ -30,47 +30,10 @@
imports = with tree; [ home.base home.dev.small ];
home.stateVersion = "22.05";
};
home-manager.users.chaos = {
imports = with tree; [ home.base home.dev.small ];
home.stateVersion = "22.05";
};
nix.settings.auto-optimise-store = true;
nix.gc = {
automatic = true;
dates = "daily";
options = "--delete-older-than 1d";
};
networking.hostName = "hetzner-vm";
time.timeZone = "Europe/London";
systemd.services.systemd-networkd-wait-online.enable = 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:8beb::1/64" ];
gateway = [ "fe80::1" ];
};
};
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.initrd.kernelModules = [ "nvme" ];
fileSystems."/" = {
device = "/dev/sda1";
fsType = "ext4";
};
system.stateVersion = "21.11";
}

View file

@ -0,0 +1,19 @@
{ ... }: {
systemd.services.systemd-networkd-wait-online.enable = 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:8beb::1/64" ];
gateway = [ "fe80::1" ];
};
};
}

View file

@ -19,7 +19,7 @@
metadata_to_use "title,artist"
auto_update "yes"
audio_buffer_size "4096"
#replaygain "track"
replaygain "track"
audio_output_format "44100:16:2"
audio_output {
type "httpd"
@ -39,8 +39,6 @@
encoder "flac"
port "8013"
format "44100:16:2"
#oggflac "yes"
#oggchaining "yes"
always_on "yes"
tags "yes"
}

View file

@ -3,87 +3,59 @@ let
mail_config = (import ./mailserver/config.nix { });
backupUser = "root";
backupPaths = [
"/secrets"
"/var/lib/vault"
"/var/lib/acme"
# Quassel & Invidious
"/var/backup/postgresql"
"/home/quassel/.config/quassel-irc.org"
# MPD State
"/mpd"
# doesn't work for restoring might as well not backup
# "/var/lib/tailscale"
# mail
mail_config.vmail_config.directory
mail_config.sieve_directory
mail_config.dkim_directory
"/var/lib/redis-rspamd"
# misskey
"/home/misskey/misskey-files"
"/var/lib/redis-misskey"
];
backupPrepareCommand = "${
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
systemctl start postgresqlBackup --wait
'')
}/bin/backupPrepareCommand";
timerConfig = {
OnBootSec = "1m";
OnCalendar = "daily";
};
repos = {
Chaos-Backups-HetznerVM = {
# 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/HetznerVM";
passwordFile = "/secrets/restic-Chaos-Backups-HetznerVM-password";
environmentFile = "/secrets/restic-Chaos-Backups-HetznerVM-env";
};
Cassie-Backups-HetznerVM = {
repository = "b2:Cryptidz-Backup:HetznerVM";
passwordFile = "/secrets/restic-Cassie-Backups-HetznerVM-password";
environmentFile = "/secrets/restic-Cassie-Backups-HetznerVM-env";
};
};
restic_commands = lib.mapAttrsToList (repoName: repoInfo:
(
# nya
pkgs.writeShellScriptBin "restic-${repoName}" ''
env \
RESTIC_PASSWORD_FILE=${repoInfo.passwordFile} \
RESTIC_REPOSITORY=${repoInfo.repository} \
$(cat ${repoInfo.environmentFile}) \
${pkgs.restic}/bin/restic $@
'')) repos;
in {
environment.systemPackages = restic_commands;
environment.systemPackages = [
(pkgs.writeShellScriptBin "restic-hetzner-vm" ''
env \
RESTIC_PASSWORD_FILE=/secrets/restic-Chaos-Backups-HetznerVM-password \
$(cat /secrets/restic-Chaos-Backups-HetznerVM-env) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.hetzner-vm = lib.mkMerge [
{
user = backupUser;
paths = backupPaths;
inherit timerConfig;
inherit backupPrepareCommand;
}
repos.Chaos-Backups-HetznerVM
];
services.restic.backups.cassie-hetzner-vm = lib.mkMerge [
{
user = backupUser;
paths = backupPaths;
inherit timerConfig;
inherit backupPrepareCommand;
}
repos.Cassie-Backups-HetznerVM
];
services.restic.backups.hetzner-vm = {
user = "root";
paths = [
"/secrets"
"/var/lib/acme"
# Quassel & Invidious
"/var/backup/postgresql"
"/home/quassel/.config/quassel-irc.org"
# MPD State
"/mpd"
# doesn't work for restoring might as well not backup
# "/var/lib/tailscale"
# mail
mail_config.vmail_config.directory
mail_config.sieve_directory
mail_config.dkim_directory
"/var/lib/redis-rspamd"
# misskey
"/home/misskey/misskey-files"
"/var/lib/redis-misskey"
];
# 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/HetznerVM";
passwordFile = "/secrets/restic-Chaos-Backups-HetznerVM-password";
environmentFile = "/secrets/restic-Chaos-Backups-HetznerVM-env";
timerConfig = {
OnBootSec = "1m";
OnCalendar = "daily";
};
inherit backupPrepareCommand;
};
services.postgresqlBackup = {
enable = true;

View file

@ -1,7 +1,6 @@
{ modulesPath, ... }: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.loader.grub.enable = true;

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash
set -ex
set -ex -o pipefail
kv_get() {
vault kv get -format json ${1}
@ -39,6 +39,10 @@ B2_CHAOS_PHOTOS_KEY=$(simple_get /api-keys/backblaze/Chaos-Photos .applicationKe
sed -i "s/B2_CHAOS_PHOTOS_ACCOUNT/${B2_CHAOS_PHOTOS_ACCOUNT}/" ./template
sed -i "s/B2_CHAOS_PHOTOS_KEY/${B2_CHAOS_PHOTOS_KEY}/" ./template
B2_CASSIE_CRYPTIDZ_BACKUP_ACCOUNT=$(simple_get /api-keys/backblaze/Cryptidz-Backup .keyID)
B2_CASSIE_CRYPTIDZ_BACKUP_KEY=$(simple_get /api-keys/backblaze/Cryptidz-Backup .applicationKey | sed "s#/#\\\/#")
sed -i "s/B2_CASSIE_CRYPTIDZ_BACKUP_ACCOUNT/${B2_CASSIE_CRYPTIDZ_BACKUP_ACCOUNT}/" ./template
sed -i "s/B2_CASSIE_CRYPTIDZ_BACKUP_KEY/${B2_CASSIE_CRYPTIDZ_BACKUP_KEY}/" ./template
popd
cat "${TMP_DIR}/template" > "${OUTPUT_FILE}"

View file

@ -26,4 +26,14 @@ hard_delete = true
[B2-Chaos-Photos]
type = alias
remote = B2-Chaos-Photos-Source:Chaos-Photos
remote = B2-Chaos-Photos-Source:Chaos-Photos
[B2-Cassie-Cryptidz-Backup-Source]
type = b2
account = B2_CASSIE_CRYPTIDZ_BACKUP_ACCOUNT
key = B2_CASSIE_CRYPTIDZ_BACKUP_KEY
hard_delete = true
[B2-Cassie-Cryptidz-Backup]
type = alias
remote = B2-Cassie-Cryptidz-Backup-Source:Cryptidz-Backup

View file

@ -0,0 +1,32 @@
{ }: {
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_htpasswd = {
user = "storage";
group = "storage";
permissions = "660";
path = "/secrets/webdav_htpasswd";
};
vault_password = {
user = "root";
group = "root";
permissions = "660";
path = "/secrets/vault_password";
};
}

63
hosts/storage/secrets.nix Normal file
View file

@ -0,0 +1,63 @@
{ 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"
[ -n "$VAULT_ADDR" ] && export VAULT_ADDR="$VAULT_ADDR_DEFAULT"
export PATH=$PATH:${pkgs.vault}/bin
export PATH=$PATH:${pkgs.jq}/bin
export PATH=$PATH:${pkgs.apacheHttpd}/bin
kv_get() {
vault kv get -format json $1
}
simple_get() {
kv_get $1 | jq .data.data$2 -r
}
file=${secrets-db.restic_hetznervm_htpasswd.path}
echo $file
username=$(simple_get "/api-keys/storage/restic/HetznerVM" .username)
password=$(simple_get "/api-keys/storage/restic/HetznerVM" .password)
htpasswd -bc $file "$username" "$password"
chown ${secrets-db.restic_hetznervm_htpasswd.user}:${secrets-db.restic_hetznervm_htpasswd.group} $file
chmod ${secrets-db.restic_hetznervm_htpasswd.permissions} $file
file=${secrets-db.restic_music_htpasswd.path}
echo $file
username=$(simple_get "/api-keys/storage/restic/Music" .username)
password=$(simple_get "/api-keys/storage/restic/Music" .password)
htpasswd -bc $file "$username" "$password"
chown ${secrets-db.restic_music_htpasswd.user}:${secrets-db.restic_music_htpasswd.group} $file
chmod ${secrets-db.restic_music_htpasswd.permissions} $file
file=${secrets-db.restic_vault_htpasswd.path}
echo $file
username=$(simple_get "/api-keys/storage/restic/Vault" .username)
password=$(simple_get "/api-keys/storage/restic/Vault" .password)
htpasswd -bc $file "$username" "$password"
chown ${secrets-db.restic_vault_htpasswd.user}:${secrets-db.restic_vault_htpasswd.group} $file
chmod ${secrets-db.restic_vault_htpasswd.permissions} $file
file=${secrets-db.webdav_htpasswd.path}
echo $file
username=$(simple_get "/api-keys/storage/webdav" .username)
password=$(simple_get "/api-keys/storage/webdav" .password)
htpasswd -bc $file "$username" "$password"
chown ${secrets-db.webdav_htpasswd.user}:${secrets-db.webdav_htpasswd.group} $file
chmod ${secrets-db.webdav_htpasswd.permissions} $file
file=${secrets-db.vault_password.path}
echo $file
simple_get "/vault-users/storage" .password > $file
chown ${secrets-db.vault_password.user}:${secrets-db.vault_password.group} $file
chmod ${secrets-db.vault_password.permissions} $file
'')
];
}

View file

@ -1,6 +1,6 @@
{ modulesPath, tree, config, pkgs, lib, ... }:
{
let secrets-db = (import ./secrets-db.nix { });
in {
imports = with tree; [
users.root
@ -11,15 +11,14 @@
./hardware.nix
./networking.nix
./secrets.nix
];
systemd.tmpfiles.rules = [
"d /secrets - root root"
#
"d /storage - root root"
];
users.groups.storage = { };
users.users.storage = {
isNormalUser = true;
@ -32,17 +31,20 @@
path = with pkgs; [ bash rclone vault getent jq ];
script = let
vault_username = "storage";
vault_password_file = "/secrets/vault_password";
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 /home/storage/.config/rclone
mkdir -p ${config_dir}
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
} ${config_file}
chown storage:storage ${config_file}
chmod 660 ${config_file}
'';
};
@ -68,7 +70,8 @@
remote = "StorageBox:";
type = "webdav";
wants = [ "populate-rclone-config.service" ];
extraArgs = [ "--addr=:4242" "--htpasswd=/secrets/webdav_htpasswd" ];
extraArgs =
[ "--addr=:4242" "--htpasswd=${secrets-db.webdav_htpasswd.path}" ];
}
{
user = "storage";
@ -77,7 +80,7 @@
wants = [ "populate-rclone-config.service" ];
extraArgs = [
"--addr=:4243"
"--htpasswd=/secrets/restic_hetznervm_htpasswd"
"--htpasswd=${secrets-db.restic_hetznervm_htpasswd.path}"
"--baseurl=/HetznerVM/"
];
}
@ -88,7 +91,7 @@
wants = [ "populate-rclone-config.service" ];
extraArgs = [
"--addr=:4244"
"--htpasswd=/secrets/restic_music_htpasswd"
"--htpasswd=${secrets-db.restic_music_htpasswd.path}"
"--baseurl=/Music/"
];
}
@ -99,7 +102,7 @@
wants = [ "populate-rclone-config.service" ];
extraArgs = [
"--addr=:4245"
"--htpasswd=/secrets/restic_vault_htpasswd"
"--htpasswd=${secrets-db.restic_vault_htpasswd.path}"
"--baseurl=/Vault/"
];
}
@ -146,6 +149,25 @@
OnCalendar = "4h";
};
}
{
source = "StorageBox:Chaos-Backups";
dest = "B2-Cassie-Cryptidz-Backup:Chaos-Backups";
wants = [ "populate-rclone-config.service" ];
timerConfig = {
OnStartupSec = "60";
OnCalendar = "4h";
};
}
{
source = "StorageBox:Chaos-Photos";
dest = "B2-Cassie-Cryptidz-Backup:Chaos-Photos";
wants = [ "populate-rclone-config.service" ];
timerConfig = {
OnStartupSec = "60";
OnCalendar = "4h";
};
}
];
};

View file

@ -1,7 +1,6 @@
{ modulesPath, ... }: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.loader.grub.enable = true;

View file

@ -1,10 +1,12 @@
{ pkgs, ... }:
let secrets-db = (import ./secrets-db.nix { });
in {
systemd.tmpfiles.rules = [ "d /secrets - root root" ];
environment.systemPackages = [
(pkgs.writeShellScriptBin "init-secrets" ''
VAULT_ADDR_DEFAULT="https://vault.owo.monster"
set -e -o pipefail
VAULT_ADDR_DEFAULT="https://vault.owo.monster"
[ -n "$VAULT_ADDR" ] && export VAULT_ADDR="$VAULT_ADDR_DEFAULT"
export PATH=$PATH:${pkgs.vault}/bin

View file

@ -14,8 +14,6 @@ in {
./secrets.nix
];
systemd.tmpfiles.rules = [ "d /secrets - root root" ];
services.vault = {
enable = true;
package = pkgs.vault-bin;

View file

@ -1,4 +1,4 @@
{...}: {
{ ... }: {
security.acme = {
defaults = { email = "chaoticryptidz@owo.monster"; };
acceptTerms = true;
@ -13,4 +13,4 @@
clientMaxBodySize = "512m";
serverNamesHashBucketSize = 1024;
};
}
}

View file

@ -5,4 +5,4 @@
dates = "daily";
options = "--delete-older-than 1d";
};
}
}