migrate hetzner-vm to hetzner-arm; piped currently dead
This commit is contained in:
parent
4206a3f07e
commit
90f450d7d9
|
@ -7,30 +7,24 @@ in rec {
|
|||
hosts = {
|
||||
# map of hostname to config for cluster node
|
||||
"piped-fi" = rec {
|
||||
ip = "${internalWireGuard.hosts.hetzner-vm.ip}";
|
||||
ip = "${internalWireGuard.hosts.hetzner-arm.ip}";
|
||||
|
||||
# ssh -L 3014:127.0.0.1:3014 -L 26257:127.0.0.1:26257 hetzner-vm
|
||||
# ssh -L 3014:127.0.0.1:3014 -L 26257:127.0.0.1:26257 hetzner-arm
|
||||
joinString = "${ip}:${toString ports.cockroachDB}";
|
||||
advertiseAddr = joinString;
|
||||
|
||||
resticName = "piped-finland";
|
||||
resticBucket = "Piped-Finland";
|
||||
|
||||
vaultUserName = "hetzner-vm-container-piped-fi";
|
||||
|
||||
baseDomain = "piped-fi.owo.monster";
|
||||
};
|
||||
|
||||
"piped-uk" = rec {
|
||||
ip = "${internalWireGuard.hosts.raspberry.ip}";
|
||||
|
||||
# ssh -L 3014:127.0.0.1:3014 -L 26257:127.0.0.1:26257 raspberry
|
||||
joinString = "${ip}:${toString ports.cockroachDB}";
|
||||
advertiseAddr = joinString;
|
||||
|
||||
resticName = "piped-uk";
|
||||
resticBucket = "Piped-UK";
|
||||
|
||||
vaultUserName = "rapsberry-container-piped-uk";
|
||||
|
||||
baseDomain = "piped-uk.owo.monster";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
rec {
|
||||
"hetzner-vm" = {
|
||||
ipv4 = "65.21.182.73";
|
||||
ipv6 = "2a01:4f9:c010:8beb::1";
|
||||
};
|
||||
"hetzner-arm" = {
|
||||
ipv4 = "65.21.145.62";
|
||||
ipv6 = "2a01:4f9:c012:9dbf::1";
|
||||
|
|
|
@ -2,10 +2,10 @@ let
|
|||
pubkeys = builtins.fromJSON (builtins.readFile ./chaosInternalWireGuardPubKeys.json);
|
||||
in rec {
|
||||
hosts = {
|
||||
"hetzner-vm" = {
|
||||
"hetzner-arm" = {
|
||||
ip = "10.69.42.1";
|
||||
public = pubkeys."hetzner-vm";
|
||||
endpoint = "hetzner-vm.servers.genderfucked.monster:51820";
|
||||
public = pubkeys."hetzner-arm";
|
||||
endpoint = "hetzner-arm.servers.genderfucked.monster:51820";
|
||||
};
|
||||
"vault" = {
|
||||
ip = "10.69.42.2";
|
||||
|
@ -25,11 +25,5 @@ in rec {
|
|||
public = pubkeys."raspberry";
|
||||
endpoint = "raspberry.servers.genderfucked.monster:51820";
|
||||
};
|
||||
# TODO: make this .1 again after migration like hetzner-vm
|
||||
"hetzner-arm" = {
|
||||
ip = "10.69.42.6";
|
||||
public = pubkeys."hetzner-arm";
|
||||
endpoint = "hetzner-arm.servers.genderfucked.monster:51820";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
"hetzner-vm": "xgOQQcZQXftPC25+A7Iyf/XK6/iSo3Osyx6kTrZKdzw=",
|
||||
"vault": "u8hSeht8xR48O9AN+0cSsXPK0ZZFNcnPhOxdc+rsrlI=",
|
||||
"raspberry": "Ghrs0ps2RCsg0My9seLq+8ZFZCM4NLZWE8RiY3g9/RU=",
|
||||
"lappy-t495": "8aZBM3f8/qThiHvGlGP1IHLoe61m/3VTwNzCi7CrhF8=",
|
||||
|
|
24
flake.lock
24
flake.lock
|
@ -93,11 +93,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694643239,
|
||||
"narHash": "sha256-pv2k/5FvyirDE8g4TNehzwZ0T4UOMMmqWSQnM/luRtE=",
|
||||
"lastModified": 1695224363,
|
||||
"narHash": "sha256-+hfjJLUMck5G92RVFDZA7LWkR3kOxs5zQ7RPW9t3eM8=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "d9b88b43524db1591fb3d9410a21428198d75d49",
|
||||
"rev": "408ba13188ff9ce309fa2bdd2f81287d79773b00",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -134,11 +134,11 @@
|
|||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1694669921,
|
||||
"narHash": "sha256-6ESpJ6FsftHV96JO/zn6je07tyV2dlLR7SdLsmkegTY=",
|
||||
"lastModified": 1694959747,
|
||||
"narHash": "sha256-CXQ2MuledDVlVM5dLC4pB41cFlBWxRw4tCBsFrq3cRk=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f2ea252d23ebc9a5336bf6a61e0644921f64e67c",
|
||||
"rev": "970a59bd19eff3752ce552935687100c46e820a5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -150,11 +150,11 @@
|
|||
},
|
||||
"nur": {
|
||||
"locked": {
|
||||
"lastModified": 1694778311,
|
||||
"narHash": "sha256-Hu5U9pXwMqUjWF7uh4SKqdKy1QMy9RVGxmst11srSgA=",
|
||||
"lastModified": 1695239195,
|
||||
"narHash": "sha256-0wA8qj7pssnjYAHyt57Js+i96qycM6b0cYXy/nzpBCc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "NUR",
|
||||
"rev": "7a673ac1f35648a908730206a2793b0e3818bc25",
|
||||
"rev": "e088ab8be212d3c2c5eeb36bac25d384b4dda779",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -176,11 +176,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1695142252,
|
||||
"narHash": "sha256-rcYxKVb6Mpna3xNSwRHMw/Yzw3tky0+JuMLM5qoBiUw=",
|
||||
"lastModified": 1695255877,
|
||||
"narHash": "sha256-QKRrwgVS0hHP34IqxjdTC0Lpp7mBVeqFNX22Lbqgmh8=",
|
||||
"owner": "ChaotiCryptidz",
|
||||
"repo": "piped-flake",
|
||||
"rev": "994a8e983eef9071d73c9b2daad9bd42aac0b1aa",
|
||||
"rev": "76f688b1e63ce9ef2b2435cd64e30d10d98fa9cd",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -7,22 +7,22 @@
|
|||
inherit (lib.lists) forEach;
|
||||
inherit (builtins) attrNames;
|
||||
|
||||
containerAddresses = import "${self}/hosts/hetzner-vm/data/containerAddresses.nix";
|
||||
containerAddresses = import "${self}/hosts/hetzner-arm/data/containerAddresses.nix";
|
||||
in {
|
||||
programs.ssh.enable = true;
|
||||
programs.ssh.matchBlocks =
|
||||
mkMerge
|
||||
((forEach ["hetzner-vm" "vault" "raspberry" "vault-decrypt"] (hostname: {
|
||||
((forEach ["hetzner-arm" "hetzner-arm-decrypt" "vault" "vault-decrypt" "raspberry"] (hostname: {
|
||||
"${hostname}" = {
|
||||
user = "root";
|
||||
hostname = "${hostname}.servers.genderfucked.monster";
|
||||
};
|
||||
}))
|
||||
++ (forEach (attrNames containerAddresses.containers) (name: {
|
||||
"hetzner-vm-container-${name}" = {
|
||||
"hetzner-arm-container-${name}" = {
|
||||
user = "root";
|
||||
hostname = "${containerAddresses.containers.${name}}";
|
||||
proxyJump = "hetzner-vm";
|
||||
proxyJump = "hetzner-arm";
|
||||
};
|
||||
}))
|
||||
++ [
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
hostPath,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkMerge;
|
||||
inherit (lib.lists) forEach;
|
||||
inherit (lib.modules) mkMerge mkForce;
|
||||
|
||||
ports = [
|
||||
# SMTP
|
||||
|
@ -26,20 +25,6 @@
|
|||
4190
|
||||
];
|
||||
|
||||
containerLib = import "${self}/lib/containerLib.nix" {
|
||||
inherit lib;
|
||||
};
|
||||
|
||||
# Using secrets from Host
|
||||
secrets = config.services.secrets.secrets;
|
||||
secretsList = [
|
||||
"mail_restic_password"
|
||||
"mail_restic_env"
|
||||
"private_mail_aliases"
|
||||
"chaos_mail_passwd"
|
||||
"system_mail_passwd"
|
||||
"gotosocial_mail_passwd"
|
||||
];
|
||||
sharedFiles = [
|
||||
"/var/lib/acme/mail.owo.monster/fullchain.pem"
|
||||
"/var/lib/acme/mail.owo.monster/key.pem"
|
||||
|
@ -48,74 +33,51 @@ in {
|
|||
containers.mail = {
|
||||
autoStart = true;
|
||||
|
||||
bindMounts = mkMerge [
|
||||
(containerLib.genBindHostsForSecrets secrets secretsList)
|
||||
|
||||
(mkMerge (forEach sharedFiles (file: {
|
||||
bindMounts = mkMerge (map (file: {
|
||||
"${file}" = {
|
||||
hostPath = "${file}";
|
||||
};
|
||||
})))
|
||||
];
|
||||
})
|
||||
sharedFiles);
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit tree;
|
||||
inherit self;
|
||||
inherit hostPath;
|
||||
hostSecrets = secrets;
|
||||
};
|
||||
|
||||
config = {config, ...}: {
|
||||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
[
|
||||
profiles.base
|
||||
inputs.home-manager-unstable.nixosModules.home-manager
|
||||
presets.nixos.containerBase
|
||||
|
||||
profiles.nginx
|
||||
modules.nixos.secrets
|
||||
|
||||
users.root
|
||||
./secrets.nix
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.mail; [
|
||||
++ (with hosts.hetzner-arm.containers.mail; [
|
||||
modules.mailserver
|
||||
profiles.mailserver
|
||||
profiles.restic
|
||||
]);
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.secrets.secretsDir} - root root"
|
||||
"d /var/lib/acme - root root"
|
||||
"d /var/lib/acme/mail.owo.monster - root root"
|
||||
];
|
||||
|
||||
networking.firewall = {
|
||||
enable = false;
|
||||
enable = mkForce false;
|
||||
};
|
||||
|
||||
home-manager.users.root = {
|
||||
imports = with tree; [home.base home.dev.small];
|
||||
|
||||
home.stateVersion = "23.05";
|
||||
};
|
||||
|
||||
# Manually configure nameserver. Using resolved inside the container seems to fail
|
||||
# currently
|
||||
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
|
||||
# users for secrets
|
||||
users.users."dovecot2" = {
|
||||
uid = config.ids.uids.dovecot2;
|
||||
group = "dovecot2";
|
||||
};
|
||||
users.groups."dovecot2".gid = config.ids.gids.dovecot2;
|
||||
|
||||
# ssl for mail
|
||||
services.nginx = {
|
||||
enable = true;
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
pkgs,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
in {
|
||||
services.mailserver = {
|
||||
enable = true;
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
hostSecrets,
|
||||
...
|
||||
}: let
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
|
||||
mailConfig = config.services.mailserver;
|
||||
|
||||
backupPrepareCommand = "${
|
||||
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||
systemctl start postgresqlBackup-roundcube --wait
|
||||
|
@ -16,8 +17,8 @@ in {
|
|||
restic
|
||||
(pkgs.writeShellScriptBin "restic-mail" ''
|
||||
env \
|
||||
RESTIC_PASSWORD_FILE=${secrets.mail_restic_password.path} \
|
||||
$(cat ${secrets.mail_restic_env.path}) \
|
||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||
$(cat ${secrets.restic_env.path}) \
|
||||
${pkgs.restic}/bin/restic $@
|
||||
'')
|
||||
];
|
||||
|
@ -36,8 +37,8 @@ in {
|
|||
# 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/Mail";
|
||||
passwordFile = "${secrets.mail_restic_password.path}";
|
||||
environmentFile = "${secrets.mail_restic_env.path}";
|
||||
passwordFile = "${secrets.restic_password.path}";
|
||||
environmentFile = "${secrets.restic_env.path}";
|
||||
|
||||
pruneOpts = [
|
||||
"--keep-last 5"
|
75
hosts/hetzner-arm/containers/mail/secrets.nix
Normal file
75
hosts/hetzner-arm/containers/mail/secrets.nix
Normal file
|
@ -0,0 +1,75 @@
|
|||
{pkgs, ...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "hetzner-arm-container-mail";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
requiredVaultPaths = [
|
||||
"api-keys/data/storage/restic/Mail"
|
||||
"api-keys/data/chaos_mail/system"
|
||||
"api-keys/data/chaos_mail/gotosocial"
|
||||
"passwords/data/mail"
|
||||
"private-public-keys/data/restic/Mail"
|
||||
"infra/data/private-mail-aliases"
|
||||
];
|
||||
|
||||
packages = with pkgs; [
|
||||
apacheHttpd
|
||||
];
|
||||
|
||||
secrets = {
|
||||
vault_password = {
|
||||
manual = true;
|
||||
};
|
||||
|
||||
restic_password = {
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/restic/Mail" .password > "$secretFile"
|
||||
'';
|
||||
};
|
||||
restic_env = {
|
||||
fetchScript = ''
|
||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Mail" .username)
|
||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Mail" .password)
|
||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Mail" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
private_mail_aliases = {
|
||||
fetchScript = ''
|
||||
kv_get "/infra/private-mail-aliases" | jq .data.data | jq -r 'to_entries|map("\(.key) \(.value.to)")[]' > "$secretFile"
|
||||
'';
|
||||
};
|
||||
chaos_mail_passwd = {
|
||||
user = "dovecot2";
|
||||
group = "dovecot2";
|
||||
fetchScript = ''
|
||||
password=$(simple_get "/passwords/mail" .password)
|
||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||
'';
|
||||
};
|
||||
system_mail_passwd = {
|
||||
user = "dovecot2";
|
||||
group = "dovecot2";
|
||||
fetchScript = ''
|
||||
password=$(simple_get "/api-keys/chaos_mail/system" .password)
|
||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||
'';
|
||||
};
|
||||
gotosocial_mail_passwd = {
|
||||
user = "dovecot2";
|
||||
group = "dovecot2";
|
||||
fetchScript = ''
|
||||
password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
|
||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -4,50 +4,40 @@
|
|||
tree,
|
||||
lib,
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkMerge;
|
||||
inherit (lib.lists) forEach;
|
||||
|
||||
containerName = "music";
|
||||
|
||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||
|
||||
hostIP = containerAddresses.host;
|
||||
containerIP = containerAddresses.containers.${containerName};
|
||||
|
||||
containerName = "music";
|
||||
containerConfig = config.containers.${containerName}.config;
|
||||
|
||||
containerLib = import "${self}/lib/containerLib.nix" {
|
||||
inherit lib;
|
||||
};
|
||||
|
||||
# Using secrets from Host
|
||||
secrets = config.services.secrets.secrets;
|
||||
secretsList = [
|
||||
"mpd_control_password"
|
||||
"slskd_env"
|
||||
];
|
||||
|
||||
ports = import ./data/ports.nix;
|
||||
|
||||
# these secrets should probs be in host but im lazy
|
||||
containerSecrets = config.containers.${containerName}.config.services.secrets.secrets;
|
||||
pathInContainer = path: "/var/lib/nixos-containers/${containerName}" + path;
|
||||
in {
|
||||
containers.music = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = hostIP;
|
||||
localAddress = containerIP;
|
||||
bindMounts = containerLib.genBindHostsForSecrets secrets secretsList;
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit tree;
|
||||
inherit self;
|
||||
inherit hostPath;
|
||||
hostSecrets = secrets;
|
||||
};
|
||||
|
||||
config = {config, ...}: {
|
||||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
|
@ -58,8 +48,10 @@ in {
|
|||
|
||||
profiles.nginx
|
||||
profiles.firewallAllow.httpCommon
|
||||
|
||||
./secrets.nix
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.music; [
|
||||
++ (with hosts.hetzner-arm.containers.music; [
|
||||
profiles.mpd
|
||||
profiles.musicSync
|
||||
profiles.soulseek
|
||||
|
@ -75,11 +67,6 @@ in {
|
|||
slskd-web
|
||||
];
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.secrets.secretsDir} - root root"
|
||||
];
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
|
@ -97,7 +84,7 @@ in {
|
|||
services.nginx.virtualHosts."stream.owo.monster" = let
|
||||
extraConfig = ''
|
||||
auth_basic "Music Password";
|
||||
auth_basic_user_file ${secrets.music_stream_passwd.path};
|
||||
auth_basic_user_file ${pathInContainer containerSecrets.music_stream_passwd.path};
|
||||
'';
|
||||
in {
|
||||
forceSSL = true;
|
||||
|
@ -118,15 +105,6 @@ in {
|
|||
})));
|
||||
};
|
||||
|
||||
# For permissions of secrets
|
||||
users.users."mpd" = {
|
||||
uid = containerConfig.ids.uids.mpd;
|
||||
group = "mpd";
|
||||
};
|
||||
users.groups."mpd" = {
|
||||
gid = containerConfig.ids.gids.mpd;
|
||||
};
|
||||
|
||||
networking = {
|
||||
nat.forwardPorts = [
|
||||
{
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (lib.lists) forEach;
|
||||
|
||||
ports = import ../data/ports.nix;
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
in {
|
||||
environment.systemPackages = with pkgs; [
|
||||
mpc_cli
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
lib,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
ports = import ../data/ports.nix;
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
|
||||
inherit (lib.modules) mkForce;
|
||||
in {
|
57
hosts/hetzner-arm/containers/music/secrets.nix
Normal file
57
hosts/hetzner-arm/containers/music/secrets.nix
Normal file
|
@ -0,0 +1,57 @@
|
|||
{pkgs, ...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "hetzner-arm-container-music";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
requiredVaultPaths = [
|
||||
"api-keys/data/mpd"
|
||||
"api-keys/data/music-stream"
|
||||
"passwords/data/soulseek"
|
||||
"passwords/data/slskd"
|
||||
];
|
||||
|
||||
packages = with pkgs; [
|
||||
apacheHttpd
|
||||
];
|
||||
|
||||
secrets = {
|
||||
vault_password = {
|
||||
manual = true;
|
||||
};
|
||||
|
||||
mpd_control_password = {
|
||||
user = "mpd";
|
||||
group = "mpd";
|
||||
fetchScript = ''
|
||||
simple_get "/api-keys/mpd" .password > "$secretFile"
|
||||
'';
|
||||
};
|
||||
music_stream_passwd = {
|
||||
user = "nginx";
|
||||
group = "nginx";
|
||||
fetchScript = ''
|
||||
username=$(simple_get "/api-keys/music-stream" .username)
|
||||
password=$(simple_get "/api-keys/music-stream" .password)
|
||||
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||
'';
|
||||
};
|
||||
slskd_env = {
|
||||
fetchScript = ''
|
||||
soulseek_password=$(simple_get "/passwords/soulseek" .password)
|
||||
slskd_password=$(simple_get "/passwords/slskd" .password)
|
||||
echo > "$secretFile"
|
||||
echo "SLSKD_SLSK_PASSWORD=$soulseek_password" >> "$secretFile"
|
||||
echo "SLSKD_PASSWORD=$slskd_password" >> "$secretFile"
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -5,10 +5,12 @@
|
|||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkForce;
|
||||
|
||||
containerName = "piped-fi";
|
||||
containerConfig = config.containers.${containerName}.config;
|
||||
|
||||
pipedSocketForComponent = (
|
||||
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
||||
|
@ -28,8 +30,7 @@ in {
|
|||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
[
|
||||
imports = with tree; [
|
||||
presets.nixos.containerBase
|
||||
|
||||
profiles.nginx
|
||||
|
@ -38,16 +39,14 @@ in {
|
|||
profiles.pipedCluster
|
||||
|
||||
./secrets.nix
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.piped-fi.profiles; [
|
||||
restic
|
||||
]);
|
||||
];
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/cockroachdb-certs - root root"
|
||||
];
|
||||
|
||||
networking.firewall.enable = mkForce false;
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "hetzner-vm-container-piped-fi";
|
||||
loginUsername = "hetzner-arm-container-piped-fi";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
|
@ -2,7 +2,6 @@
|
|||
self,
|
||||
hostPath,
|
||||
tree,
|
||||
lib,
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
|
@ -11,34 +10,21 @@
|
|||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||
hostIP = containerAddresses.host;
|
||||
containerIP = containerAddresses.containers.quassel;
|
||||
|
||||
containerLib = import "${self}/lib/containerLib.nix" {
|
||||
inherit lib;
|
||||
};
|
||||
|
||||
# Using secrets from Host
|
||||
secrets = config.services.secrets.secrets;
|
||||
secretsList = [
|
||||
"quassel_restic_env"
|
||||
"quassel_restic_password"
|
||||
];
|
||||
in {
|
||||
containers.quassel = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = hostIP;
|
||||
localAddress = containerIP;
|
||||
bindMounts = containerLib.genBindHostsForSecrets secrets secretsList;
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit tree;
|
||||
inherit self;
|
||||
inherit hostPath;
|
||||
hostSecrets = secrets;
|
||||
};
|
||||
|
||||
config = {config, ...}: {
|
||||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
|
@ -46,17 +32,14 @@ in {
|
|||
presets.nixos.containerBase
|
||||
profiles.sshd
|
||||
profiles.firewallAllow.ssh
|
||||
|
||||
./secrets.nix
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.quassel.profiles; [
|
||||
++ (with hosts.hetzner-arm.containers.quassel.profiles; [
|
||||
quassel
|
||||
restic
|
||||
]);
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.secrets.secretsDir} - root root"
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [4242];
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
pkgs,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
|
||||
backupPrepareCommand = "${
|
||||
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||
|
@ -15,8 +15,8 @@ in {
|
|||
restic
|
||||
(pkgs.writeShellScriptBin "restic-quassel" ''
|
||||
env \
|
||||
RESTIC_PASSWORD_FILE=${secrets.quassel_restic_password.path} \
|
||||
$(cat ${secrets.quassel_restic_env.path}) \
|
||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||
$(cat ${secrets.restic_env.path}) \
|
||||
${pkgs.restic}/bin/restic $@
|
||||
'')
|
||||
];
|
||||
|
@ -31,8 +31,8 @@ in {
|
|||
# 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/Quassel";
|
||||
passwordFile = "${secrets.quassel_restic_password.path}";
|
||||
environmentFile = "${secrets.quassel_restic_env.path}";
|
||||
passwordFile = "${secrets.restic_password.path}";
|
||||
environmentFile = "${secrets.restic_env.path}";
|
||||
|
||||
pruneOpts = [
|
||||
"--keep-last 5"
|
38
hosts/hetzner-arm/containers/quassel/secrets.nix
Normal file
38
hosts/hetzner-arm/containers/quassel/secrets.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "hetzner-arm-container-quassel";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
requiredVaultPaths = [
|
||||
"api-keys/data/storage/restic/Quassel"
|
||||
"private-public-keys/data/restic/Quassel"
|
||||
];
|
||||
|
||||
secrets = {
|
||||
vault_password = {
|
||||
manual = true;
|
||||
};
|
||||
|
||||
restic_password = {
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/restic/Quassel" .password > "$secretFile"
|
||||
'';
|
||||
};
|
||||
restic_env = {
|
||||
fetchScript = ''
|
||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Quassel" .username)
|
||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Quassel" .password)
|
||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Quassel" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
70
hosts/hetzner-arm/containers/social/default.nix
Normal file
70
hosts/hetzner-arm/containers/social/default.nix
Normal file
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
self,
|
||||
hostPath,
|
||||
tree,
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||
hostIP = containerAddresses.host;
|
||||
containerIP = containerAddresses.containers.social;
|
||||
in {
|
||||
containers.social = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = hostIP;
|
||||
localAddress = containerIP;
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit tree;
|
||||
inherit self;
|
||||
inherit hostPath;
|
||||
};
|
||||
|
||||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
[
|
||||
presets.nixos.containerBase
|
||||
profiles.sshd
|
||||
profiles.firewallAllow.ssh
|
||||
|
||||
./secrets.nix
|
||||
]
|
||||
++ (with hosts.hetzner-arm.containers.social.profiles; [
|
||||
gotosocial
|
||||
restic
|
||||
]);
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [8080];
|
||||
};
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."gts-01.owo.monster" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://${containerIP}:8080";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
# uncomment if running nginx without recommendedProxySettings
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||
'';
|
||||
};
|
||||
extraConfig = ''
|
||||
client_max_body_size 128M;
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
{
|
||||
hostPath,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||
hostIP = containerAddresses.host;
|
||||
containerIP = containerAddresses.containers.social;
|
||||
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
in {
|
||||
services.gotosocial = {
|
||||
enable = true;
|
||||
setupPostgresqlDB = true;
|
||||
environmentFile = secrets.social_env_secrets.path;
|
||||
environmentFile = secrets.env_secrets.path;
|
||||
|
||||
settings = {
|
||||
application-name = "chaos-gts";
|
|
@ -2,13 +2,12 @@
|
|||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
hostSecrets,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (lib.lists) forEach;
|
||||
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
|
||||
# Because gotosocial-admin isn't a seporate package we need to generate a seperate config
|
||||
# and duplicate the wrapper for use in a systemd unit
|
||||
|
@ -48,8 +47,8 @@ in {
|
|||
restic
|
||||
(pkgs.writeShellScriptBin "restic-social" ''
|
||||
env \
|
||||
RESTIC_PASSWORD_FILE=${secrets.social_restic_password.path} \
|
||||
$(cat ${secrets.social_restic_env.path}) \
|
||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||
$(cat ${secrets.restic_env.path}) \
|
||||
${pkgs.restic}/bin/restic $@
|
||||
'')
|
||||
];
|
||||
|
@ -64,8 +63,8 @@ in {
|
|||
# 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/Social";
|
||||
passwordFile = "${secrets.social_restic_password.path}";
|
||||
environmentFile = "${secrets.social_restic_env.path}";
|
||||
passwordFile = "${secrets.restic_password.path}";
|
||||
environmentFile = "${secrets.restic_env.path}";
|
||||
|
||||
pruneOpts = [
|
||||
"--keep-last 10"
|
47
hosts/hetzner-arm/containers/social/secrets.nix
Normal file
47
hosts/hetzner-arm/containers/social/secrets.nix
Normal file
|
@ -0,0 +1,47 @@
|
|||
{...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "hetzner-arm-container-social";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
requiredVaultPaths = [
|
||||
"private-public-keys/data/restic/Social"
|
||||
|
||||
"api-keys/data/storage/restic/Social"
|
||||
|
||||
"api-keys/data/chaos_mail/gotosocial"
|
||||
];
|
||||
|
||||
secrets = {
|
||||
vault_password = {
|
||||
manual = true;
|
||||
};
|
||||
|
||||
restic_password = {
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/restic/Social" .password > "$secretFile"
|
||||
'';
|
||||
};
|
||||
restic_env = {
|
||||
fetchScript = ''
|
||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Social" .username)
|
||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Social" .password)
|
||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Social" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
env_secrets = {
|
||||
fetchScript = ''
|
||||
smtp_password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
|
||||
echo "GTS_SMTP_PASSWORD=$smtp_password" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -8,7 +8,8 @@
|
|||
rclone_serve_restic_social = 4212;
|
||||
rclone_serve_restic_quassel = 4213;
|
||||
rclone_serve_restic_piped_finland = 4214;
|
||||
rclone_serve_restic_mail = 4215;
|
||||
rclone_serve_restic_piped_uk = 4215;
|
||||
rclone_serve_restic_mail = 4216;
|
||||
|
||||
rclone_serve_http_music = 4220;
|
||||
rclone_serve_http_public = 4221;
|
|
@ -36,20 +36,14 @@ in {
|
|||
|
||||
imports = with tree;
|
||||
[
|
||||
profiles.base
|
||||
inputs.home-manager-unstable.nixosModules.home-manager
|
||||
presets.nixos.containerBase
|
||||
|
||||
profiles.sshd
|
||||
|
||||
modules.nixos.rclone-serve
|
||||
modules.nixos.rclone-sync
|
||||
modules.nixos.secrets
|
||||
profiles.firewallAllow.ssh
|
||||
|
||||
./secrets.nix
|
||||
|
||||
users.root
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.storage.profiles; [
|
||||
++ (with hosts.hetzner-arm.containers.storage.profiles; [
|
||||
rcloneConfigs
|
||||
rcloneServe
|
||||
rcloneSync
|
||||
|
@ -58,20 +52,12 @@ in {
|
|||
|
||||
environment.systemPackages = with pkgs; [rclone];
|
||||
|
||||
home-manager.users.root = {
|
||||
imports = with tree; [home.base home.dev.small];
|
||||
home.packages = with pkgs; [vault-bin];
|
||||
home.stateVersion = "23.05";
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = attrValues ports;
|
||||
};
|
||||
|
||||
# Manually configure nameserver. Using resolved inside the container seems to fail
|
||||
# currently
|
||||
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
|
@ -110,6 +96,7 @@ in {
|
|||
"/Social/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_social}";
|
||||
"/Quassel/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_quassel}";
|
||||
"/Piped-Finland/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_piped_finland}";
|
||||
"/Piped-UK/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_piped_uk}";
|
||||
"/Mail/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_mail}";
|
||||
};
|
||||
extraConfig = ''
|
|
@ -126,6 +126,16 @@ in {
|
|||
"--baseurl=/Piped-Finland/"
|
||||
];
|
||||
}
|
||||
{
|
||||
id = "restic-piped-uk";
|
||||
remote = "StorageBox:Backups/Restic/Piped-UK";
|
||||
type = "restic";
|
||||
extraArgs = [
|
||||
"--addr=0.0.0.0:${toString ports.rclone_serve_restic_piped_uk}"
|
||||
"--htpasswd=${secrets.restic_piped_uk_htpasswd.path}"
|
||||
"--baseurl=/Piped-UK/"
|
||||
];
|
||||
}
|
||||
{
|
||||
id = "restic-mail";
|
||||
remote = "StorageBox:Backups/Restic/Mail";
|
|
@ -1,17 +1,10 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.services.secrets;
|
||||
in {
|
||||
{pkgs, ...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "hetzner-vm-container-storage";
|
||||
loginPasswordFile = cfg.secrets.vault_password.path;
|
||||
loginUsername = "hetzner-arm-container-storage";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
||||
|
@ -36,6 +29,7 @@ in {
|
|||
"api-keys/data/storage/restic/Social"
|
||||
"api-keys/data/storage/restic/Quassel"
|
||||
"api-keys/data/storage/restic/Piped-Finland"
|
||||
"api-keys/data/storage/restic/Piped-UK"
|
||||
"api-keys/data/storage/restic/Mail"
|
||||
|
||||
"api-keys/data/storage/webdav/main"
|
||||
|
@ -51,14 +45,6 @@ in {
|
|||
rclone
|
||||
];
|
||||
|
||||
uidMap = {
|
||||
"storage" = config.users.users."storage".uid;
|
||||
};
|
||||
|
||||
gidMap = {
|
||||
"storage" = config.users.groups."storage".gid;
|
||||
};
|
||||
|
||||
extraFunctions = ''
|
||||
replace_slash_for_sed() {
|
||||
sed "s#/#\\\/#"
|
||||
|
@ -142,6 +128,16 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
restic_piped_uk_htpasswd = {
|
||||
user = "storage";
|
||||
group = "storage";
|
||||
fetchScript = ''
|
||||
username=$(simple_get "/api-keys/storage/restic/Piped-UK" .username)
|
||||
password=$(simple_get "/api-keys/storage/restic/Piped-UK" .password)
|
||||
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||
'';
|
||||
};
|
||||
|
||||
restic_mail_htpasswd = {
|
||||
user = "storage";
|
||||
group = "storage";
|
|
@ -5,6 +5,5 @@
|
|||
social = "192.168.100.12";
|
||||
music = "192.168.100.13";
|
||||
quassel = "192.168.100.14";
|
||||
piped = "192.168.100.15";
|
||||
};
|
||||
}
|
|
@ -11,25 +11,24 @@ in {
|
|||
presets.nixos.serverHetzner
|
||||
presets.nixos.serverEncryptedDrive
|
||||
|
||||
#profiles.nginx
|
||||
#profiles.firewallAllow.httpCommon
|
||||
profiles.nginx
|
||||
profiles.firewallAllow.httpCommon
|
||||
|
||||
#profiles.chaosInternalWireGuard
|
||||
profiles.chaosInternalWireGuard
|
||||
|
||||
./hardware.nix
|
||||
./secrets.nix
|
||||
]
|
||||
++ (forEach [
|
||||
#"social"
|
||||
#"storage"
|
||||
#"music"
|
||||
#"quassel"
|
||||
#"piped-fi"
|
||||
#"mail"
|
||||
"social"
|
||||
"storage"
|
||||
"music"
|
||||
"quassel"
|
||||
"piped-fi"
|
||||
"mail"
|
||||
] (name: ./containers + "/${name}"))
|
||||
++ (with hosts.hetzner-vm.profiles; [
|
||||
#vaultUI
|
||||
#gitlabStaticSites
|
||||
++ (with hosts.hetzner-arm.profiles; [
|
||||
gitlabStaticSites
|
||||
]);
|
||||
|
||||
# For Containers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{pkgs, ...}: {
|
||||
{...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
|
@ -9,12 +9,13 @@
|
|||
|
||||
autoSecrets = {
|
||||
enable = true;
|
||||
#affectedSystemdServices = [
|
||||
# "wg-quick-wg0"
|
||||
#];
|
||||
affectedSystemdServices = [
|
||||
"wg-quick-wg0"
|
||||
];
|
||||
};
|
||||
|
||||
requiredVaultPaths = [
|
||||
"private-public-keys/data/ssh/root@hetzner-arm"
|
||||
"private-public-keys/data/ssh/root@hetzner-arm-decrypt"
|
||||
|
||||
"api-keys/data/gitlab/gitlab_pages_serve"
|
||||
|
@ -25,11 +26,28 @@
|
|||
manual = true;
|
||||
};
|
||||
|
||||
ssh_host_ed25519_key = {
|
||||
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||
permissions = "600";
|
||||
fetchScript = ''
|
||||
[ ! -d "$SYSROOT/etc/ssh" ] && mkdir -p "$SYSROOT/etc/ssh/"
|
||||
simple_get "/private-public-keys/ssh/root@hetzner-arm" .private | base64 -d > "$secretFile"
|
||||
'';
|
||||
};
|
||||
ssh_host_ed25519_key_pub = {
|
||||
path = "/etc/ssh/ssh_host_ed25519_key.pub";
|
||||
permissions = "600";
|
||||
fetchScript = ''
|
||||
[ ! -d "$SYSROOT/etc/ssh" ] && mkdir -p "$SYSROOT/etc/ssh/"
|
||||
simple_get "/private-public-keys/ssh/root@hetzner-arm" .private | base64 -d > "$secretFile"
|
||||
'';
|
||||
};
|
||||
|
||||
# this doesn't need to be a secret and can be generated at install time
|
||||
# but it makes it easier to install.
|
||||
# it's stored in /nix store anyway
|
||||
ssh_host_ed25519_key = {
|
||||
path = "/ssh_host_ed25519_key";
|
||||
initrd_ssh_host_ed25519_key = {
|
||||
path = "/initrd_ssh_host_ed25519_key";
|
||||
permissions = "600";
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/ssh/root@hetzner-arm-decrypt" .private | base64 -d > "$secretFile"
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
{
|
||||
self,
|
||||
hostPath,
|
||||
tree,
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||
hostIP = containerAddresses.host;
|
||||
containerIP = containerAddresses.containers.social;
|
||||
|
||||
# Using secrets from Host
|
||||
secrets = config.services.secrets.secrets;
|
||||
in {
|
||||
containers.social = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = hostIP;
|
||||
localAddress = containerIP;
|
||||
bindMounts = {
|
||||
"${secrets.social_restic_password.path}" = {
|
||||
hostPath = "${secrets.social_restic_password.path}";
|
||||
};
|
||||
"${secrets.social_restic_env.path}" = {
|
||||
hostPath = "${secrets.social_restic_env.path}";
|
||||
};
|
||||
"${secrets.social_env_secrets.path}" = {
|
||||
hostPath = "${secrets.social_env_secrets.path}";
|
||||
};
|
||||
};
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit tree;
|
||||
inherit self;
|
||||
inherit hostPath;
|
||||
hostSecrets = secrets;
|
||||
};
|
||||
|
||||
config = {config, ...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
[
|
||||
profiles.base
|
||||
inputs.home-manager-unstable.nixosModules.home-manager
|
||||
|
||||
profiles.sshd
|
||||
|
||||
modules.nixos.secrets
|
||||
|
||||
users.root
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.social; [
|
||||
profiles.gotosocial
|
||||
profiles.restic
|
||||
]);
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
rclone
|
||||
restic
|
||||
];
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.secrets.secretsDir} - root root"
|
||||
];
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [22 8080];
|
||||
};
|
||||
|
||||
home-manager.users.root = {
|
||||
imports = with tree; [home.base home.dev.small];
|
||||
home.stateVersion = "23.05";
|
||||
};
|
||||
|
||||
# Manually configure nameserver. Using resolved inside the container seems to fail
|
||||
# currently
|
||||
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."gts-01.owo.monster" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://${containerIP}:8080";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
# uncomment if running nginx without recommendedProxySettings
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||
'';
|
||||
};
|
||||
extraConfig = ''
|
||||
client_max_body_size 128M;
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
{...}: {
|
||||
boot.loader = {
|
||||
grub = {
|
||||
enable = true;
|
||||
device = "/dev/sda";
|
||||
};
|
||||
};
|
||||
|
||||
boot.initrd.kernelModules = ["nvme"];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/sda1";
|
||||
fsType = "ext4";
|
||||
};
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
{
|
||||
tree,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.lists) forEach;
|
||||
in {
|
||||
imports = with tree;
|
||||
[
|
||||
presets.nixos.serverBase
|
||||
presets.nixos.serverHetzner
|
||||
|
||||
profiles.nginx
|
||||
profiles.firewallAllow.httpCommon
|
||||
|
||||
profiles.cross.arm64
|
||||
profiles.chaosInternalWireGuard
|
||||
|
||||
./hardware.nix
|
||||
./secrets.nix
|
||||
]
|
||||
++ (forEach [
|
||||
"social"
|
||||
"storage"
|
||||
"music"
|
||||
"quassel"
|
||||
"piped-fi"
|
||||
"mail"
|
||||
] (name: ./containers + "/${name}"))
|
||||
++ (with hosts.hetzner-vm.profiles; [
|
||||
vaultUI
|
||||
gitlabStaticSites
|
||||
]);
|
||||
|
||||
# For Containers
|
||||
networking.nat = {
|
||||
enable = true;
|
||||
internalInterfaces = ["ve-+"];
|
||||
externalInterface = "enp1s0";
|
||||
};
|
||||
|
||||
networking.hostName = "hetzner-vm";
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
{pkgs, ...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "hetzner-vm";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
||||
enable = true;
|
||||
affectedSystemdServices = [
|
||||
"wg-quick-wg0"
|
||||
"container@music"
|
||||
"container@social"
|
||||
"container@quassel"
|
||||
"container@piped-fi"
|
||||
];
|
||||
};
|
||||
|
||||
packages = with pkgs; [
|
||||
# for music & mail passwd files
|
||||
apacheHttpd
|
||||
];
|
||||
|
||||
requiredVaultPaths = [
|
||||
"api-keys/data/mpd"
|
||||
"api-keys/data/music-stream"
|
||||
|
||||
"api-keys/data/gitlab/gitlab_pages_serve"
|
||||
|
||||
"api-keys/data/storage/restic/Mail"
|
||||
"api-keys/data/storage/restic/Social"
|
||||
"api-keys/data/storage/restic/Quassel"
|
||||
|
||||
"api-keys/data/chaos_mail/system"
|
||||
"api-keys/data/chaos_mail/gotosocial"
|
||||
|
||||
"passwords/data/soulseek"
|
||||
"passwords/data/slskd"
|
||||
"passwords/data/mail"
|
||||
|
||||
"private-public-keys/data/restic/Mail"
|
||||
"private-public-keys/data/restic/Social"
|
||||
"private-public-keys/data/restic/Quassel"
|
||||
|
||||
"infra/data/private-mail-aliases"
|
||||
];
|
||||
|
||||
secrets = {
|
||||
vault_password = {
|
||||
manual = true;
|
||||
};
|
||||
|
||||
# Used directly by server
|
||||
# for fetching gitlab static sites
|
||||
gitlab_env = {
|
||||
user = "gitlab_artifacts_sync";
|
||||
group = "gitlab_artifacts_sync";
|
||||
fetchScript = ''
|
||||
token=$(simple_get "/api-keys/gitlab/gitlab_pages_serve" .token)
|
||||
echo "GITLAB_TOKEN=$token" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
|
||||
# Container: music
|
||||
mpd_control_password = {
|
||||
user = "mpd";
|
||||
group = "mpd";
|
||||
fetchScript = ''
|
||||
simple_get "/api-keys/mpd" .password > "$secretFile"
|
||||
'';
|
||||
};
|
||||
music_stream_passwd = {
|
||||
user = "nginx";
|
||||
group = "nginx";
|
||||
fetchScript = ''
|
||||
username=$(simple_get "/api-keys/music-stream" .username)
|
||||
password=$(simple_get "/api-keys/music-stream" .password)
|
||||
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||
'';
|
||||
};
|
||||
slskd_env = {
|
||||
fetchScript = ''
|
||||
soulseek_password=$(simple_get "/passwords/soulseek" .password)
|
||||
slskd_password=$(simple_get "/passwords/slskd" .password)
|
||||
echo > "$secretFile"
|
||||
echo "SLSKD_SLSK_PASSWORD=$soulseek_password" >> "$secretFile"
|
||||
echo "SLSKD_PASSWORD=$slskd_password" >> "$secretFile"
|
||||
'';
|
||||
};
|
||||
|
||||
# Container: mail
|
||||
mail_restic_password = {
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/restic/Mail" .password > "$secretFile"
|
||||
'';
|
||||
};
|
||||
mail_restic_env = {
|
||||
fetchScript = ''
|
||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Mail" .username)
|
||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Mail" .password)
|
||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Mail" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
private_mail_aliases = {
|
||||
fetchScript = ''
|
||||
kv_get "/infra/private-mail-aliases" | jq .data.data | jq -r 'to_entries|map("\(.key) \(.value.to)")[]' > "$secretFile"
|
||||
'';
|
||||
};
|
||||
chaos_mail_passwd = {
|
||||
user = "dovecot2";
|
||||
group = "dovecot2";
|
||||
fetchScript = ''
|
||||
password=$(simple_get "/passwords/mail" .password)
|
||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||
'';
|
||||
};
|
||||
system_mail_passwd = {
|
||||
user = "dovecot2";
|
||||
group = "dovecot2";
|
||||
fetchScript = ''
|
||||
password=$(simple_get "/api-keys/chaos_mail/system" .password)
|
||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||
'';
|
||||
};
|
||||
gotosocial_mail_passwd = {
|
||||
user = "dovecot2";
|
||||
group = "dovecot2";
|
||||
fetchScript = ''
|
||||
password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
|
||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||
'';
|
||||
};
|
||||
|
||||
# Container: social
|
||||
social_restic_password = {
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/restic/Social" .password > "$secretFile"
|
||||
'';
|
||||
};
|
||||
social_restic_env = {
|
||||
fetchScript = ''
|
||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Social" .username)
|
||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Social" .password)
|
||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Social" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
social_env_secrets = {
|
||||
fetchScript = ''
|
||||
smtp_password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
|
||||
echo "GTS_SMTP_PASSWORD=$smtp_password" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
|
||||
# Container: quassel
|
||||
quassel_restic_password = {
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/restic/Quassel" .password > "$secretFile"
|
||||
'';
|
||||
};
|
||||
quassel_restic_env = {
|
||||
fetchScript = ''
|
||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Quassel" .username)
|
||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Quassel" .password)
|
||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Quassel" > "$secretFile"
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
presets.nixos.encryptedUSB
|
||||
|
||||
profiles.cross.arm64
|
||||
#profiles.remote-builders
|
||||
profiles.remoteBuilders
|
||||
profiles.chaosInternalWireGuard
|
||||
|
||||
./secrets.nix
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
};
|
||||
|
||||
music_stream_password = {
|
||||
user = 1000;
|
||||
user = "chaos";
|
||||
group = "users";
|
||||
fetchScript = ''
|
||||
simple_get "/api-keys/music-stream" .password > "$secretFile"
|
||||
|
@ -17,8 +17,6 @@
|
|||
# Required for home.apps.manualBackupApps
|
||||
gitlab_archiver_token = {
|
||||
user = "chaos";
|
||||
group = "users";
|
||||
|
||||
fetchScript = ''
|
||||
simple_get "/api-keys/gitlab/gitlab_archiver" .token > "$secretFile"
|
||||
'';
|
||||
|
@ -27,8 +25,6 @@
|
|||
# Required for home.apps.manualBackupApps
|
||||
restic_music_env = {
|
||||
user = "chaos";
|
||||
group = "users";
|
||||
|
||||
fetchScript = ''
|
||||
api_username=$(simple_get "/api-keys/storage/restic/Music" .username)
|
||||
api_password=$(simple_get "/api-keys/storage/restic/Music" .password)
|
||||
|
|
|
@ -81,16 +81,6 @@ in {
|
|||
modules = defaultModules ++ [./hetzner-arm/hetzner-arm.nix];
|
||||
};
|
||||
|
||||
hetzner-vm = nixosUnstableSystem {
|
||||
specialArgs =
|
||||
defaultSpecialArgs
|
||||
// {
|
||||
hostPath = ./hetzner-vm;
|
||||
};
|
||||
system = "x86_64-linux";
|
||||
modules = defaultModules ++ [./hetzner-vm/hetzner-vm.nix];
|
||||
};
|
||||
|
||||
vault = nixosUnstableSystem {
|
||||
specialArgs =
|
||||
defaultSpecialArgs
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkForce;
|
||||
|
||||
containerName = "piped-uk";
|
||||
containerConfig = config.containers.${containerName}.config;
|
||||
|
||||
pipedSocketForComponent = (
|
||||
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
||||
|
@ -39,11 +41,12 @@ in {
|
|||
./secrets.nix
|
||||
];
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/cockroachdb-certs - root root"
|
||||
];
|
||||
|
||||
networking.firewall.enable = mkForce false;
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
|
|
|
@ -1,25 +1,17 @@
|
|||
{pkgs, ...}: {
|
||||
{...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
packages = with pkgs; [rclone];
|
||||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "raspberry";
|
||||
loginUsername = "raspberry-container-piped-uk";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
||||
enable = true;
|
||||
affectedSystemdServices = ["wg-quick-wg0" "cockroachdb"];
|
||||
affectedSystemdServices = ["cockroachdb"];
|
||||
};
|
||||
|
||||
extraFunctions = ''
|
||||
simple_get_obscure() {
|
||||
rclone obscure "$(simple_get "$@")"
|
||||
}
|
||||
'';
|
||||
|
||||
requiredVaultPaths = [
|
||||
"private-public-keys/data/piped-cockroachdb-ca/nodes/raspberry"
|
||||
];
|
||||
|
@ -29,7 +21,7 @@
|
|||
manual = true;
|
||||
};
|
||||
|
||||
piped_cockroachdb_ca_certificate = {
|
||||
cockroachdb_ca_certificate = {
|
||||
user = "cockroachdb";
|
||||
group = "cockroachdb";
|
||||
permissions = "600";
|
||||
|
@ -42,7 +34,7 @@
|
|||
| base64 -d > "$secretFile"
|
||||
'';
|
||||
};
|
||||
piped_cockroachdb_node_certificate = {
|
||||
cockroachdb_node_certificate = {
|
||||
user = "cockroachdb";
|
||||
group = "cockroachdb";
|
||||
permissions = "600";
|
||||
|
@ -55,7 +47,7 @@
|
|||
| base64 -d > "$secretFile"
|
||||
'';
|
||||
};
|
||||
piped_cockroachdb_node_key = {
|
||||
cockroachdb_node_key = {
|
||||
user = "cockroachdb";
|
||||
group = "cockroachdb";
|
||||
permissions = "600";
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
};
|
||||
|
||||
requiredVaultPaths = [
|
||||
"/private-public-keys/data/ssh/root@vault"
|
||||
"/private-public-keys/data/ssh/root@vault-decrypt"
|
||||
|
||||
"private-public-keys/data/restic/Vault"
|
||||
|
@ -27,11 +28,28 @@
|
|||
manual = true;
|
||||
};
|
||||
|
||||
ssh_host_ed25519_key = {
|
||||
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||
permissions = "600";
|
||||
fetchScript = ''
|
||||
[ ! -d "$SYSROOT/etc/ssh" ] && mkdir -p "$SYSROOT/etc/ssh/"
|
||||
simple_get "/private-public-keys/ssh/root@vault" .private | base64 -d > "$secretFile"
|
||||
'';
|
||||
};
|
||||
ssh_host_ed25519_key_pub = {
|
||||
path = "/etc/ssh/ssh_host_ed25519_key.pub";
|
||||
permissions = "600";
|
||||
fetchScript = ''
|
||||
[ ! -d "$SYSROOT/etc/ssh" ] && mkdir -p "$SYSROOT/etc/ssh/"
|
||||
simple_get "/private-public-keys/ssh/root@vault" .private | base64 -d > "$secretFile"
|
||||
'';
|
||||
};
|
||||
|
||||
# this doesn't need to be a secret and can be generated at install time
|
||||
# but it makes it easier to install.
|
||||
# it's stored in /nix store anyway
|
||||
ssh_host_ed25519_key = {
|
||||
path = "/ssh_host_ed25519_key";
|
||||
initrd_ssh_host_ed25519_key = {
|
||||
path = "/initrd_ssh_host_ed25519_key";
|
||||
permissions = "600";
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/ssh/root@vault-decrypt" .private | base64 -d > "$secretFile"
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
]
|
||||
++ (with hosts.vault.profiles; [
|
||||
vault
|
||||
vaultUI
|
||||
restic
|
||||
]);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.lists) filter;
|
||||
inherit (lib) types;
|
||||
inherit (builtins) isString listToAttrs;
|
||||
inherit (builtins) isString listToAttrs attrNames;
|
||||
|
||||
cfg = config.services.secrets;
|
||||
|
||||
|
@ -115,25 +115,79 @@ in {
|
|||
extraFunctions = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "extra bash functions to add to top of script";
|
||||
description = "extra bash functions to add to top of script for init";
|
||||
};
|
||||
|
||||
extraCheckFunctions = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = "extra bash functions to add to top of script for check";
|
||||
};
|
||||
|
||||
uidMap = mkOption {
|
||||
type = types.attrsOf types.int;
|
||||
default = {};
|
||||
description = "optional mapping of users to user IDs; required for SYSROOT when user isn't available on host";
|
||||
default = listToAttrs (map (
|
||||
secretName: let
|
||||
secretUserName = cfg.secrets.${secretName}.user;
|
||||
in {
|
||||
name = "${secretUserName}";
|
||||
value = config.users.users.${secretUserName}.uid;
|
||||
}
|
||||
) (filter
|
||||
(secretName: let
|
||||
secret = cfg.secrets.${secretName};
|
||||
in
|
||||
isString secret.user
|
||||
&& (
|
||||
if config.users.users ? "${secret.user}"
|
||||
then true
|
||||
else builtins.trace "warning: secrets module could not find a uid mapping for user ${secret.user}" false
|
||||
))
|
||||
(attrNames cfg.secrets)));
|
||||
description = ''
|
||||
optional mapping of users to user IDs
|
||||
required for SYSROOT when user isn't available on host
|
||||
defaults to getting values from users.users.<name>.uid for all secrets with user set as string
|
||||
'';
|
||||
};
|
||||
|
||||
gidMap = mkOption {
|
||||
type = types.attrsOf types.int;
|
||||
default = {};
|
||||
description = "optional mapping of groups to group IDs; required for SYSROOT when group isn't available on host";
|
||||
default = listToAttrs (map (
|
||||
secretName: let
|
||||
secretGroupName = cfg.secrets.${secretName}.group;
|
||||
in {
|
||||
name = "${secretGroupName}";
|
||||
value = config.users.groups.${secretGroupName}.gid;
|
||||
}
|
||||
) (filter
|
||||
(secretName: let
|
||||
secret = cfg.secrets.${secretName};
|
||||
in
|
||||
isString secret.group
|
||||
&& (
|
||||
if config.users.groups ? "${secret.group}"
|
||||
then true
|
||||
else builtins.trace "warning: secrets module could not find a gid mapping for group ${secret.group}" false
|
||||
))
|
||||
(attrNames cfg.secrets)));
|
||||
description = ''
|
||||
optional mapping of groups to group IDs
|
||||
required for SYSROOT when group isn't available on host
|
||||
defaults to getting values from users.groups.<group>.gid for all secrets with group set as string
|
||||
'';
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = "packages for script";
|
||||
description = "packages for init script";
|
||||
};
|
||||
|
||||
checkPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = "packages for checkscript";
|
||||
};
|
||||
|
||||
secrets = mkOption {
|
||||
|
@ -241,7 +295,7 @@ in {
|
|||
// {
|
||||
auto-secrets.partOf =
|
||||
map (unitConfig: unitConfig.name + ".service")
|
||||
(lib.filter
|
||||
(filter
|
||||
(unitConfig: unitConfig.withPartOf)
|
||||
affectedSystemdServices);
|
||||
};
|
||||
|
|
|
@ -195,6 +195,11 @@
|
|||
stat --format "%a" "$1" 2>/dev/null
|
||||
}
|
||||
|
||||
emojiTick="✅"
|
||||
emojiCross="❌"
|
||||
|
||||
${cfg.extraCheckFunctions}
|
||||
|
||||
GLOBAL_FAIL=false
|
||||
''
|
||||
+ (concatStringsSep "\n" (mapAttrsToList (_name: secret: let
|
||||
|
@ -226,40 +231,40 @@
|
|||
secretFile="$SYSROOT${secretPath}"
|
||||
|
||||
if [[ -f "$SYSROOT${secretPath}" ]]; then
|
||||
echo "✅ File Exists"
|
||||
echo "$emojiTick File Exists"
|
||||
else
|
||||
echo "❌ File Does Not Exist"
|
||||
echo "$emojiCross File Does Not Exist"
|
||||
LOCAL_FAIL=true
|
||||
fi
|
||||
|
||||
if getUserID "$SYSROOT${secretPath}" >/dev/null && ${userCheck}; then
|
||||
echo "✅ File Is Owned By Correct User"
|
||||
echo "$emojiTick File Is Owned By Correct User"
|
||||
else
|
||||
echo "❌ File Is Not Owned By Correct User (${toString secretUser})"
|
||||
echo "$emojiCross File Is Not Owned By Correct User (${toString secretUser})"
|
||||
LOCAL_FAIL=true
|
||||
fi
|
||||
|
||||
if getGroupID "$SYSROOT${secretPath}" >/dev/null && ${groupCheck}; then
|
||||
echo "✅ File Is Owned By Correct Group"
|
||||
echo "$emojiTick File Is Owned By Correct Group"
|
||||
else
|
||||
echo "❌ File Is Not Owned By Correct Group (${toString secretGroup})"
|
||||
echo "$emojiCross File Is Not Owned By Correct Group (${toString secretGroup})"
|
||||
LOCAL_FAIL=true
|
||||
fi
|
||||
|
||||
if getPermissions "$SYSROOT${secretPath}" >/dev/null && [[ "$(getPermissions "$SYSROOT${secretPath}")" -eq "${secretPermissions}" ]]; then
|
||||
echo "✅ File Has Correct Permissions"
|
||||
echo "$emojiTick File Has Correct Permissions"
|
||||
else
|
||||
echo "❌ File Does Not Have Correct Permissions (${secretPermissions})"
|
||||
echo "$emojiCross File Does Not Have Correct Permissions (${secretPermissions})"
|
||||
LOCAL_FAIL=true
|
||||
fi
|
||||
|
||||
${optionalString (secret.checkScript != null) secret.checkScript}
|
||||
|
||||
if [[ "$LOCAL_FAIL" == "true" ]]; then
|
||||
echo "❌ File Did Not Pass The Vibe Check"
|
||||
echo "$emojiCross File Did Not Pass The Vibe Check"
|
||||
GLOBAL_FAIL=true
|
||||
else
|
||||
echo "✅ File Passed The Vibe Check"
|
||||
echo "$emojiTick File Passed The Vibe Check"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
@ -267,10 +272,10 @@
|
|||
cfg.secrets))
|
||||
+ ''
|
||||
if [[ "$GLOBAL_FAIL" == "true" ]]; then
|
||||
echo "❌ One Or More Secrets Did Not Pass The Vibe Check"
|
||||
echo "$emojiCross One Or More Secrets Did Not Pass The Vibe Check"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ All Secrets Passed The Vibe Check"
|
||||
echo "$emojiTick All Secrets Passed The Vibe Check"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
@ -319,7 +324,7 @@ in rec {
|
|||
scripts = genScripts cfg;
|
||||
in (writeShellApplication {
|
||||
name = scriptName;
|
||||
runtimeInputs = defaultPackages ++ cfg.packages;
|
||||
runtimeInputs = defaultPackages ++ cfg.checkPackages;
|
||||
text = scripts.checkScript;
|
||||
})
|
||||
);
|
||||
|
|
25
outputs.nix
25
outputs.nix
|
@ -18,6 +18,22 @@ in
|
|||
overlays = [
|
||||
(import ./overlay)
|
||||
inputs.piped-flake.overlays.default
|
||||
(_prev: final: {
|
||||
piped-backend-deps =
|
||||
final.piped-backend-deps.overrideAttrs
|
||||
{
|
||||
# Won't build due to this; added a native-arm64 to all builders on arm64
|
||||
# https://github.com/NixOS/nixpkgs/issues/255780
|
||||
requiredSystemFeatures = ["native-arm64"];
|
||||
};
|
||||
piped-backend =
|
||||
final.piped-backend.overrideAttrs
|
||||
{
|
||||
# Won't build due to this; added a native-arm64 to all builders on arm64
|
||||
# https://github.com/NixOS/nixpkgs/issues/255780
|
||||
requiredSystemFeatures = ["native-arm64"];
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
in
|
||||
|
@ -124,18 +140,15 @@ in
|
|||
|
||||
# All machines/containers with secrets.nix
|
||||
machines = rec {
|
||||
"hetzner-vm" = {
|
||||
containers = ["storage" "piped-fi"];
|
||||
sshAddress = "hetzner-vm.servers.genderfucked.monster";
|
||||
};
|
||||
"hetzner-arm" = {
|
||||
containers = ["storage" "piped-fi"];
|
||||
sshAddress = "hetzner-vm.servers.genderfucked.monster";
|
||||
containers = ["storage" "music" "quassel" "social" "mail" "piped-fi"];
|
||||
sshAddress = "hetzner-arm.servers.genderfucked.monster";
|
||||
};
|
||||
"vault" = {
|
||||
sshAddress = "vault.servers.genderfucked.monster";
|
||||
};
|
||||
"raspberry" = {
|
||||
containers = ["piped-uk"];
|
||||
sshAddress = "raspberry.servers.genderfucked.monster";
|
||||
};
|
||||
"lappy-t495" = {};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkForce;
|
||||
inherit (lib.lists) optional;
|
||||
inherit (lib.lists) optionals;
|
||||
|
||||
system = pkgs.system;
|
||||
|
||||
|
@ -33,10 +33,10 @@ in {
|
|||
"dm_mod"
|
||||
"cryptd"
|
||||
]
|
||||
++ (lib.optionals (system == "x86_64_linux") ["aesni_intel"]);
|
||||
++ (optionals (system == "x86_64_linux") ["aesni_intel"]);
|
||||
|
||||
secrets = {
|
||||
"/ssh_host_ed25519_key" = "/ssh_host_ed25519_key";
|
||||
"/ssh_host_ed25519_key" = mkForce "/initrd_ssh_host_ed25519_key";
|
||||
};
|
||||
|
||||
luks = {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.strings) optionalString versionAtLeast;
|
||||
inherit (lib.optional);
|
||||
in {
|
||||
nix = {
|
||||
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
|
||||
|
@ -13,6 +15,7 @@ in {
|
|||
(versionAtLeast config.nix.package.version "2.4") ''
|
||||
experimental-features = nix-command flakes
|
||||
'';
|
||||
settings.system-features = lib.optional (pkgs.system == "aarch64-linux") "native-arm64";
|
||||
settings.trusted-users = ["root" "@wheel"];
|
||||
};
|
||||
nixpkgs = {
|
||||
|
@ -30,6 +33,23 @@ in {
|
|||
inputs.gitlab_artifacts_sync.overlays.default
|
||||
inputs.gitlab_archiver.overlays.default
|
||||
inputs.piped-flake.overlays.default
|
||||
|
||||
(_prev: final: {
|
||||
piped-backend-deps =
|
||||
final.piped-backend-deps.overrideAttrs
|
||||
{
|
||||
# Won't build due to this; added a native-arm64 to all builders on arm64
|
||||
# https://github.com/NixOS/nixpkgs/issues/255780
|
||||
requiredSystemFeatures = ["native-arm64"];
|
||||
};
|
||||
piped-backend =
|
||||
final.piped-backend.overrideAttrs
|
||||
{
|
||||
# Won't build due to this; added a native-arm64 to all builders on arm64
|
||||
# https://github.com/NixOS/nixpkgs/issues/255780
|
||||
requiredSystemFeatures = ["native-arm64"];
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
environment.etc."nixpkgs-commit".text = inputs.nixpkgs-unstable.rev;
|
||||
|
|
|
@ -12,14 +12,11 @@
|
|||
|
||||
currentHostName = config.networking.hostName;
|
||||
|
||||
joinString = lib.concatStringsSep "," ([
|
||||
"localhost:${toString ports.cockroachDB}"
|
||||
]
|
||||
++ (
|
||||
joinString = lib.concatStringsSep "," (
|
||||
map
|
||||
(hostName: hosts.${hostName}.joinString)
|
||||
(filter (hostName: hostName != currentHostName) (attrNames hosts))
|
||||
));
|
||||
);
|
||||
in {
|
||||
systemd.services.haproxy.wantedBy = ["piped-backend.service"];
|
||||
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
{
|
||||
self,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
secrets = config.services.secrets.secrets;
|
||||
|
||||
clusterConfig = import "${self}/data/piped/pipedClusterConfig.nix";
|
||||
|
||||
currentHostConfig = clusterConfig.hosts.${config.networking.hostName};
|
||||
inherit (currentHostConfig) resticName resticBucket;
|
||||
in {
|
||||
environment.systemPackages = with pkgs; [
|
||||
restic
|
||||
(pkgs.writeShellScriptBin "restic-piped-finland" ''
|
||||
(pkgs.writeShellScriptBin "restic-${resticName}" ''
|
||||
env \
|
||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||
$(cat ${secrets.restic_env.path}) \
|
||||
|
@ -15,14 +21,14 @@ in {
|
|||
'')
|
||||
];
|
||||
|
||||
services.restic.backups.piped-finland = {
|
||||
services.restic.backups.${resticName} = {
|
||||
user = "root";
|
||||
paths = [
|
||||
"/var/lib/cockroachdb"
|
||||
"/var/lib/cockroachdb-certs"
|
||||
];
|
||||
|
||||
repository = "rest:https://storage-restic.owo.monster/Piped-Finland";
|
||||
repository = "rest:https://storage-restic.owo.monster/${resticBucket}";
|
||||
passwordFile = "${secrets.restic_password.path}";
|
||||
environmentFile = "${secrets.restic_env.path}";
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.modules) mkIf mkMerge;
|
||||
|
||||
currentHostname = config.networking.hostName;
|
||||
|
||||
|
@ -26,22 +26,28 @@
|
|||
};
|
||||
in {
|
||||
nix.buildMachines = [
|
||||
(mkIf (currentHostname != "hetzner-vm") (builderDefaults
|
||||
// {
|
||||
hostName = "hetzner-vm.servers.genderfucked.monster";
|
||||
systems = ["x86_64-linux" "aarch64-linux"];
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU1JdDJBQnF3SGhNano5cjZhdHY0WHVYNTh4RVdlU3RrbVhVd3ZNVkd2NHcgcm9vdEBuaXhvcwo=";
|
||||
maxJobs = 3;
|
||||
speedFactor = 2;
|
||||
}))
|
||||
(mkIf (currentHostname != "vault") (builderDefaults
|
||||
// {
|
||||
(mkIf (currentHostname != "hetzner-arm") (mkMerge [
|
||||
builderDefaults
|
||||
{
|
||||
hostName = "hetzner-arm.servers.genderfucked.monster";
|
||||
systems = ["aarch64-linux"];
|
||||
supportedFeatures = ["native-arm64"];
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUk5cGM0REU1UlV4UUp2T1pwenFOQWVac0JlRW1kcmp4OFlnV3orVXBMckcgcm9vdEBoZXR6bmVyLWFybQo=";
|
||||
maxJobs = 4;
|
||||
speedFactor = 3;
|
||||
}
|
||||
]))
|
||||
(mkIf (currentHostname != "vault") (mkMerge [
|
||||
builderDefaults
|
||||
{
|
||||
hostName = "vault.servers.genderfucked.monster";
|
||||
systems = ["x86_64-linux"];
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU16L1dyaG81MTFGdzhXN3FsU0NUY1V4cWh4TGlBQkJXbFNNNFRNNzJ5RWQgcm9vdEBuaXhvcwo=";
|
||||
maxJobs = 2;
|
||||
systems = ["aarch64-linux"];
|
||||
supportedFeatures = ["native-arm64"];
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSURGTlFjUTdkbUlRS1lqMUVVTFBlcTI4d2hzMTg2YVZ0WitWU05rd3I2aEkgcm9vdEB2YXVsdAo=";
|
||||
maxJobs = 1;
|
||||
speedFactor = 1;
|
||||
}))
|
||||
}
|
||||
]))
|
||||
];
|
||||
nix.distributedBuilds = true;
|
||||
nix.extraOptions = "builders-use-substitutes = true";
|
||||
|
|
1
result-man
Symbolic link
1
result-man
Symbolic link
|
@ -0,0 +1 @@
|
|||
/nix/store/026j6nzg6hyllkkvzjnqnarxwrc32nsa-bash-5.2-p15-man
|
9
scripts/deploy/hetzner-arm.sh
Executable file
9
scripts/deploy/hetzner-arm.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
cd $SCRIPT_DIR
|
||||
cd $(git rev-parse --show-toplevel)
|
||||
|
||||
DEFAULT_HOST="root@hetzner-arm.servers.genderfucked.monster"
|
||||
TARGET_HOST=${HOST:-${DEFAULT_HOST}}
|
||||
nixos-rebuild switch --flake .#hetzner-arm --target-host "$TARGET_HOST" --use-substitutes -s "$@"
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
cd $SCRIPT_DIR
|
||||
cd $(git rev-parse --show-toplevel)
|
||||
|
||||
nixos-rebuild switch --flake .#hetzner-vm --target-host hetzner-vm -s "$@"
|
|
@ -4,5 +4,6 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|||
cd $SCRIPT_DIR
|
||||
cd $(git rev-parse --show-toplevel)
|
||||
|
||||
[ -n "$NO_BUILD_PIPED_BACKEND" ] && ./scripts/buildPipedBackendAArch64.nix
|
||||
nixos-rebuild switch --flake .#raspberry --target-host raspberry -s "$@"
|
||||
DEFAULT_HOST="root@raspberry.servers.genderfucked.monster"
|
||||
TARGET_HOST=${HOST:-${DEFAULT_HOST}}
|
||||
nixos-rebuild switch --flake .#raspberry --target-host "$TARGET_HOST" --use-substitutes -s "$@"
|
||||
|
|
|
@ -4,4 +4,6 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|||
cd $SCRIPT_DIR
|
||||
cd $(git rev-parse --show-toplevel)
|
||||
|
||||
nixos-rebuild switch --flake .#vault --target-host vault -s "$@"
|
||||
DEFAULT_HOST="root@vault.servers.genderfucked.monster"
|
||||
TARGET_HOST=${HOST:-${DEFAULT_HOST}}
|
||||
nixos-rebuild switch --flake .#vault --target-host "$TARGET_HOST" --use-substitutes -s "$@"
|
|
@ -9,6 +9,6 @@ cd $(git rev-parse --show-toplevel)
|
|||
HOSTNAME=$(hostname)
|
||||
|
||||
[ "${NO_REBUILD}" == "" ] && ./scripts/rebuild.sh "$@"
|
||||
[ "${HOSTNAME}" != "hetzner-vm" ] && ./scripts/deploy/hetzner-vm.sh "$@"
|
||||
[ "${HOSTNAME}" != "hetzner-arm" ] && ./scripts/deploy/hetzner-arm.sh "$@"
|
||||
[ "${HOSTNAME}" != "vault" ] && ./scripts/deploy/vault.sh "$@"
|
||||
[ "${HOSTNAME}" != "raspberry" ] && ./scripts/deploy/raspberry.sh "$@"
|
Loading…
Reference in a new issue