attempt moving vault to hetzner-arm
This commit is contained in:
parent
7c8e57d416
commit
3ba2086d8a
68
hosts/hetzner-arm/containers/vault-ca/default.nix
Normal file
68
hosts/hetzner-arm/containers/vault-ca/default.nix
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
self,
|
||||||
|
hostPath,
|
||||||
|
tree,
|
||||||
|
inputs,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||||
|
hostIP = containerAddresses.host;
|
||||||
|
containerIP = containerAddresses.containers.vault-ca;
|
||||||
|
in {
|
||||||
|
containers.vault-ca = {
|
||||||
|
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
|
||||||
|
./secrets.nix
|
||||||
|
]
|
||||||
|
++ (with hosts.hetzner-arm.containers.vault-ca.profiles; [
|
||||||
|
vault
|
||||||
|
#internalCA
|
||||||
|
restic
|
||||||
|
]);
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [8200 8443];
|
||||||
|
|
||||||
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
|
system.stateVersion = "23.05";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."vault.owo.monster" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
locations = {
|
||||||
|
"/".proxyPass = "http://${containerIP}:8200";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: redo this
|
||||||
|
#security.acme.certs."vault.genderfucked.monster" = {
|
||||||
|
# server = "https://internal-ca.genderfucked.monster:8443/acme/acme/directory";
|
||||||
|
#};
|
||||||
|
|
||||||
|
#services.nginx.virtualHosts."vault.genderfucked.monster" = {
|
||||||
|
# forceSSL = true;
|
||||||
|
# enableACME = true;
|
||||||
|
# locations = {
|
||||||
|
# "/".proxyPass = "http://${containerIP}:8200";
|
||||||
|
# };
|
||||||
|
#};
|
||||||
|
}
|
|
@ -4,9 +4,19 @@
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (config.services.secrets) secrets;
|
|
||||||
backupSchedules = import "${self}/data/backupSchedules.nix";
|
backupSchedules = import "${self}/data/backupSchedules.nix";
|
||||||
|
inherit (config.services.secrets) secrets;
|
||||||
in {
|
in {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
restic
|
||||||
|
(pkgs.writeShellScriptBin "restic-vault" ''
|
||||||
|
env \
|
||||||
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
|
$(cat ${secrets.restic_env.path}) \
|
||||||
|
${pkgs.restic}/bin/restic $@
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
services.restic.backups.vault = {
|
services.restic.backups.vault = {
|
||||||
user = "root";
|
user = "root";
|
||||||
paths = [
|
paths = [
|
||||||
|
@ -15,18 +25,10 @@ in {
|
||||||
];
|
];
|
||||||
timerConfig = backupSchedules.restic.high;
|
timerConfig = backupSchedules.restic.high;
|
||||||
|
|
||||||
# env contains fixed repository with auth
|
# 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/Vault";
|
repository = "rest:https://storage-restic.owo.monster/Vault";
|
||||||
passwordFile = "${secrets.restic_password.path}";
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
environmentFile = "${secrets.restic_env.path}";
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = [
|
|
||||||
(pkgs.writeShellScriptBin "restic-vault" ''
|
|
||||||
env \
|
|
||||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
|
||||||
$(cat ${secrets.restic_env.path}) \
|
|
||||||
${pkgs.restic}/bin/restic $@
|
|
||||||
'')
|
|
||||||
];
|
|
||||||
}
|
}
|
11
hosts/hetzner-arm/containers/vault-ca/profiles/vault.nix
Normal file
11
hosts/hetzner-arm/containers/vault-ca/profiles/vault.nix
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{pkgs, ...}: {
|
||||||
|
services.vault = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.vault-bin;
|
||||||
|
address = "0.0.0.0:8200";
|
||||||
|
storageBackend = "file";
|
||||||
|
extraConfig = ''
|
||||||
|
ui = true
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
51
hosts/hetzner-arm/containers/vault-ca/secrets.nix
Normal file
51
hosts/hetzner-arm/containers/vault-ca/secrets.nix
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{pkgs, ...}: {
|
||||||
|
services.secrets = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
packages = with pkgs; [
|
||||||
|
apacheHttpd
|
||||||
|
];
|
||||||
|
|
||||||
|
vaultLogin = {
|
||||||
|
enable = true;
|
||||||
|
# TODO: change to hetzner-arm-container-vault-ca
|
||||||
|
loginUsername = "vault";
|
||||||
|
};
|
||||||
|
|
||||||
|
autoSecrets = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
requiredVaultPaths = [
|
||||||
|
"private-public-keys/data/restic/Vault"
|
||||||
|
|
||||||
|
"api-keys/data/storage/restic/Vault"
|
||||||
|
|
||||||
|
"infra/data/internalCAPassword"
|
||||||
|
];
|
||||||
|
|
||||||
|
secrets = {
|
||||||
|
vault_password = {
|
||||||
|
manual = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
restic_password = {
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/restic/Vault" .password > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
restic_env = {
|
||||||
|
fetchScript = ''
|
||||||
|
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Vault" .restic)
|
||||||
|
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Vault" > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
internal_ca_password = {
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/infra/internalCAPassword" .password > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,6 +3,12 @@
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
services.vaultui = {
|
||||||
|
enable = true;
|
||||||
|
package = inputs.vaultui.packages.${pkgs.system}.vaultui;
|
||||||
|
domain = "vaultui.owo.monster";
|
||||||
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."thisisanexampleofspeex.uk" = {
|
services.nginx.virtualHosts."thisisanexampleofspeex.uk" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
{...}: {
|
|
||||||
boot.loader = {
|
|
||||||
systemd-boot.enable = true;
|
|
||||||
efi.canTouchEfiVariables = true;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
{pkgs, ...}: {
|
|
||||||
services.vault = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.vault-bin;
|
|
||||||
address = "127.0.0.1:8200";
|
|
||||||
storageBackend = "file";
|
|
||||||
extraConfig = ''
|
|
||||||
ui = true
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."vault.owo.monster" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = {
|
|
||||||
"/".proxyPass = "http://127.0.0.1:8200";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
security.acme.certs."vault.genderfucked.monster" = {
|
|
||||||
server = "https://internal-ca.genderfucked.monster:8443/acme/acme/directory";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."vault.genderfucked.monster" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = {
|
|
||||||
"/".proxyPass = "http://127.0.0.1:8200";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
inputs,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
services.vaultui = {
|
|
||||||
enable = true;
|
|
||||||
package = inputs.vaultui.packages.${pkgs.system}.vaultui;
|
|
||||||
domain = "vaultui.owo.monster";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
{...}: {
|
|
||||||
services.secrets = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
vaultURL = "http://127.0.0.1:8200";
|
|
||||||
|
|
||||||
vaultLogin = {
|
|
||||||
enable = true;
|
|
||||||
loginUsername = "vault";
|
|
||||||
};
|
|
||||||
|
|
||||||
autoSecrets = {
|
|
||||||
# won't work when sealed
|
|
||||||
enable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
requiredVaultPaths = [
|
|
||||||
"private-public-keys/data/ssh/root@vault"
|
|
||||||
"private-public-keys/data/ssh/root@vault-decrypt"
|
|
||||||
|
|
||||||
"private-public-keys/data/restic/Vault"
|
|
||||||
|
|
||||||
"api-keys/data/storage/restic/Vault"
|
|
||||||
|
|
||||||
"infra/data/internalCAPassword"
|
|
||||||
];
|
|
||||||
|
|
||||||
secrets = {
|
|
||||||
vault_password = {
|
|
||||||
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
|
|
||||||
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"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
restic_password = {
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/private-public-keys/restic/Vault" .password > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
restic_env = {
|
|
||||||
fetchScript = ''
|
|
||||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Vault" .restic)
|
|
||||||
echo "RESTIC_REPOSITORY=rest:https://restic:$RESTIC_PASSWORD@storage-restic.owo.monster/Vault" > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
internal_ca_password = {
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/infra/internalCAPassword" .password > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
{tree, ...}: {
|
|
||||||
imports = with tree;
|
|
||||||
[
|
|
||||||
presets.nixos.serverBase
|
|
||||||
presets.nixos.serverHetzner
|
|
||||||
presets.nixos.serverEncryptedDrive
|
|
||||||
|
|
||||||
profiles.nginx
|
|
||||||
profiles.firewallAllow.httpCommon
|
|
||||||
profiles.chaosInternalWireGuard
|
|
||||||
|
|
||||||
./secrets.nix
|
|
||||||
./hardware.nix
|
|
||||||
]
|
|
||||||
++ (with hosts.vault.profiles; [
|
|
||||||
vault
|
|
||||||
vaultUI
|
|
||||||
restic
|
|
||||||
internalCA
|
|
||||||
]);
|
|
||||||
|
|
||||||
networking.hostName = "vault";
|
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
|
||||||
system.stateVersion = "23.05";
|
|
||||||
}
|
|
Loading…
Reference in a new issue