wireguard for raspberry, outputs.nix tidy, enable generating of vault policies

This commit is contained in:
chaos 2023-09-14 13:54:56 +01:00
parent cd961b33be
commit ed7e0c4db5
No known key found for this signature in database
13 changed files with 284 additions and 105 deletions

View file

@ -20,5 +20,9 @@
ip = "10.69.42.4";
public = "rEioKieZqI3UaJGGaSC/yaHfdZE9VKpsq355x4dHgCs=";
};
raspberry = {
ip = "10.69.42.5";
public = "IGq+WanFM/bKNUkwjO/0AAtDhJLvtvU+mVxH27QyHTc=";
};
};
}

View file

@ -41,11 +41,7 @@ in {
};
}));
config = {
config,
pkgs,
...
}: {
config = {config, ...}: {
_module.args = {
inherit inputs;
inherit tree;

View file

@ -21,6 +21,7 @@
]
++ (lib.forEach [
"social"
"storage"
"music"
"quassel"
"piped"

View file

@ -28,6 +28,12 @@ in {
presharedKeyFile = "${secrets.wg_preshared_lappy-t495.path}";
allowedIPs = ["${data.hosts.lappy-t495.ip}/32"];
}
# raspberry
{
publicKey = "${data.hosts.raspberry.public}";
presharedKeyFile = "${secrets.wg_preshared_raspberry.path}";
allowedIPs = ["${data.hosts.raspberry.ip}/32"];
}
];
};
};

View file

@ -32,6 +32,33 @@ in {
"${group}" = getGID group;
}));
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/storage/restic/Piped"
"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/wireguard/chaos-internal/hetzner-vm"
"private-public-keys/data/restic/Mail"
"private-public-keys/data/restic/Social"
"private-public-keys/data/restic/Quassel"
"private-public-keys/data/restic/Piped"
"infra/data/private-mail-aliases"
];
secrets = {
# Used directly by server
# for fetching gitlab static sites
@ -50,23 +77,25 @@ in {
'';
};
wg_preshared_vault = {
path = "/secrets/wg_preshared_vault";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .preshared_keys.vault > "$secretFile"
'';
};
wg_preshared_iphone8 = {
path = "/secrets/wg_preshared_iphone8";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .preshared_keys.iphone8 > "$secretFile"
'';
};
wg_preshared_lappy-t495 = {
path = "/secrets/wg_preshared_lappy-t495";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" ".preshared_keys.lappy_t495" > "$secretFile"
'';
};
wg_preshared_raspberry = {
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" ".preshared_keys.raspberry" > "$secretFile"
'';
};
# Container: music
mpd_control_password = {
@ -109,8 +138,6 @@ in {
'';
};
private_mail_aliases = {
user = "root";
group = "root";
fetchScript = ''
kv_get "/infra/private-mail-aliases" | jq .data.data | jq -r 'to_entries|map("\(.key) \(.value.to)")[]' > "$secretFile"
'';
@ -154,8 +181,6 @@ in {
'';
};
social_env_secrets = {
user = "root";
group = "root";
fetchScript = ''
smtp_password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
echo "GTS_SMTP_PASSWORD=$smtp_password" > "$secretFile"

View file

@ -14,7 +14,7 @@ in {
{
publicKey = "${data.hosts.hetzner-vm.public}";
presharedKeyFile = "${secrets.wg_preshared_hetzner-vm.path}";
allowedIPs = ["${data.hosts.hetzner-vm.ip}/32"];
allowedIPs = ["${data.hosts.hetzner-vm.ip}/24"];
endpoint = "${data.hosts.hetzner-vm.endpoint}";
persistentKeepalive = 25;
}

View file

@ -0,0 +1,33 @@
{config, ...}: let
secrets = config.services.secrets.secrets;
data = import ../../../data/chaos_wireguard_internal.nix {};
persistentKeepalive = 15;
in {
networking.firewall.trustedInterfaces = ["wg0"];
networking.wg-quick.interfaces = {
wg0 = {
address = ["${data.hosts.raspberry.ip}/32"];
privateKeyFile = "${secrets.wg_priv.path}";
peers = [
# hetzner-vm
{
publicKey = "${data.hosts.hetzner-vm.public}";
presharedKeyFile = "${secrets.wg_preshared_hetzner-vm.path}";
allowedIPs = ["${data.hosts.hetzner-vm.ip}/24"];
endpoint = "${data.hosts.hetzner-vm.endpoint}";
inherit persistentKeepalive;
}
# vault
{
publicKey = "${data.hosts.vault.public}";
presharedKeyFile = "${secrets.wg_preshared_vault.path}";
allowedIPs = ["${data.hosts.vault.ip}/32"];
endpoint = "${data.hosts.vault.endpoint}";
inherit persistentKeepalive;
}
];
};
};
}

View file

@ -30,6 +30,23 @@
sed -i "s/WIFI_PASSWORD/$password/" "$secretFile"
'';
};
# for internal wireguard VPN
wg_priv = {
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/raspberry" .private > "$secretFile"
'';
};
wg_preshared_hetzner-vm = {
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/raspberry" .preshared_keys.hetzner_vm > "$secretFile"
'';
};
wg_preshared_vault = {
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/raspberry" .preshared_keys.vault > "$secretFile"
'';
};
};
};
}

View file

@ -29,6 +29,12 @@ in {
presharedKeyFile = "${secrets.wg_preshared_lappy-t495.path}";
allowedIPs = ["${data.hosts.lappy-t495.ip}/32"];
}
# raspberry
{
publicKey = "${data.hosts.raspberry.public}";
presharedKeyFile = "${secrets.wg_preshared_raspberry.path}";
allowedIPs = ["${data.hosts.raspberry.ip}/32"];
}
];
};
};

