1
1
Fork 1
mirror of https://github.com/oddlama/nix-config.git synced 2025-10-10 23:00:39 +02:00

feat: experiment with kanidm and acme dns-01. add common conditional locations to impermanence

This commit is contained in:
oddlama 2023-05-25 01:57:16 +02:00
parent 668f9fdaf4
commit 0e3d881887
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
24 changed files with 323 additions and 29 deletions

View file

@ -93,7 +93,7 @@ then select the host in the fzf menu
## Stuff
- Secrets can be created/edited by running `nix run .#edit-secret some/secret.age`
- Secrets can be rekeyed by running `nix run .#rekey` (you will be prompted to do so in an error message if neccessary)
- Secrets can be rekeyed by running `nix run .#rekey` (you will also be prompted to do so in an error message if neccessary)
To be able to decrypt the repository-wide secrets transparently on a host that
is _not_ managed by this config, you will need to <sub>(be me and)</sub> run
@ -110,10 +110,10 @@ all commands using these extra parameters, or permanently add the following the
## Misc
Generate self-signed cert:
Generate self-signed cert, e.g. for kanidm internal communication to proxy:
```bash
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout zackbiene-selfcert.key -out zackbiene-selfcert.crt -subj \
-keyout selfcert.key -out selfcert.crt -subj \
"/CN=example.com" -addext "subjectAltName=DNS:example.com,DNS:sub1.example.com,DNS:sub2.example.com,IP:10.0.0.1"
```

View file

@ -1,4 +1,8 @@
{
config,
lib,
...
}: {
# State that should be kept across reboots, but is otherwise
# NOT important information in any way that needs to be backed up.
#environment.persistence."/nix/state" = {
@ -20,10 +24,90 @@
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
];
directories = [
"/var/lib/nixos"
"/var/lib/systemd/coredump"
"/var/log"
];
directories =
[
{
directory = "/var/lib/nixos";
user = "root";
group = "root";
mode = "0755";
}
{
directory = "/var/lib/systemd";
user = "root";
group = "root";
mode = "0755";
}
{
directory = "/var/log";
user = "root";
group = "root";
mode = "0755";
}
#{ directory = "/tmp"; user = "root"; group = "root"; mode = "1777"; }
#{ directory = "/var/tmp"; user = "root"; group = "root"; mode = "1777"; }
{
directory = "/var/spool";
user = "root";
group = "root";
mode = "0777";
}
]
++ lib.optionals config.networking.wireless.iwd.enable [
{
directory = "/var/lib/iwd";
user = "root";
group = "root";
mode = "0700";
}
]
++ lib.optionals (config.services.kea.dhcp4.enable || config.services.kea.dhcp6.enable) [
{
directory = "/var/lib/kea";
user = "kea";
group = "kea";
mode = "0755";
}
]
++ lib.optionals config.services.gitea.enable [
{
directory = "/var/lib/gitea";
user = "gitea";
group = "gitea";
mode = "0755";
}
]
++ lib.optionals config.security.acme.acceptTerms [
{
directory = "/var/lib/acme";
user = "acme";
group = "acme";
mode = "0755";
}
]
++ lib.optionals config.services.printing.enable [
{
directory = "/var/lib/cups";
user = "root";
group = "root";
mode = "0755";
}
]
++ lib.optionals config.services.fail2ban.enable [
{
directory = "/var/lib/fail2ban";
user = "fail2ban";
group = "fail2ban";
mode = "0750";
}
]
++ lib.optionals config.services.opendkim.enable [
{
directory = "/var/lib/postgresql";
user = "postgres";
group = "postgres";
mode = "0755";
}
];
};
}

View file

@ -2,6 +2,7 @@ let
# IP addresses: ${"${interface} \e{halfbright}\4{${interface}}\e{reset} \e{halfbright}\6{${interface}}\e{reset}"}
issue_text = ''
\d \t
\e{halfbright}\4\e{reset} \e{halfbright}\6\e{reset}
This is \e{cyan}\n\e{reset} [\e{lightblue}\l\e{reset}] (\s \m \r)
'';

View file

