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 = {
|
hosts = {
|
||||||
# map of hostname to config for cluster node
|
# map of hostname to config for cluster node
|
||||||
"piped-fi" = rec {
|
"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}";
|
joinString = "${ip}:${toString ports.cockroachDB}";
|
||||||
advertiseAddr = joinString;
|
advertiseAddr = joinString;
|
||||||
|
|
||||||
|
resticName = "piped-finland";
|
||||||
resticBucket = "Piped-Finland";
|
resticBucket = "Piped-Finland";
|
||||||
|
|
||||||
vaultUserName = "hetzner-vm-container-piped-fi";
|
|
||||||
|
|
||||||
baseDomain = "piped-fi.owo.monster";
|
baseDomain = "piped-fi.owo.monster";
|
||||||
};
|
};
|
||||||
|
|
||||||
"piped-uk" = rec {
|
"piped-uk" = rec {
|
||||||
ip = "${internalWireGuard.hosts.raspberry.ip}";
|
ip = "${internalWireGuard.hosts.raspberry.ip}";
|
||||||
|
|
||||||
# ssh -L 3014:127.0.0.1:3014 -L 26257:127.0.0.1:26257 raspberry
|
# ssh -L 3014:127.0.0.1:3014 -L 26257:127.0.0.1:26257 raspberry
|
||||||
joinString = "${ip}:${toString ports.cockroachDB}";
|
joinString = "${ip}:${toString ports.cockroachDB}";
|
||||||
advertiseAddr = joinString;
|
advertiseAddr = joinString;
|
||||||
|
resticName = "piped-uk";
|
||||||
resticBucket = "Piped-UK";
|
resticBucket = "Piped-UK";
|
||||||
|
|
||||||
vaultUserName = "rapsberry-container-piped-uk";
|
|
||||||
|
|
||||||
baseDomain = "piped-uk.owo.monster";
|
baseDomain = "piped-uk.owo.monster";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
rec {
|
rec {
|
||||||
"hetzner-vm" = {
|
|
||||||
ipv4 = "65.21.182.73";
|
|
||||||
ipv6 = "2a01:4f9:c010:8beb::1";
|
|
||||||
};
|
|
||||||
"hetzner-arm" = {
|
"hetzner-arm" = {
|
||||||
ipv4 = "65.21.145.62";
|
ipv4 = "65.21.145.62";
|
||||||
ipv6 = "2a01:4f9:c012:9dbf::1";
|
ipv6 = "2a01:4f9:c012:9dbf::1";
|
||||||
|
|
|
@ -2,10 +2,10 @@ let
|
||||||
pubkeys = builtins.fromJSON (builtins.readFile ./chaosInternalWireGuardPubKeys.json);
|
pubkeys = builtins.fromJSON (builtins.readFile ./chaosInternalWireGuardPubKeys.json);
|
||||||
in rec {
|
in rec {
|
||||||
hosts = {
|
hosts = {
|
||||||
"hetzner-vm" = {
|
"hetzner-arm" = {
|
||||||
ip = "10.69.42.1";
|
ip = "10.69.42.1";
|
||||||
public = pubkeys."hetzner-vm";
|
public = pubkeys."hetzner-arm";
|
||||||
endpoint = "hetzner-vm.servers.genderfucked.monster:51820";
|
endpoint = "hetzner-arm.servers.genderfucked.monster:51820";
|
||||||
};
|
};
|
||||||
"vault" = {
|
"vault" = {
|
||||||
ip = "10.69.42.2";
|
ip = "10.69.42.2";
|
||||||
|
@ -25,11 +25,5 @@ in rec {
|
||||||
public = pubkeys."raspberry";
|
public = pubkeys."raspberry";
|
||||||
endpoint = "raspberry.servers.genderfucked.monster:51820";
|
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=",
|
"vault": "u8hSeht8xR48O9AN+0cSsXPK0ZZFNcnPhOxdc+rsrlI=",
|
||||||
"raspberry": "Ghrs0ps2RCsg0My9seLq+8ZFZCM4NLZWE8RiY3g9/RU=",
|
"raspberry": "Ghrs0ps2RCsg0My9seLq+8ZFZCM4NLZWE8RiY3g9/RU=",
|
||||||
"lappy-t495": "8aZBM3f8/qThiHvGlGP1IHLoe61m/3VTwNzCi7CrhF8=",
|
"lappy-t495": "8aZBM3f8/qThiHvGlGP1IHLoe61m/3VTwNzCi7CrhF8=",
|
||||||
|
|
24
flake.lock
24
flake.lock
|
@ -93,11 +93,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694643239,
|
"lastModified": 1695224363,
|
||||||
"narHash": "sha256-pv2k/5FvyirDE8g4TNehzwZ0T4UOMMmqWSQnM/luRtE=",
|
"narHash": "sha256-+hfjJLUMck5G92RVFDZA7LWkR3kOxs5zQ7RPW9t3eM8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "d9b88b43524db1591fb3d9410a21428198d75d49",
|
"rev": "408ba13188ff9ce309fa2bdd2f81287d79773b00",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -134,11 +134,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694669921,
|
"lastModified": 1694959747,
|
||||||
"narHash": "sha256-6ESpJ6FsftHV96JO/zn6je07tyV2dlLR7SdLsmkegTY=",
|
"narHash": "sha256-CXQ2MuledDVlVM5dLC4pB41cFlBWxRw4tCBsFrq3cRk=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "f2ea252d23ebc9a5336bf6a61e0644921f64e67c",
|
"rev": "970a59bd19eff3752ce552935687100c46e820a5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -150,11 +150,11 @@
|
||||||
},
|
},
|
||||||
"nur": {
|
"nur": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694778311,
|
"lastModified": 1695239195,
|
||||||
"narHash": "sha256-Hu5U9pXwMqUjWF7uh4SKqdKy1QMy9RVGxmst11srSgA=",
|
"narHash": "sha256-0wA8qj7pssnjYAHyt57Js+i96qycM6b0cYXy/nzpBCc=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "7a673ac1f35648a908730206a2793b0e3818bc25",
|
"rev": "e088ab8be212d3c2c5eeb36bac25d384b4dda779",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -176,11 +176,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1695142252,
|
"lastModified": 1695255877,
|
||||||
"narHash": "sha256-rcYxKVb6Mpna3xNSwRHMw/Yzw3tky0+JuMLM5qoBiUw=",
|
"narHash": "sha256-QKRrwgVS0hHP34IqxjdTC0Lpp7mBVeqFNX22Lbqgmh8=",
|
||||||
"owner": "ChaotiCryptidz",
|
"owner": "ChaotiCryptidz",
|
||||||
"repo": "piped-flake",
|
"repo": "piped-flake",
|
||||||
"rev": "994a8e983eef9071d73c9b2daad9bd42aac0b1aa",
|
"rev": "76f688b1e63ce9ef2b2435cd64e30d10d98fa9cd",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -7,22 +7,22 @@
|
||||||
inherit (lib.lists) forEach;
|
inherit (lib.lists) forEach;
|
||||||
inherit (builtins) attrNames;
|
inherit (builtins) attrNames;
|
||||||
|
|
||||||
containerAddresses = import "${self}/hosts/hetzner-vm/data/containerAddresses.nix";
|
containerAddresses = import "${self}/hosts/hetzner-arm/data/containerAddresses.nix";
|
||||||
in {
|
in {
|
||||||
programs.ssh.enable = true;
|
programs.ssh.enable = true;
|
||||||
programs.ssh.matchBlocks =
|
programs.ssh.matchBlocks =
|
||||||
mkMerge
|
mkMerge
|
||||||
((forEach ["hetzner-vm" "vault" "raspberry" "vault-decrypt"] (hostname: {
|
((forEach ["hetzner-arm" "hetzner-arm-decrypt" "vault" "vault-decrypt" "raspberry"] (hostname: {
|
||||||
"${hostname}" = {
|
"${hostname}" = {
|
||||||
user = "root";
|
user = "root";
|
||||||
hostname = "${hostname}.servers.genderfucked.monster";
|
hostname = "${hostname}.servers.genderfucked.monster";
|
||||||
};
|
};
|
||||||
}))
|
}))
|
||||||
++ (forEach (attrNames containerAddresses.containers) (name: {
|
++ (forEach (attrNames containerAddresses.containers) (name: {
|
||||||
"hetzner-vm-container-${name}" = {
|
"hetzner-arm-container-${name}" = {
|
||||||
user = "root";
|
user = "root";
|
||||||
hostname = "${containerAddresses.containers.${name}}";
|
hostname = "${containerAddresses.containers.${name}}";
|
||||||
proxyJump = "hetzner-vm";
|
proxyJump = "hetzner-arm";
|
||||||
};
|
};
|
||||||
}))
|
}))
|
||||||
++ [
|
++ [
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
hostPath,
|
hostPath,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkMerge;
|
inherit (lib.modules) mkMerge mkForce;
|
||||||
inherit (lib.lists) forEach;
|
|
||||||
|
|
||||||
ports = [
|
ports = [
|
||||||
# SMTP
|
# SMTP
|
||||||
|
@ -26,20 +25,6 @@
|
||||||
4190
|
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 = [
|
sharedFiles = [
|
||||||
"/var/lib/acme/mail.owo.monster/fullchain.pem"
|
"/var/lib/acme/mail.owo.monster/fullchain.pem"
|
||||||
"/var/lib/acme/mail.owo.monster/key.pem"
|
"/var/lib/acme/mail.owo.monster/key.pem"
|
||||||
|
@ -48,74 +33,51 @@ in {
|
||||||
containers.mail = {
|
containers.mail = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|
||||||
bindMounts = mkMerge [
|
bindMounts = mkMerge (map (file: {
|
||||||
(containerLib.genBindHostsForSecrets secrets secretsList)
|
|
||||||
|
|
||||||
(mkMerge (forEach sharedFiles (file: {
|
|
||||||
"${file}" = {
|
"${file}" = {
|
||||||
hostPath = "${file}";
|
hostPath = "${file}";
|
||||||
};
|
};
|
||||||
})))
|
})
|
||||||
];
|
sharedFiles);
|
||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
inherit tree;
|
inherit tree;
|
||||||
inherit self;
|
inherit self;
|
||||||
inherit hostPath;
|
inherit hostPath;
|
||||||
hostSecrets = secrets;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {config, ...}: {
|
config = {...}: {
|
||||||
nixpkgs.pkgs = pkgs;
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree;
|
||||||
[
|
[
|
||||||
profiles.base
|
presets.nixos.containerBase
|
||||||
inputs.home-manager-unstable.nixosModules.home-manager
|
|
||||||
|
|
||||||
profiles.nginx
|
profiles.nginx
|
||||||
modules.nixos.secrets
|
|
||||||
|
|
||||||
users.root
|
./secrets.nix
|
||||||
]
|
]
|
||||||
++ (with hosts.hetzner-vm.containers.mail; [
|
++ (with hosts.hetzner-arm.containers.mail; [
|
||||||
modules.mailserver
|
modules.mailserver
|
||||||
profiles.mailserver
|
profiles.mailserver
|
||||||
profiles.restic
|
profiles.restic
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d ${config.services.secrets.secretsDir} - root root"
|
|
||||||
"d /var/lib/acme - root root"
|
"d /var/lib/acme - root root"
|
||||||
"d /var/lib/acme/mail.owo.monster - root root"
|
"d /var/lib/acme/mail.owo.monster - root root"
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
enable = false;
|
enable = mkForce false;
|
||||||
};
|
};
|
||||||
|
|
||||||
home-manager.users.root = {
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
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";
|
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
|
# ssl for mail
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
in {
|
in {
|
||||||
services.mailserver = {
|
services.mailserver = {
|
||||||
enable = true;
|
enable = true;
|
|
@ -1,11 +1,12 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
config,
|
config,
|
||||||
hostSecrets,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
mailConfig = config.services.mailserver;
|
mailConfig = config.services.mailserver;
|
||||||
|
|
||||||
backupPrepareCommand = "${
|
backupPrepareCommand = "${
|
||||||
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||||
systemctl start postgresqlBackup-roundcube --wait
|
systemctl start postgresqlBackup-roundcube --wait
|
||||||
|
@ -16,8 +17,8 @@ in {
|
||||||
restic
|
restic
|
||||||
(pkgs.writeShellScriptBin "restic-mail" ''
|
(pkgs.writeShellScriptBin "restic-mail" ''
|
||||||
env \
|
env \
|
||||||
RESTIC_PASSWORD_FILE=${secrets.mail_restic_password.path} \
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
$(cat ${secrets.mail_restic_env.path}) \
|
$(cat ${secrets.restic_env.path}) \
|
||||||
${pkgs.restic}/bin/restic $@
|
${pkgs.restic}/bin/restic $@
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
@ -36,8 +37,8 @@ in {
|
||||||
# repository is overrided in environmentFile to contain auth
|
# repository is overrided in environmentFile to contain auth
|
||||||
# make sure to keep up to date when changing repository
|
# make sure to keep up to date when changing repository
|
||||||
repository = "rest:https://storage-restic.owo.monster/Mail";
|
repository = "rest:https://storage-restic.owo.monster/Mail";
|
||||||
passwordFile = "${secrets.mail_restic_password.path}";
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
environmentFile = "${secrets.mail_restic_env.path}";
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
|
|
||||||
pruneOpts = [
|
pruneOpts = [
|
||||||
"--keep-last 5"
|
"--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,
|
tree,
|
||||||
lib,
|
lib,
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
|
||||||
pkgs,
|
pkgs,
|
||||||
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkMerge;
|
inherit (lib.modules) mkMerge;
|
||||||
inherit (lib.lists) forEach;
|
inherit (lib.lists) forEach;
|
||||||
|
|
||||||
|
containerName = "music";
|
||||||
|
|
||||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||||
|
|
||||||
hostIP = containerAddresses.host;
|
hostIP = containerAddresses.host;
|
||||||
containerIP = containerAddresses.containers.${containerName};
|
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;
|
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 {
|
in {
|
||||||
containers.music = {
|
containers.music = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
privateNetwork = true;
|
privateNetwork = true;
|
||||||
hostAddress = hostIP;
|
hostAddress = hostIP;
|
||||||
localAddress = containerIP;
|
localAddress = containerIP;
|
||||||
bindMounts = containerLib.genBindHostsForSecrets secrets secretsList;
|
|
||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
inherit tree;
|
inherit tree;
|
||||||
inherit self;
|
inherit self;
|
||||||
inherit hostPath;
|
inherit hostPath;
|
||||||
hostSecrets = secrets;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {config, ...}: {
|
config = {...}: {
|
||||||
nixpkgs.pkgs = pkgs;
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree;
|
||||||
|
@ -58,8 +48,10 @@ in {
|
||||||
|
|
||||||
profiles.nginx
|
profiles.nginx
|
||||||
profiles.firewallAllow.httpCommon
|
profiles.firewallAllow.httpCommon
|
||||||
|
|
||||||
|
./secrets.nix
|
||||||
]
|
]
|
||||||
++ (with hosts.hetzner-vm.containers.music; [
|
++ (with hosts.hetzner-arm.containers.music; [
|
||||||
profiles.mpd
|
profiles.mpd
|
||||||
profiles.musicSync
|
profiles.musicSync
|
||||||
profiles.soulseek
|
profiles.soulseek
|
||||||
|
@ -75,11 +67,6 @@ in {
|
||||||
slskd-web
|
slskd-web
|
||||||
];
|
];
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${config.services.secrets.secretsDir} - root root"
|
|
||||||
];
|
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
|
@ -97,7 +84,7 @@ in {
|
||||||
services.nginx.virtualHosts."stream.owo.monster" = let
|
services.nginx.virtualHosts."stream.owo.monster" = let
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
auth_basic "Music Password";
|
auth_basic "Music Password";
|
||||||
auth_basic_user_file ${secrets.music_stream_passwd.path};
|
auth_basic_user_file ${pathInContainer containerSecrets.music_stream_passwd.path};
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
forceSSL = true;
|
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 = {
|
networking = {
|
||||||
nat.forwardPorts = [
|
nat.forwardPorts = [
|
||||||
{
|
{
|
|
@ -1,14 +1,14 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
inherit (lib.lists) forEach;
|
inherit (lib.lists) forEach;
|
||||||
|
|
||||||
ports = import ../data/ports.nix;
|
ports = import ../data/ports.nix;
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
in {
|
in {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
mpc_cli
|
mpc_cli
|
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
ports = import ../data/ports.nix;
|
ports = import ../data/ports.nix;
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
inherit (lib.modules) mkForce;
|
inherit (lib.modules) mkForce;
|
||||||
in {
|
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,
|
inputs,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
|
inherit (lib.modules) mkForce;
|
||||||
|
|
||||||
containerName = "piped-fi";
|
containerName = "piped-fi";
|
||||||
containerConfig = config.containers.${containerName}.config;
|
|
||||||
|
|
||||||
pipedSocketForComponent = (
|
pipedSocketForComponent = (
|
||||||
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
||||||
|
@ -28,26 +30,23 @@ in {
|
||||||
config = {...}: {
|
config = {...}: {
|
||||||
nixpkgs.pkgs = pkgs;
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree; [
|
||||||
[
|
presets.nixos.containerBase
|
||||||
presets.nixos.containerBase
|
|
||||||
|
|
||||||
profiles.nginx
|
profiles.nginx
|
||||||
profiles.firewallAllow.httpCommon
|
profiles.firewallAllow.httpCommon
|
||||||
|
|
||||||
profiles.pipedCluster
|
profiles.pipedCluster
|
||||||
|
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
]
|
];
|
||||||
++ (with hosts.hetzner-vm.containers.piped-fi.profiles; [
|
|
||||||
restic
|
|
||||||
]);
|
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /var/lib/cockroachdb-certs - root root"
|
"d /var/lib/cockroachdb-certs - root root"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
networking.firewall.enable = mkForce false;
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
vaultLogin = {
|
vaultLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
loginUsername = "hetzner-vm-container-piped-fi";
|
loginUsername = "hetzner-arm-container-piped-fi";
|
||||||
};
|
};
|
||||||
|
|
||||||
autoSecrets = {
|
autoSecrets = {
|
|
@ -2,7 +2,6 @@
|
||||||
self,
|
self,
|
||||||
hostPath,
|
hostPath,
|
||||||
tree,
|
tree,
|
||||||
lib,
|
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
@ -11,34 +10,21 @@
|
||||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||||
hostIP = containerAddresses.host;
|
hostIP = containerAddresses.host;
|
||||||
containerIP = containerAddresses.containers.quassel;
|
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 {
|
in {
|
||||||
containers.quassel = {
|
containers.quassel = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
privateNetwork = true;
|
privateNetwork = true;
|
||||||
hostAddress = hostIP;
|
hostAddress = hostIP;
|
||||||
localAddress = containerIP;
|
localAddress = containerIP;
|
||||||
bindMounts = containerLib.genBindHostsForSecrets secrets secretsList;
|
|
||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
inherit tree;
|
inherit tree;
|
||||||
inherit self;
|
inherit self;
|
||||||
inherit hostPath;
|
inherit hostPath;
|
||||||
hostSecrets = secrets;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {config, ...}: {
|
config = {...}: {
|
||||||
nixpkgs.pkgs = pkgs;
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree;
|
||||||
|
@ -46,17 +32,14 @@ in {
|
||||||
presets.nixos.containerBase
|
presets.nixos.containerBase
|
||||||
profiles.sshd
|
profiles.sshd
|
||||||
profiles.firewallAllow.ssh
|
profiles.firewallAllow.ssh
|
||||||
|
|
||||||
|
./secrets.nix
|
||||||
]
|
]
|
||||||
++ (with hosts.hetzner-vm.containers.quassel.profiles; [
|
++ (with hosts.hetzner-arm.containers.quassel.profiles; [
|
||||||
quassel
|
quassel
|
||||||
restic
|
restic
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${config.services.secrets.secretsDir} - root root"
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [4242];
|
networking.firewall.allowedTCPPorts = [4242];
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
home-manager.users.root.home.stateVersion = "23.05";
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
backupPrepareCommand = "${
|
backupPrepareCommand = "${
|
||||||
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||||
|
@ -15,8 +15,8 @@ in {
|
||||||
restic
|
restic
|
||||||
(pkgs.writeShellScriptBin "restic-quassel" ''
|
(pkgs.writeShellScriptBin "restic-quassel" ''
|
||||||
env \
|
env \
|
||||||
RESTIC_PASSWORD_FILE=${secrets.quassel_restic_password.path} \
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
$(cat ${secrets.quassel_restic_env.path}) \
|
$(cat ${secrets.restic_env.path}) \
|
||||||
${pkgs.restic}/bin/restic $@
|
${pkgs.restic}/bin/restic $@
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
@ -31,8 +31,8 @@ in {
|
||||||
# repository is overrided in environmentFile to contain auth
|
# repository is overrided in environmentFile to contain auth
|
||||||
# make sure to keep up to date when changing repository
|
# make sure to keep up to date when changing repository
|
||||||
repository = "rest:https://storage-restic.owo.monster/Quassel";
|
repository = "rest:https://storage-restic.owo.monster/Quassel";
|
||||||
passwordFile = "${secrets.quassel_restic_password.path}";
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
environmentFile = "${secrets.quassel_restic_env.path}";
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
|
|
||||||
pruneOpts = [
|
pruneOpts = [
|
||||||
"--keep-last 5"
|
"--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,
|
hostPath,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||||
hostIP = containerAddresses.host;
|
hostIP = containerAddresses.host;
|
||||||
containerIP = containerAddresses.containers.social;
|
containerIP = containerAddresses.containers.social;
|
||||||
|
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
in {
|
in {
|
||||||
services.gotosocial = {
|
services.gotosocial = {
|
||||||
enable = true;
|
enable = true;
|
||||||
setupPostgresqlDB = true;
|
setupPostgresqlDB = true;
|
||||||
environmentFile = secrets.social_env_secrets.path;
|
environmentFile = secrets.env_secrets.path;
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
application-name = "chaos-gts";
|
application-name = "chaos-gts";
|
|
@ -2,13 +2,12 @@
|
||||||
pkgs,
|
pkgs,
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
hostSecrets,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
inherit (lib.lists) forEach;
|
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
|
# 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
|
# and duplicate the wrapper for use in a systemd unit
|
||||||
|
@ -48,8 +47,8 @@ in {
|
||||||
restic
|
restic
|
||||||
(pkgs.writeShellScriptBin "restic-social" ''
|
(pkgs.writeShellScriptBin "restic-social" ''
|
||||||
env \
|
env \
|
||||||
RESTIC_PASSWORD_FILE=${secrets.social_restic_password.path} \
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
$(cat ${secrets.social_restic_env.path}) \
|
$(cat ${secrets.restic_env.path}) \
|
||||||
${pkgs.restic}/bin/restic $@
|
${pkgs.restic}/bin/restic $@
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
@ -64,8 +63,8 @@ in {
|
||||||
# repository is overrided in environmentFile to contain auth
|
# repository is overrided in environmentFile to contain auth
|
||||||
# make sure to keep up to date when changing repository
|
# make sure to keep up to date when changing repository
|
||||||
repository = "rest:https://storage-restic.owo.monster/Social";
|
repository = "rest:https://storage-restic.owo.monster/Social";
|
||||||
passwordFile = "${secrets.social_restic_password.path}";
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
environmentFile = "${secrets.social_restic_env.path}";
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
|
|
||||||
pruneOpts = [
|
pruneOpts = [
|
||||||
"--keep-last 10"
|
"--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_social = 4212;
|
||||||
rclone_serve_restic_quassel = 4213;
|
rclone_serve_restic_quassel = 4213;
|
||||||
rclone_serve_restic_piped_finland = 4214;
|
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_music = 4220;
|
||||||
rclone_serve_http_public = 4221;
|
rclone_serve_http_public = 4221;
|
|
@ -36,20 +36,14 @@ in {
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree;
|
||||||
[
|
[
|
||||||
profiles.base
|
presets.nixos.containerBase
|
||||||
inputs.home-manager-unstable.nixosModules.home-manager
|
|
||||||
|
|
||||||
profiles.sshd
|
profiles.sshd
|
||||||
|
profiles.firewallAllow.ssh
|
||||||
modules.nixos.rclone-serve
|
|
||||||
modules.nixos.rclone-sync
|
|
||||||
modules.nixos.secrets
|
|
||||||
|
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
|
|
||||||
users.root
|
|
||||||
]
|
]
|
||||||
++ (with hosts.hetzner-vm.containers.storage.profiles; [
|
++ (with hosts.hetzner-arm.containers.storage.profiles; [
|
||||||
rcloneConfigs
|
rcloneConfigs
|
||||||
rcloneServe
|
rcloneServe
|
||||||
rcloneSync
|
rcloneSync
|
||||||
|
@ -58,20 +52,12 @@ in {
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [rclone];
|
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 = {
|
networking.firewall = {
|
||||||
enable = true;
|
enable = true;
|
||||||
allowedTCPPorts = attrValues ports;
|
allowedTCPPorts = attrValues ports;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Manually configure nameserver. Using resolved inside the container seems to fail
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
# currently
|
|
||||||
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
|
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -110,6 +96,7 @@ in {
|
||||||
"/Social/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_social}";
|
"/Social/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_social}";
|
||||||
"/Quassel/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_quassel}";
|
"/Quassel/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_quassel}";
|
||||||
"/Piped-Finland/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_piped_finland}";
|
"/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}";
|
"/Mail/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_mail}";
|
||||||
};
|
};
|
||||||
extraConfig = ''
|
extraConfig = ''
|
|
@ -126,6 +126,16 @@ in {
|
||||||
"--baseurl=/Piped-Finland/"
|
"--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";
|
id = "restic-mail";
|
||||||
remote = "StorageBox:Backups/Restic/Mail";
|
remote = "StorageBox:Backups/Restic/Mail";
|
|
@ -1,17 +1,10 @@
|
||||||
{
|
{pkgs, ...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
cfg = config.services.secrets;
|
|
||||||
in {
|
|
||||||
services.secrets = {
|
services.secrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
vaultLogin = {
|
vaultLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
loginUsername = "hetzner-vm-container-storage";
|
loginUsername = "hetzner-arm-container-storage";
|
||||||
loginPasswordFile = cfg.secrets.vault_password.path;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
autoSecrets = {
|
autoSecrets = {
|
||||||
|
@ -36,6 +29,7 @@ in {
|
||||||
"api-keys/data/storage/restic/Social"
|
"api-keys/data/storage/restic/Social"
|
||||||
"api-keys/data/storage/restic/Quassel"
|
"api-keys/data/storage/restic/Quassel"
|
||||||
"api-keys/data/storage/restic/Piped-Finland"
|
"api-keys/data/storage/restic/Piped-Finland"
|
||||||
|
"api-keys/data/storage/restic/Piped-UK"
|
||||||
"api-keys/data/storage/restic/Mail"
|
"api-keys/data/storage/restic/Mail"
|
||||||
|
|
||||||
"api-keys/data/storage/webdav/main"
|
"api-keys/data/storage/webdav/main"
|
||||||
|
@ -51,14 +45,6 @@ in {
|
||||||
rclone
|
rclone
|
||||||
];
|
];
|
||||||
|
|
||||||
uidMap = {
|
|
||||||
"storage" = config.users.users."storage".uid;
|
|
||||||
};
|
|
||||||
|
|
||||||
gidMap = {
|
|
||||||
"storage" = config.users.groups."storage".gid;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFunctions = ''
|
extraFunctions = ''
|
||||||
replace_slash_for_sed() {
|
replace_slash_for_sed() {
|
||||||
sed "s#/#\\\/#"
|
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 = {
|
restic_mail_htpasswd = {
|
||||||
user = "storage";
|
user = "storage";
|
||||||
group = "storage";
|
group = "storage";
|
|
@ -5,6 +5,5 @@
|
||||||
social = "192.168.100.12";
|
social = "192.168.100.12";
|
||||||
music = "192.168.100.13";
|
music = "192.168.100.13";
|
||||||
quassel = "192.168.100.14";
|
quassel = "192.168.100.14";
|
||||||
piped = "192.168.100.15";
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -3,4 +3,4 @@
|
||||||
systemd-boot.enable = true;
|
systemd-boot.enable = true;
|
||||||
efi.canTouchEfiVariables = true;
|
efi.canTouchEfiVariables = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,25 +11,24 @@ in {
|
||||||
presets.nixos.serverHetzner
|
presets.nixos.serverHetzner
|
||||||
presets.nixos.serverEncryptedDrive
|
presets.nixos.serverEncryptedDrive
|
||||||
|
|
||||||
#profiles.nginx
|
profiles.nginx
|
||||||
#profiles.firewallAllow.httpCommon
|
profiles.firewallAllow.httpCommon
|
||||||
|
|
||||||
#profiles.chaosInternalWireGuard
|
profiles.chaosInternalWireGuard
|
||||||
|
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
]
|
]
|
||||||
++ (forEach [
|
++ (forEach [
|
||||||
#"social"
|
"social"
|
||||||
#"storage"
|
"storage"
|
||||||
#"music"
|
"music"
|
||||||
#"quassel"
|
"quassel"
|
||||||
#"piped-fi"
|
"piped-fi"
|
||||||
#"mail"
|
"mail"
|
||||||
] (name: ./containers + "/${name}"))
|
] (name: ./containers + "/${name}"))
|
||||||
++ (with hosts.hetzner-vm.profiles; [
|
++ (with hosts.hetzner-arm.profiles; [
|
||||||
#vaultUI
|
gitlabStaticSites
|
||||||
#gitlabStaticSites
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# For Containers
|
# For Containers
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{pkgs, ...}: {
|
{...}: {
|
||||||
services.secrets = {
|
services.secrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
@ -9,12 +9,13 @@
|
||||||
|
|
||||||
autoSecrets = {
|
autoSecrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
#affectedSystemdServices = [
|
affectedSystemdServices = [
|
||||||
# "wg-quick-wg0"
|
"wg-quick-wg0"
|
||||||
#];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
requiredVaultPaths = [
|
requiredVaultPaths = [
|
||||||
|
"private-public-keys/data/ssh/root@hetzner-arm"
|
||||||
"private-public-keys/data/ssh/root@hetzner-arm-decrypt"
|
"private-public-keys/data/ssh/root@hetzner-arm-decrypt"
|
||||||
|
|
||||||
"api-keys/data/gitlab/gitlab_pages_serve"
|
"api-keys/data/gitlab/gitlab_pages_serve"
|
||||||
|
@ -25,11 +26,28 @@
|
||||||
manual = true;
|
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
|
# this doesn't need to be a secret and can be generated at install time
|
||||||
# but it makes it easier to install.
|
# but it makes it easier to install.
|
||||||
# it's stored in /nix store anyway
|
# it's stored in /nix store anyway
|
||||||
ssh_host_ed25519_key = {
|
initrd_ssh_host_ed25519_key = {
|
||||||
path = "/ssh_host_ed25519_key";
|
path = "/initrd_ssh_host_ed25519_key";
|
||||||
permissions = "600";
|
permissions = "600";
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
simple_get "/private-public-keys/ssh/root@hetzner-arm-decrypt" .private | base64 -d > "$secretFile"
|
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
|
presets.nixos.encryptedUSB
|
||||||
|
|
||||||
profiles.cross.arm64
|
profiles.cross.arm64
|
||||||
#profiles.remote-builders
|
profiles.remoteBuilders
|
||||||
profiles.chaosInternalWireGuard
|
profiles.chaosInternalWireGuard
|
||||||
|
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
music_stream_password = {
|
music_stream_password = {
|
||||||
user = 1000;
|
user = "chaos";
|
||||||
group = "users";
|
group = "users";
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
simple_get "/api-keys/music-stream" .password > "$secretFile"
|
simple_get "/api-keys/music-stream" .password > "$secretFile"
|
||||||
|
@ -17,8 +17,6 @@
|
||||||
# Required for home.apps.manualBackupApps
|
# Required for home.apps.manualBackupApps
|
||||||
gitlab_archiver_token = {
|
gitlab_archiver_token = {
|
||||||
user = "chaos";
|
user = "chaos";
|
||||||
group = "users";
|
|
||||||
|
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
simple_get "/api-keys/gitlab/gitlab_archiver" .token > "$secretFile"
|
simple_get "/api-keys/gitlab/gitlab_archiver" .token > "$secretFile"
|
||||||
'';
|
'';
|
||||||
|
@ -27,8 +25,6 @@
|
||||||
# Required for home.apps.manualBackupApps
|
# Required for home.apps.manualBackupApps
|
||||||
restic_music_env = {
|
restic_music_env = {
|
||||||
user = "chaos";
|
user = "chaos";
|
||||||
group = "users";
|
|
||||||
|
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
api_username=$(simple_get "/api-keys/storage/restic/Music" .username)
|
api_username=$(simple_get "/api-keys/storage/restic/Music" .username)
|
||||||
api_password=$(simple_get "/api-keys/storage/restic/Music" .password)
|
api_password=$(simple_get "/api-keys/storage/restic/Music" .password)
|
||||||
|
|
|
@ -81,16 +81,6 @@ in {
|
||||||
modules = defaultModules ++ [./hetzner-arm/hetzner-arm.nix];
|
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 {
|
vault = nixosUnstableSystem {
|
||||||
specialArgs =
|
specialArgs =
|
||||||
defaultSpecialArgs
|
defaultSpecialArgs
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
|
inherit (lib.modules) mkForce;
|
||||||
|
|
||||||
containerName = "piped-uk";
|
containerName = "piped-uk";
|
||||||
containerConfig = config.containers.${containerName}.config;
|
|
||||||
|
|
||||||
pipedSocketForComponent = (
|
pipedSocketForComponent = (
|
||||||
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
||||||
|
@ -39,11 +41,12 @@ in {
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /var/lib/cockroachdb-certs - root root"
|
"d /var/lib/cockroachdb-certs - root root"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
networking.firewall.enable = mkForce false;
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,25 +1,17 @@
|
||||||
{pkgs, ...}: {
|
{...}: {
|
||||||
services.secrets = {
|
services.secrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
packages = with pkgs; [rclone];
|
|
||||||
|
|
||||||
vaultLogin = {
|
vaultLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
loginUsername = "raspberry";
|
loginUsername = "raspberry-container-piped-uk";
|
||||||
};
|
};
|
||||||
|
|
||||||
autoSecrets = {
|
autoSecrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
affectedSystemdServices = ["wg-quick-wg0" "cockroachdb"];
|
affectedSystemdServices = ["cockroachdb"];
|
||||||
};
|
};
|
||||||
|
|
||||||
extraFunctions = ''
|
|
||||||
simple_get_obscure() {
|
|
||||||
rclone obscure "$(simple_get "$@")"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
requiredVaultPaths = [
|
requiredVaultPaths = [
|
||||||
"private-public-keys/data/piped-cockroachdb-ca/nodes/raspberry"
|
"private-public-keys/data/piped-cockroachdb-ca/nodes/raspberry"
|
||||||
];
|
];
|
||||||
|
@ -29,7 +21,7 @@
|
||||||
manual = true;
|
manual = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
piped_cockroachdb_ca_certificate = {
|
cockroachdb_ca_certificate = {
|
||||||
user = "cockroachdb";
|
user = "cockroachdb";
|
||||||
group = "cockroachdb";
|
group = "cockroachdb";
|
||||||
permissions = "600";
|
permissions = "600";
|
||||||
|
@ -42,7 +34,7 @@
|
||||||
| base64 -d > "$secretFile"
|
| base64 -d > "$secretFile"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
piped_cockroachdb_node_certificate = {
|
cockroachdb_node_certificate = {
|
||||||
user = "cockroachdb";
|
user = "cockroachdb";
|
||||||
group = "cockroachdb";
|
group = "cockroachdb";
|
||||||
permissions = "600";
|
permissions = "600";
|
||||||
|
@ -55,7 +47,7 @@
|
||||||
| base64 -d > "$secretFile"
|
| base64 -d > "$secretFile"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
piped_cockroachdb_node_key = {
|
cockroachdb_node_key = {
|
||||||
user = "cockroachdb";
|
user = "cockroachdb";
|
||||||
group = "cockroachdb";
|
group = "cockroachdb";
|
||||||
permissions = "600";
|
permissions = "600";
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
requiredVaultPaths = [
|
requiredVaultPaths = [
|
||||||
|
"/private-public-keys/data/ssh/root@vault"
|
||||||
"/private-public-keys/data/ssh/root@vault-decrypt"
|
"/private-public-keys/data/ssh/root@vault-decrypt"
|
||||||
|
|
||||||
"private-public-keys/data/restic/Vault"
|
"private-public-keys/data/restic/Vault"
|
||||||
|
@ -27,11 +28,28 @@
|
||||||
manual = true;
|
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
|
# this doesn't need to be a secret and can be generated at install time
|
||||||
# but it makes it easier to install.
|
# but it makes it easier to install.
|
||||||
# it's stored in /nix store anyway
|
# it's stored in /nix store anyway
|
||||||
ssh_host_ed25519_key = {
|
initrd_ssh_host_ed25519_key = {
|
||||||
path = "/ssh_host_ed25519_key";
|
path = "/initrd_ssh_host_ed25519_key";
|
||||||
permissions = "600";
|
permissions = "600";
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
simple_get "/private-public-keys/ssh/root@vault-decrypt" .private | base64 -d > "$secretFile"
|
simple_get "/private-public-keys/ssh/root@vault-decrypt" .private | base64 -d > "$secretFile"
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
]
|
]
|
||||||
++ (with hosts.vault.profiles; [
|
++ (with hosts.vault.profiles; [
|
||||||
vault
|
vault
|
||||||
|
vaultUI
|
||||||
restic
|
restic
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.lists) filter;
|
inherit (lib.lists) filter;
|
||||||
inherit (lib) types;
|
inherit (lib) types;
|
||||||
inherit (builtins) isString listToAttrs;
|
inherit (builtins) isString listToAttrs attrNames;
|
||||||
|
|
||||||
cfg = config.services.secrets;
|
cfg = config.services.secrets;
|
||||||
|
|
||||||
|
@ -115,25 +115,79 @@ in {
|
||||||
extraFunctions = mkOption {
|
extraFunctions = mkOption {
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
default = "";
|
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 {
|
uidMap = mkOption {
|
||||||
type = types.attrsOf types.int;
|
type = types.attrsOf types.int;
|
||||||
default = {};
|
default = listToAttrs (map (
|
||||||
description = "optional mapping of users to user IDs; required for SYSROOT when user isn't available on host";
|
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 {
|
gidMap = mkOption {
|
||||||
type = types.attrsOf types.int;
|
type = types.attrsOf types.int;
|
||||||
default = {};
|
default = listToAttrs (map (
|
||||||
description = "optional mapping of groups to group IDs; required for SYSROOT when group isn't available on host";
|
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 {
|
packages = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = [];
|
default = [];
|
||||||
description = "packages for script";
|
description = "packages for init script";
|
||||||
|
};
|
||||||
|
|
||||||
|
checkPackages = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [];
|
||||||
|
description = "packages for checkscript";
|
||||||
};
|
};
|
||||||
|
|
||||||
secrets = mkOption {
|
secrets = mkOption {
|
||||||
|
@ -241,7 +295,7 @@ in {
|
||||||
// {
|
// {
|
||||||
auto-secrets.partOf =
|
auto-secrets.partOf =
|
||||||
map (unitConfig: unitConfig.name + ".service")
|
map (unitConfig: unitConfig.name + ".service")
|
||||||
(lib.filter
|
(filter
|
||||||
(unitConfig: unitConfig.withPartOf)
|
(unitConfig: unitConfig.withPartOf)
|
||||||
affectedSystemdServices);
|
affectedSystemdServices);
|
||||||
};
|
};
|
||||||
|
|
|
@ -195,6 +195,11 @@
|
||||||
stat --format "%a" "$1" 2>/dev/null
|
stat --format "%a" "$1" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emojiTick="✅"
|
||||||
|
emojiCross="❌"
|
||||||
|
|
||||||
|
${cfg.extraCheckFunctions}
|
||||||
|
|
||||||
GLOBAL_FAIL=false
|
GLOBAL_FAIL=false
|
||||||
''
|
''
|
||||||
+ (concatStringsSep "\n" (mapAttrsToList (_name: secret: let
|
+ (concatStringsSep "\n" (mapAttrsToList (_name: secret: let
|
||||||
|
@ -226,40 +231,40 @@
|
||||||
secretFile="$SYSROOT${secretPath}"
|
secretFile="$SYSROOT${secretPath}"
|
||||||
|
|
||||||
if [[ -f "$SYSROOT${secretPath}" ]]; then
|
if [[ -f "$SYSROOT${secretPath}" ]]; then
|
||||||
echo "✅ File Exists"
|
echo "$emojiTick File Exists"
|
||||||
else
|
else
|
||||||
echo "❌ File Does Not Exist"
|
echo "$emojiCross File Does Not Exist"
|
||||||
LOCAL_FAIL=true
|
LOCAL_FAIL=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if getUserID "$SYSROOT${secretPath}" >/dev/null && ${userCheck}; then
|
if getUserID "$SYSROOT${secretPath}" >/dev/null && ${userCheck}; then
|
||||||
echo "✅ File Is Owned By Correct User"
|
echo "$emojiTick File Is Owned By Correct User"
|
||||||
else
|
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
|
LOCAL_FAIL=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if getGroupID "$SYSROOT${secretPath}" >/dev/null && ${groupCheck}; then
|
if getGroupID "$SYSROOT${secretPath}" >/dev/null && ${groupCheck}; then
|
||||||
echo "✅ File Is Owned By Correct Group"
|
echo "$emojiTick File Is Owned By Correct Group"
|
||||||
else
|
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
|
LOCAL_FAIL=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if getPermissions "$SYSROOT${secretPath}" >/dev/null && [[ "$(getPermissions "$SYSROOT${secretPath}")" -eq "${secretPermissions}" ]]; then
|
if getPermissions "$SYSROOT${secretPath}" >/dev/null && [[ "$(getPermissions "$SYSROOT${secretPath}")" -eq "${secretPermissions}" ]]; then
|
||||||
echo "✅ File Has Correct Permissions"
|
echo "$emojiTick File Has Correct Permissions"
|
||||||
else
|
else
|
||||||
echo "❌ File Does Not Have Correct Permissions (${secretPermissions})"
|
echo "$emojiCross File Does Not Have Correct Permissions (${secretPermissions})"
|
||||||
LOCAL_FAIL=true
|
LOCAL_FAIL=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${optionalString (secret.checkScript != null) secret.checkScript}
|
${optionalString (secret.checkScript != null) secret.checkScript}
|
||||||
|
|
||||||
if [[ "$LOCAL_FAIL" == "true" ]]; then
|
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
|
GLOBAL_FAIL=true
|
||||||
else
|
else
|
||||||
echo "✅ File Passed The Vibe Check"
|
echo "$emojiTick File Passed The Vibe Check"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
@ -267,10 +272,10 @@
|
||||||
cfg.secrets))
|
cfg.secrets))
|
||||||
+ ''
|
+ ''
|
||||||
if [[ "$GLOBAL_FAIL" == "true" ]]; then
|
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
|
exit 1
|
||||||
else
|
else
|
||||||
echo "✅ All Secrets Passed The Vibe Check"
|
echo "$emojiTick All Secrets Passed The Vibe Check"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -319,7 +324,7 @@ in rec {
|
||||||
scripts = genScripts cfg;
|
scripts = genScripts cfg;
|
||||||
in (writeShellApplication {
|
in (writeShellApplication {
|
||||||
name = scriptName;
|
name = scriptName;
|
||||||
runtimeInputs = defaultPackages ++ cfg.packages;
|
runtimeInputs = defaultPackages ++ cfg.checkPackages;
|
||||||
text = scripts.checkScript;
|
text = scripts.checkScript;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
25
outputs.nix
25
outputs.nix
|
@ -18,6 +18,22 @@ in
|
||||||
overlays = [
|
overlays = [
|
||||||
(import ./overlay)
|
(import ./overlay)
|
||||||
inputs.piped-flake.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"];
|
||||||
|
};
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@ -124,18 +140,15 @@ in
|
||||||
|
|
||||||
# All machines/containers with secrets.nix
|
# All machines/containers with secrets.nix
|
||||||
machines = rec {
|
machines = rec {
|
||||||
"hetzner-vm" = {
|
|
||||||
containers = ["storage" "piped-fi"];
|
|
||||||
sshAddress = "hetzner-vm.servers.genderfucked.monster";
|
|
||||||
};
|
|
||||||
"hetzner-arm" = {
|
"hetzner-arm" = {
|
||||||
containers = ["storage" "piped-fi"];
|
containers = ["storage" "music" "quassel" "social" "mail" "piped-fi"];
|
||||||
sshAddress = "hetzner-vm.servers.genderfucked.monster";
|
sshAddress = "hetzner-arm.servers.genderfucked.monster";
|
||||||
};
|
};
|
||||||
"vault" = {
|
"vault" = {
|
||||||
sshAddress = "vault.servers.genderfucked.monster";
|
sshAddress = "vault.servers.genderfucked.monster";
|
||||||
};
|
};
|
||||||
"raspberry" = {
|
"raspberry" = {
|
||||||
|
containers = ["piped-uk"];
|
||||||
sshAddress = "raspberry.servers.genderfucked.monster";
|
sshAddress = "raspberry.servers.genderfucked.monster";
|
||||||
};
|
};
|
||||||
"lappy-t495" = {};
|
"lappy-t495" = {};
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkForce;
|
inherit (lib.modules) mkForce;
|
||||||
inherit (lib.lists) optional;
|
inherit (lib.lists) optionals;
|
||||||
|
|
||||||
system = pkgs.system;
|
system = pkgs.system;
|
||||||
|
|
||||||
|
@ -33,10 +33,10 @@ in {
|
||||||
"dm_mod"
|
"dm_mod"
|
||||||
"cryptd"
|
"cryptd"
|
||||||
]
|
]
|
||||||
++ (lib.optionals (system == "x86_64_linux") ["aesni_intel"]);
|
++ (optionals (system == "x86_64_linux") ["aesni_intel"]);
|
||||||
|
|
||||||
secrets = {
|
secrets = {
|
||||||
"/ssh_host_ed25519_key" = "/ssh_host_ed25519_key";
|
"/ssh_host_ed25519_key" = mkForce "/initrd_ssh_host_ed25519_key";
|
||||||
};
|
};
|
||||||
|
|
||||||
luks = {
|
luks = {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
{
|
{
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
config,
|
||||||
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.strings) optionalString versionAtLeast;
|
inherit (lib.strings) optionalString versionAtLeast;
|
||||||
|
inherit (lib.optional);
|
||||||
in {
|
in {
|
||||||
nix = {
|
nix = {
|
||||||
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
|
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
|
||||||
|
@ -13,6 +15,7 @@ in {
|
||||||
(versionAtLeast config.nix.package.version "2.4") ''
|
(versionAtLeast config.nix.package.version "2.4") ''
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
'';
|
'';
|
||||||
|
settings.system-features = lib.optional (pkgs.system == "aarch64-linux") "native-arm64";
|
||||||
settings.trusted-users = ["root" "@wheel"];
|
settings.trusted-users = ["root" "@wheel"];
|
||||||
};
|
};
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
|
@ -30,6 +33,23 @@ in {
|
||||||
inputs.gitlab_artifacts_sync.overlays.default
|
inputs.gitlab_artifacts_sync.overlays.default
|
||||||
inputs.gitlab_archiver.overlays.default
|
inputs.gitlab_archiver.overlays.default
|
||||||
inputs.piped-flake.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;
|
environment.etc."nixpkgs-commit".text = inputs.nixpkgs-unstable.rev;
|
||||||
|
|
|
@ -12,14 +12,11 @@
|
||||||
|
|
||||||
currentHostName = config.networking.hostName;
|
currentHostName = config.networking.hostName;
|
||||||
|
|
||||||
joinString = lib.concatStringsSep "," ([
|
joinString = lib.concatStringsSep "," (
|
||||||
"localhost:${toString ports.cockroachDB}"
|
map
|
||||||
]
|
(hostName: hosts.${hostName}.joinString)
|
||||||
++ (
|
(filter (hostName: hostName != currentHostName) (attrNames hosts))
|
||||||
map
|
);
|
||||||
(hostName: hosts.${hostName}.joinString)
|
|
||||||
(filter (hostName: hostName != currentHostName) (attrNames hosts))
|
|
||||||
));
|
|
||||||
in {
|
in {
|
||||||
systemd.services.haproxy.wantedBy = ["piped-backend.service"];
|
systemd.services.haproxy.wantedBy = ["piped-backend.service"];
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
{
|
{
|
||||||
|
self,
|
||||||
pkgs,
|
pkgs,
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = config.services.secrets.secrets;
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
|
clusterConfig = import "${self}/data/piped/pipedClusterConfig.nix";
|
||||||
|
|
||||||
|
currentHostConfig = clusterConfig.hosts.${config.networking.hostName};
|
||||||
|
inherit (currentHostConfig) resticName resticBucket;
|
||||||
in {
|
in {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
restic
|
restic
|
||||||
(pkgs.writeShellScriptBin "restic-piped-finland" ''
|
(pkgs.writeShellScriptBin "restic-${resticName}" ''
|
||||||
env \
|
env \
|
||||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
$(cat ${secrets.restic_env.path}) \
|
$(cat ${secrets.restic_env.path}) \
|
||||||
|
@ -15,14 +21,14 @@ in {
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
services.restic.backups.piped-finland = {
|
services.restic.backups.${resticName} = {
|
||||||
user = "root";
|
user = "root";
|
||||||
paths = [
|
paths = [
|
||||||
"/var/lib/cockroachdb"
|
"/var/lib/cockroachdb"
|
||||||
"/var/lib/cockroachdb-certs"
|
"/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}";
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
environmentFile = "${secrets.restic_env.path}";
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkIf;
|
inherit (lib.modules) mkIf mkMerge;
|
||||||
|
|
||||||
currentHostname = config.networking.hostName;
|
currentHostname = config.networking.hostName;
|
||||||
|
|
||||||
|
@ -26,22 +26,28 @@
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
nix.buildMachines = [
|
nix.buildMachines = [
|
||||||
(mkIf (currentHostname != "hetzner-vm") (builderDefaults
|
(mkIf (currentHostname != "hetzner-arm") (mkMerge [
|
||||||
// {
|
builderDefaults
|
||||||
hostName = "hetzner-vm.servers.genderfucked.monster";
|
{
|
||||||
systems = ["x86_64-linux" "aarch64-linux"];
|
hostName = "hetzner-arm.servers.genderfucked.monster";
|
||||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU1JdDJBQnF3SGhNano5cjZhdHY0WHVYNTh4RVdlU3RrbVhVd3ZNVkd2NHcgcm9vdEBuaXhvcwo=";
|
systems = ["aarch64-linux"];
|
||||||
maxJobs = 3;
|
supportedFeatures = ["native-arm64"];
|
||||||
speedFactor = 2;
|
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUk5cGM0REU1UlV4UUp2T1pwenFOQWVac0JlRW1kcmp4OFlnV3orVXBMckcgcm9vdEBoZXR6bmVyLWFybQo=";
|
||||||
}))
|
maxJobs = 4;
|
||||||
(mkIf (currentHostname != "vault") (builderDefaults
|
speedFactor = 3;
|
||||||
// {
|
}
|
||||||
|
]))
|
||||||
|
(mkIf (currentHostname != "vault") (mkMerge [
|
||||||
|
builderDefaults
|
||||||
|
{
|
||||||
hostName = "vault.servers.genderfucked.monster";
|
hostName = "vault.servers.genderfucked.monster";
|
||||||
systems = ["x86_64-linux"];
|
systems = ["aarch64-linux"];
|
||||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU16L1dyaG81MTFGdzhXN3FsU0NUY1V4cWh4TGlBQkJXbFNNNFRNNzJ5RWQgcm9vdEBuaXhvcwo=";
|
supportedFeatures = ["native-arm64"];
|
||||||
maxJobs = 2;
|
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSURGTlFjUTdkbUlRS1lqMUVVTFBlcTI4d2hzMTg2YVZ0WitWU05rd3I2aEkgcm9vdEB2YXVsdAo=";
|
||||||
|
maxJobs = 1;
|
||||||
speedFactor = 1;
|
speedFactor = 1;
|
||||||
}))
|
}
|
||||||
|
]))
|
||||||
];
|
];
|
||||||
nix.distributedBuilds = true;
|
nix.distributedBuilds = true;
|
||||||
nix.extraOptions = "builders-use-substitutes = 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 $SCRIPT_DIR
|
||||||
cd $(git rev-parse --show-toplevel)
|
cd $(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
[ -n "$NO_BUILD_PIPED_BACKEND" ] && ./scripts/buildPipedBackendAArch64.nix
|
DEFAULT_HOST="root@raspberry.servers.genderfucked.monster"
|
||||||
nixos-rebuild switch --flake .#raspberry --target-host raspberry -s "$@"
|
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 $SCRIPT_DIR
|
||||||
cd $(git rev-parse --show-toplevel)
|
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)
|
HOSTNAME=$(hostname)
|
||||||
|
|
||||||
[ "${NO_REBUILD}" == "" ] && ./scripts/rebuild.sh "$@"
|
[ "${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}" != "vault" ] && ./scripts/deploy/vault.sh "$@"
|
||||||
[ "${HOSTNAME}" != "raspberry" ] && ./scripts/deploy/raspberry.sh "$@"
|
[ "${HOSTNAME}" != "raspberry" ] && ./scripts/deploy/raspberry.sh "$@"
|
Loading…
Reference in a new issue