View file

@ -1,6 +1,15 @@
{...}: {
services.secrets = {
enable = true;
requiredVaultPaths = [
"private-public-keys/data/wireguard/chaos-internal/vault"
"private-public-keys/data/restic/Vault"
"api-keys/data/storage/restic/Vault"
];
secrets = {
restic_password = {
fetchScript = ''
@ -34,6 +43,11 @@
simple_get "/private-public-keys/wireguard/chaos-internal/vault" ".preshared_keys.lappy_t495" > "$secretFile"
'';
};
wg_preshared_raspberry = {
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/vault" ".preshared_keys.raspberry" > "$secretFile"
'';
};
};
};
}

View file

@ -7,7 +7,7 @@
inherit (lib.lists) forEach unique flatten;
inherit (lib.strings) concatStringsSep optionalString;
inherit (lib.attrsets) mapAttrsToList filterAttrs;
inherit (pkgs) writeShellApplication;
inherit (pkgs) writeShellApplication writeText;
genScripts = cfg: let
scriptBase = ''
@ -288,4 +288,29 @@ in {
text = scripts.initScript;
})
);
genVaultPolicy = (
cfg: name: let
inherit (cfg) requiredVaultPaths;
policies = forEach requiredVaultPaths (policyConfig: let
path =
if isString policyConfig
then policyConfig
else policyConfig.path;
capabilities =
if isString policyConfig
then ["read" "list"]
else policyConfig.capabilities;
escapeString = str: "\"" + str + "\"";
in ''
path "${path}" {
capabilities = [${concatStringsSep "," (forEach capabilities escapeString)}]
}
'');
in (writeText "vault-policy-${name}.hcl" ''
${concatStringsSep "\n" policies}
'')
);
}

View file