@ -3,7 +3,19 @@
nixos-hardware,
pkgs,
...
}: {
}: let
# TODO byebyebye
# TODO byebyebye
# TODO byebyebye
# TODO byebyebye
# TODO byebyebye
# TODO byebyebye
# TODO byebyebye
# TODO byebyebye
# TODO byebyebye
inherit (config.repo.secrets.local) acme;
auth.domain = config.repo.secrets.local.auth.domain;
in {
imports = [
nixos-hardware.common-cpu-intel
nixos-hardware.common-pc-ssd
@ -33,15 +45,26 @@
};
in {
test = defineVm 11;
#nginx = defineVm 12;
#ddclient = defineVm 11;
nginx = defineVm 12;
#kanidm = defineVm 13;
#gitea = defineVm 14;
#vaultwarden = defineVm 15;
#samba = defineVm 16;
#samba+wsdd = defineVm 16;
#fasten-health = defineVm 17;
#immich = defineVm 18;
#paperless = defineVm 19;
#radicale = defineVm 20;
#minecraft = defineVm 21;
#grafana
#loki
#maddy = defineVm 19;
#anonaddy = defineVm 19;
#automatic1111 = defineVm 19;
#invokeai = defineVm 19;
#kanidm = defineVm 12 // {
# configPath = ./vm-test.nix;
@ -51,4 +74,162 @@
microvm.vms.test.config = {
rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBXXjI6uB26xOF0DPy/QyLladoGIKfAtofyqPgIkCH/g";
};
microvm.vms.nginx.config = {
lib,
config,
parentNodeName,
...
}: {
rekey.hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN2TxWynLb8V9SP45kFqsoCWhe/dG8N1xWNuJG5VQndq";
rekey.secrets."kanidm-self-signed.crt" = {
file = ./secrets/kanidm-self-signed.crt.age;
mode = "440";
owner = "nginx";
group = "kanidm";
};
rekey.secrets."kanidm-self-signed.key" = {
file = ./secrets/kanidm-self-signed.key.age;
mode = "440";
owner = "nginx";
group = "kanidm";
};
rekey.secrets."dhparams.pem" = {
# TODO make own?
file = ../zackbiene/secrets/dhparams.pem.age;
mode = "440";
group = "nginx";
};
networking.hosts = {
"192.168.100.12" = [auth.domain];
};
rekey.secrets.acme-credentials = {
file = ./secrets/acme-credentials.age;
mode = "440";
group = "acme";
};
security.acme = {
acceptTerms = true;
defaults = {
inherit (acme) email;
dnsProvider = "cloudflare";
credentialsFile = config.rekey.secrets.acme-credentials.path;
dnsPropagationCheck = true;
};
certs = lib.genAttrs acme.domains (domain: {
extraDomainNames = ["*.${domain}"];
});
};
users.groups.acme.members = ["nginx"];
# TODO needed in my current testing network that has no ipv6 connectivity
# TODO but these should use fallback......... something's wrong
systemd.network.networks."10-wan".networkConfig.DNS = ["1.1.1.1" "8.8.8.8"];
# TODO reload nginx when acme is renewed
# TODO make default nginx config in core to reduce boilerplate?
services.nginx = let
# TODO not implemented well
# TODO not implemented well
# TODO not implemented well
# TODO not implemented well
# TODO not implemented well
# TODO not implemented well
# TODO not implemented well
# TODO not implemented well
# TODO (acme.domains is very specific)
# TODO (security.acme causes recursion)
matchingWildcardCert = domain: let
# Filter all certs that are wildcard certs and which match the given domain
matchingCerts =
lib.filter
(x: !lib.hasInfix "." (lib.removeSuffix ".${x}" domain))
acme.domains;
in
assert lib.assertMsg (matchingCerts != []) "No wildcard certificate was defined that matches ${domain}";
lib.head matchingCerts;
in {
enable = true;
recommendedBrotliSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
# SSL config
sslCiphers = "EECDH+AESGCM:EDH+AESGCM:!aNULL";
sslDhparam = config.rekey.secrets."dhparams.pem".path;
commonHttpConfig = ''
error_log syslog:server=unix:/dev/log;
access_log syslog:server=unix:/dev/log;
ssl_ecdh_curve secp384r1;
'';
upstreams."kanidm" = {
servers."${config.extra.wireguard."${parentNodeName}-local-vms".ipv4}:8300" = {};
extraConfig = ''
zone kanidm 64k;
keepalive 2;
'';
};
virtualHosts.${auth.domain} = {
forceSSL = true;
useACMEHost = matchingWildcardCert auth.domain;
locations."/".proxyPass = "https://kanidm";
# Allow using self-signed certs to satisfy kanidm's requirement
# for TLS connections. (This is over wireguard anyway)
extraConfig = ''
proxy_ssl_verify off;
'';
};
};
networking.firewall.allowedTCPPorts = [80 443];
networking.nftables.firewall.rules = lib.mkForce {
local-vms-to-local.allowedTCPPorts = [8300];
};
# systemd.services.kanidm = let
# cfg = config.services.kanidm;
# certName = config.services.nginx.virtualHosts.${cfg.serverSettings.domain}.useACMEHost;
# in {
# requires = [ "acme-finished-${certName}.target" ];
# serviceConfig.LoadCredential = let
# certDir = config.security.acme.certs.${certName}.directory;
# in [
# "fullchain.pem:${certDir}/fullchain.pem"
# "key.pem:${certDir}/key.pem"
# ];
# };
services.kanidm = {
enableServer = true;
# enablePAM = true;
serverSettings = {
inherit (auth) domain;
origin = "https://${config.services.kanidm.serverSettings.domain}";
#tls_chain = "/run/credentials/kanidm.service/fullchain.pem";
#tls_key = "/run/credentials/kanidm.service/key.pem";
tls_chain = config.rekey.secrets."kanidm-self-signed.crt".path;
tls_key = config.rekey.secrets."kanidm-self-signed.key".path;
bindaddress = "${config.extra.wireguard."${parentNodeName}-local-vms".ipv4}:8300";
trust_x_forward_for = true;
};
enableClient = true;
clientSettings = {
uri = config.services.kanidm.serverSettings.origin;
verify_ca = true;
verify_hostnames = true;
};
};
environment.systemPackages = [pkgs.kanidm];
};
}

View file

@ -1 +0,0 @@
{}

View file

@ -3,7 +3,7 @@
lib,
...
}: let
inherit (config.lib.net) ip cidr;
inherit (config.lib.net) cidr;
lanCidrv4 = "192.168.100.0/24";
lanCidrv6 = "fd00::/64";
@ -165,7 +165,7 @@ in {
interface = "lan-self";
subnet = lanCidrv4;
pools = [
{pool = "${cidr.host 20 lanCidrv4} - ${cidr.host (-6) lanCidrv4}";}
{pool = "${cidr.host 40 lanCidrv4} - ${cidr.host (-6) lanCidrv4}";}
];
option-data = [
{

View file

@ -1 +0,0 @@
{}

View file

@ -1 +0,0 @@
{}

View file

@ -1 +0,0 @@
{}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -42,14 +42,14 @@
services.nginx = {
upstreams."vaultwarden" = {
servers = {"localhost:8012" = {};};
servers."localhost:8012" = {};
extraConfig = ''
zone vaultwarden 64k;
keepalive 2;
'';
};
upstreams."vaultwarden-websocket" = {
servers = {"localhost:3012" = {};};
servers."localhost:3012" = {};
extraConfig = ''
zone vaultwarden-websocket 64k;
keepalive 2;

View file

@ -17,7 +17,7 @@
services.nginx = {
upstreams."esphome" = {
servers = {"unix:/run/esphome/esphome.sock" = {};};
servers."unix:/run/esphome/esphome.sock" = {};
extraConfig = ''
zone esphome 64k;
keepalive 2;

View file

@ -108,7 +108,7 @@ in {
services.nginx = {
upstreams."homeassistant" = {
servers = {"localhost:${toString haPort}" = {};};
servers."localhost:${toString haPort}" = {};
extraConfig = ''
zone homeassistant 64k;
keepalive 2;

View file

@ -5,8 +5,8 @@
}: let
inherit (config.lib.net) cidr;
net.iot.ipv4cidr = "10.90.0.1/24";
net.iot.ipv6cidr = "fd90::1/64";
iotCidrv4 = "10.90.0.0/24";
iotCidrv6 = "fd90::/64";
in {
networking.hostId = config.repo.secrets.local.networking.hostId;
@ -23,7 +23,10 @@ in {
linkConfig.RequiredForOnline = "routable";
};
"10-wlan1" = {
address = [net.iot.ipv4cidr net.iot.ipv6cidr];
address = [
(cidr.hostCidr 1 iotCidrv4)
(cidr.hostCidr 1 iotCidrv6)
];
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wlan1.mac;
linkConfig.RequiredForOnline = "no";
};

View file

@ -34,6 +34,8 @@
sslCiphers = "EECDH+AESGCM:EDH+AESGCM:!aNULL";
sslDhparam = config.rekey.secrets."dhparams.pem".path;
commonHttpConfig = ''
error_log syslog:server=unix:/dev/log;
access_log syslog:server=unix:/dev/log;
ssl_ecdh_curve secp384r1;
'';
};

View file

@ -32,7 +32,7 @@
services.nginx = {
upstreams."zigbee2mqtt" = {
servers = {"localhost:8072" = {};};
servers."localhost:8072" = {};
extraConfig = ''
zone zigbee2mqtt 64k;
keepalive 2;

View file

@ -32,6 +32,7 @@
types
;
parentConfig = config;
cfg = config.extra.microvms;
inherit (config.extra.microvms) vms;
inherit (config.lib) net;
@ -103,7 +104,7 @@
// node.specialArgs;
inherit (node) pkgs;
inherit (vmCfg) autostart;
config = {
config = {config, ...}: {
imports = [microvm.microvm] ++ cfg.commonImports ++ node.imports;
microvm = {
@ -156,7 +157,7 @@
extra.networking.renameInterfacesByMac.${vmCfg.networking.mainLinkName} = mac;
systemd.network.networks = let
wgConfig = config.extra.wireguard."${nodeName}-local-vms".unitConfName;
wgConfig = parentConfig.extra.wireguard."${nodeName}-local-vms".unitConfName;
in {
# Remove requirement for the wireguard interface to come online,
# to allow microvms to be deployed more easily (otherwise they
@ -204,13 +205,19 @@
networking.nftables.firewall = {
zones = mkForce {
"${vmCfg.networking.mainLinkName}".interfaces = [vmCfg.networking.mainLinkName];
local-vms.interfaces = ["local-vms"];
local-vms.interfaces = [config.extra.wireguard."${nodeName}-local-vms".linkName];
};
rules = mkForce {
"${vmCfg.networking.mainLinkName}-to-local" = {
from = [vmCfg.networking.mainLinkName];
to = ["local"];
inherit
(config.networking.firewall)
allowedTCPPorts
allowedUDPPorts
;
};
local-vms-to-local = {

View file

@ -0,0 +1,10 @@
age-encryption.org/v1
-> X25519 +S2DEXP2FxIlF3HeWNul/QHE4fuVwv7ausZO8C1Yvko
USoULC2zp6mkLEGQFc4ELAotOQkq85yjfC3ImZQe6g0
-> piv-p256 xqSe8Q AuVsMp2nyVB5I6ae7X4rnTT6gH/AyOwkVH5C8qRzenCu
QLdaqASucS24wx5LuoFVD+LBdgsd+wGITMhJBOCrqpY
-> z&m(b4Nw-grease ,&}.>' UWDXz
adqzHHC2X08jrZz0h0y+MuJHM6/kuSUNad8+19cY88IRTF2ujQnoDVDS
--- 8dc8Ta84I8RY7YGIcEuZStaEncGXv1uwJw2ncy3QgtU
Æàr}÷jãEŒA]ˆ¥ÒW˜4gù3“æòAº"ð¹È¤¡Êš
™ru3Î_…E �/ŽöœztKÉß”ë¢Ýˆ°ÔI/°‚‹}Ïò *

View file

@ -0,0 +1 @@
Zs0W99JiuCv1F3NMTp/PcMBrt1bzWttJWNEh00Freyw=

View file

@ -0,0 +1,9 @@
age-encryption.org/v1
-> X25519 95jd7mMbmilIpQbvDmu48FfMFZZbkioExF8KTw3fNXI
CxWXmbD6kArjmJ2Y4lYVcwaQghWyJzS6DsQ4djspUf4
-> piv-p256 xqSe8Q A13AOGXe31ASOihylki3jl8xCxp2bh2lYnzQC44Rbe10
+R8gYDIFyANNPLvdQcq8+67dy+tFcVqS/7rYAbN7pz8
-> 6q.AXp(-grease
GJOOcphfNDKW
--- E/iTzPRKqfS52YBWVcbVAak5koIxmdanzTXRt/5MZnM
ÃÛ¸›6çW®ní?W}7Jp[Bêo|T¸:ûÓÞT¹¿˜]Ykû¤¿ŠBŸ‡èò‰oÞ½6zqVŒ’?+ ˆë^Mž�*/ˆ¶Ö ­