@ -47,6 +47,25 @@ in {
default = "/secrets";
};
requiredVaultPaths = mkOption {
type = types.listOf (types.oneOf [
types.str
(types.submodule {
options = {
path = mkOption {
type = types.str;
};
capabilities = mkOption {
type = types.listOf types.str;
default = ["read" "list"];
};
};
})
]);
default = [];
description = "default vault paths as API path, not kv2 path";
};
vaultURL = mkOption {
type = types.str;
default = "https://vault.owo.monster";

View file

@ -2,6 +2,8 @@
nixpkgs = inputs.nixpkgs-unstable;
lib = nixpkgs.lib;
inherit (lib.attrsets) mergeAttrsList;
hosts = import ./hosts inputs;
in
{
@ -13,100 +15,131 @@ in
deploy-rs = inputs.deploy-rs;
};
}
// (inputs.flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {
inherit system;
overlays = [
(import ./overlay)
];
};
secretsLib = import ./modules/nixos/secrets-lib/lib.nix {
inherit (nixpkgs) lib;
inherit pkgs;
};
secretsInitScriptForSystem = system_name: let
systemConfig = self.nixosConfigurations.${system_name}.config;
systemSecretsConfig = systemConfig.services.secrets;
// (inputs.flake-utils.lib.eachDefaultSystem (
system: let
pkgs = import nixpkgs {
inherit system;
overlays = [
(import ./overlay)
];
};
in
secretsLib.mkSecretsInitScript systemSecretsConfig "${system_name}";
lib.foldl' lib.recursiveUpdate {} [
{
formatter = pkgs.alejandra;
secretsInitScriptForSystemContainer = system_name: container_name: let
systemConfig = self.nixosConfigurations.${system_name}.config;
containerConfig = systemConfig.containers.${container_name}.config;
containerSecretsConfig = containerConfig.services.secrets;
in
secretsLib.mkSecretsInitScript containerSecretsConfig "${system_name}-${container_name}";
devShell = pkgs.mkShell {
VAULT_API_ADDR = "https://vault.owo.monster";
packages =
(with pkgs; [
git
nano
bat
nix
vault-bin
])
++ (with self.packages."${system}"; [
mk-enc-usb
mk-normal-enc-ssd
mk-dual-enc-ssd
mk-raspberry-ext-drive
]);
};
secretsInitAppForSystem = system_name: packages: let
name = "secrets-init-${system_name}";
package = packages."${name}";
in {
type = "app";
program = "${package}/bin/${name}";
};
packages = {
inherit (pkgs) comic-code comic-sans;
inherit (pkgs) mk-enc-usb mk-normal-enc-ssd mk-dual-enc-ssd mk-raspberry-ext-drive;
inherit (pkgs) gotosocial;
};
}
secretsInitAppForSystemContainer = system_name: container_name: packages: let
name = "secrets-init-${system_name}-${container_name}";
package = packages."${name}";
in {
type = "app";
program = "${package}/bin/${name}";
};
in {
devShell = pkgs.mkShell {
VAULT_API_ADDR = "https://vault.owo.monster";
packages =
(with pkgs; [
git
nano
bat
nix
vault-bin
])
++ (with self.packages."${system}"; [
mk-enc-usb
mk-normal-enc-ssd
mk-dual-enc-ssd
mk-raspberry-ext-drive
]);
};
# secrets-init, secrets-check and vault-policy for machines and containers
(let
secretsLib = import ./modules/nixos/secrets-lib/lib.nix {
inherit (nixpkgs) lib;
inherit pkgs;
};
apps = let
packages = self.packages."${system}";
in {
mk-enc-usb = {
type = "app";
program = "${packages.mk-enc-usb}/bin/mk-enc-usb";
};
mk-normal-enc-ssd = {
type = "app";
program = "${packages.mk-normal-enc-ssd}/bin/mk-normal-enc-ssd";
};
mk-dual-enc-ssd = {
type = "app";
program = "${packages.mk-dual-enc-ssd}/bin/mk-dual-enc-ssd";
};
mk-raspberry-ext-drive = {
type = "app";
program = "${packages.mk-raspberry-ext-drive}/bin/mk-raspberry-ext-drive";
};
secrets-init-lappy-t495 = secretsInitAppForSystem "lappy-t495" packages;
secrets-init-vault = secretsInitAppForSystem "vault" packages;
secrets-init-hetzner-vm = secretsInitAppForSystem "hetzner-vm" packages;
secrets-init-hetzner-vm-storage = secretsInitAppForSystemContainer "hetzner-vm" "storage" packages;
secrets-init-raspberry = secretsInitAppForSystem "raspberry" packages;
};
systemConfigForSystem = system_name: self.nixosConfigurations.${system_name}.config;
secretsConfigForSystem = system_name: let
systemConfig = systemConfigForSystem system_name;
in
systemConfig.services.secrets;
packages = {
inherit (pkgs) comic-code comic-sans;
inherit (pkgs) mk-enc-usb mk-normal-enc-ssd mk-dual-enc-ssd;
inherit (pkgs) gotosocial;
secrets-init-lappy-t495 = secretsInitScriptForSystem "lappy-t495";
secrets-init-vault = secretsInitScriptForSystem "vault";
secrets-init-hetzner-vm = secretsInitScriptForSystem "hetzner-vm";
secrets-init-hetzner-vm-storage = secretsInitScriptForSystemContainer "hetzner-vm" "storage";
secrets-init-raspberry = secretsInitScriptForSystem "raspberry";
};
}))
systemConfigForContainer = system_name: container_name: let
systemConfig = systemConfigForSystem system_name;
in
systemConfig.containers.${container_name}.config;
secretsConfigForContainer = system_name: container_name: let
systemConfig = systemConfigForContainer system_name container_name;
in
systemConfig.services.secrets;
secretsInitScriptForSystem = system_name: let
secretsConfig = secretsConfigForSystem system_name;
in
secretsLib.mkSecretsInitScript secretsConfig "${system_name}";
secretsInitScriptForContainer = system_name: container_name: let
secretsConfig = secretsConfigForContainer system_name container_name;
in
secretsLib.mkSecretsInitScript secretsConfig "${system_name}-container-${container_name}";
vaultPolicyForSystem = system_name: let
secretsConfig = secretsConfigForSystem system_name;
in
secretsLib.genVaultPolicy secretsConfig "${system_name}";
vaultPolicyForContainer = system_name: container_name: let
secretsConfig = secretsConfigForContainer system_name container_name;
in
secretsLib.genVaultPolicy secretsConfig "${system_name}-container-${container_name}";
# All machines/containers with secrets.nix
machines = let
defaults = {
hasHostSecrets = true;
containers = [];
};
in {
"hetzner-vm" = {
inherit (defaults) hasHostSecrets;
containers = ["storage"];
};
"vault" = {
inherit (defaults) hasHostSecrets containers;
};
"raspberry" = {
inherit (defaults) hasHostSecrets containers;
};
"lappy-t495" = {
inherit (defaults) hasHostSecrets containers;
};
"tablet" = {
inherit (defaults) hasHostSecrets containers;
};
};
machinesWithHostSecrets = lib.filter (machine: machines.${machine}.hasHostSecrets) (builtins.attrNames machines);
machinesWithContainers = lib.filter (machine: (builtins.length machines.${machine}.containers) != 0) (builtins.attrNames machines);
in {
packages = mergeAttrsList [
(mergeAttrsList (
lib.forEach machinesWithHostSecrets (machine_name: {
"secrets-init-${machine_name}" = secretsInitScriptForSystem machine_name;
"vault-policy-${machine_name}" = vaultPolicyForSystem machine_name;
})
))
(mergeAttrsList (lib.forEach machinesWithContainers (machine_name: let
machine = machines.${machine_name};
containers = machine.containers;
in (mergeAttrsList (lib.forEach containers (container_name: {
"secrets-init-${machine_name}-container-${container_name}" = secretsInitScriptForContainer machine_name container_name;
"vault-policy-${machine_name}-container-${container_name}" = vaultPolicyForContainer machine_name container_name;
}))))))
];
})
]
))