add aspects/hosts/ configurations
Host-specific NixOS configurations for: - alexandria (server) - io (desktop) - rotterdam (desktop) - trantor (server, aarch64) Each host has a main config file and _hostname/ directory with hardware-configuration and other host-specific modules. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ad0aa14d14
commit
25c69e3c18
30 changed files with 1298 additions and 0 deletions
49
aspects/hosts/_alexandria/hardware-configuration.nix
Normal file
49
aspects/hosts/_alexandria/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"usbhid"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
kernelModules = [ ];
|
||||
};
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
extraModulePackages = [ ];
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/31289617-1d84-4432-a833-680b52e88525";
|
||||
fsType = "ext4";
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/4130-BE54";
|
||||
fsType = "vfat";
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{
|
||||
device = "/swapfile";
|
||||
size = 8192;
|
||||
}
|
||||
];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
15
aspects/hosts/_alexandria/jellyfin.nix
Normal file
15
aspects/hosts/_alexandria/jellyfin.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{ lib, inputs, ... }:
|
||||
let
|
||||
utils = import ../../../utils.nix { inherit inputs lib; };
|
||||
inherit (utils) mkNginxVHosts;
|
||||
in
|
||||
{
|
||||
services.jellyfin = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = mkNginxVHosts {
|
||||
domains."jellyfin.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:8096/";
|
||||
};
|
||||
}
|
||||
83
aspects/hosts/_alexandria/kanidm.nix
Normal file
83
aspects/hosts/_alexandria/kanidm.nix
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
utils = import ../../../utils.nix { inherit inputs lib; };
|
||||
inherit (utils) mkNginxVHosts;
|
||||
kanidmCertDir = "/var/lib/kanidm/certs";
|
||||
in
|
||||
|
||||
{
|
||||
services.kanidm = {
|
||||
enableServer = true;
|
||||
enableClient = true;
|
||||
package = pkgs.kanidm;
|
||||
|
||||
serverSettings = {
|
||||
domain = "auth.baduhai.dev";
|
||||
origin = "https://auth.baduhai.dev";
|
||||
bindaddress = "127.0.0.1:8443";
|
||||
ldapbindaddress = "127.0.0.1:636";
|
||||
trust_x_forward_for = true;
|
||||
# Use self-signed certificates for internal TLS
|
||||
tls_chain = "${kanidmCertDir}/cert.pem";
|
||||
tls_key = "${kanidmCertDir}/key.pem";
|
||||
};
|
||||
|
||||
clientSettings = {
|
||||
uri = "https://auth.baduhai.dev";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = mkNginxVHosts {
|
||||
domains."auth.baduhai.dev" = {
|
||||
locations."/" = {
|
||||
proxyPass = "https://127.0.0.1:8443";
|
||||
extraConfig = ''
|
||||
proxy_ssl_verify off;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $host;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 636 ];
|
||||
|
||||
# Generate self-signed certificates for kanidm's internal TLS
|
||||
systemd.services.kanidm-generate-certs = {
|
||||
description = "Generate self-signed TLS certificates for Kanidm";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "kanidm.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
mkdir -p ${kanidmCertDir}
|
||||
if [ ! -f ${kanidmCertDir}/key.pem ]; then
|
||||
${pkgs.openssl}/bin/openssl req -x509 -newkey rsa:4096 \
|
||||
-keyout ${kanidmCertDir}/key.pem \
|
||||
-out ${kanidmCertDir}/cert.pem \
|
||||
-days 3650 -nodes \
|
||||
-subj "/CN=localhost" \
|
||||
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
|
||||
chown -R kanidm:kanidm ${kanidmCertDir}
|
||||
chmod 600 ${kanidmCertDir}/key.pem
|
||||
chmod 644 ${kanidmCertDir}/cert.pem
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# Ensure certificate generation runs before kanidm starts
|
||||
systemd.services.kanidm = {
|
||||
after = [ "kanidm-generate-certs.service" ];
|
||||
wants = [ "kanidm-generate-certs.service" ];
|
||||
};
|
||||
}
|
||||
97
aspects/hosts/_alexandria/nextcloud.nix
Normal file
97
aspects/hosts/_alexandria/nextcloud.nix
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
utils = import ../../../utils.nix { inherit inputs lib; };
|
||||
inherit (utils) mkNginxVHosts;
|
||||
in
|
||||
|
||||
{
|
||||
services = {
|
||||
nextcloud = {
|
||||
enable = true;
|
||||
package = pkgs.nextcloud32;
|
||||
datadir = "/data/nextcloud";
|
||||
hostName = "cloud.baduhai.dev";
|
||||
configureRedis = true;
|
||||
https = true;
|
||||
secretFile = config.age.secrets."nextcloud-secrets.json".path;
|
||||
database.createLocally = true;
|
||||
maxUploadSize = "16G";
|
||||
extraApps = {
|
||||
inherit (config.services.nextcloud.package.packages.apps)
|
||||
calendar
|
||||
contacts
|
||||
notes
|
||||
tasks
|
||||
user_oidc
|
||||
;
|
||||
};
|
||||
extraAppsEnable = true;
|
||||
caching = {
|
||||
apcu = true;
|
||||
redis = true;
|
||||
};
|
||||
settings = {
|
||||
trusted_proxies = [ "127.0.0.1" ];
|
||||
default_phone_region = "BR";
|
||||
maintenance_window_start = "4";
|
||||
allow_local_remote_servers = true;
|
||||
enabledPreviewProviders = [
|
||||
"OC\\Preview\\BMP"
|
||||
"OC\\Preview\\EMF"
|
||||
"OC\\Preview\\Font"
|
||||
"OC\\Preview\\GIF"
|
||||
"OC\\Preview\\HEIC"
|
||||
"OC\\Preview\\Illustrator"
|
||||
"OC\\Preview\\JPEG"
|
||||
"OC\\Preview\\Krita"
|
||||
"OC\\Preview\\MarkDown"
|
||||
"OC\\Preview\\Movie"
|
||||
"OC\\Preview\\MP3"
|
||||
"OC\\Preview\\MSOffice2003"
|
||||
"OC\\Preview\\MSOffice2007"
|
||||
"OC\\Preview\\MSOfficeDoc"
|
||||
"OC\\Preview\\OpenDocument"
|
||||
"OC\\Preview\\PDF"
|
||||
"OC\\Preview\\Photoshop"
|
||||
"OC\\Preview\\PNG"
|
||||
"OC\\Preview\\Postscript"
|
||||
"OC\\Preview\\SVG"
|
||||
"OC\\Preview\\TIFF"
|
||||
"OC\\Preview\\TXT"
|
||||
"OC\\Preview\\XBitmap"
|
||||
];
|
||||
};
|
||||
config = {
|
||||
dbtype = "pgsql";
|
||||
adminpassFile = config.age.secrets.nextcloud-adminpass.path;
|
||||
};
|
||||
phpOptions = {
|
||||
"opcache.interned_strings_buffer" = "16";
|
||||
};
|
||||
};
|
||||
|
||||
nginx.virtualHosts = mkNginxVHosts {
|
||||
domains."cloud.baduhai.dev" = { };
|
||||
};
|
||||
};
|
||||
|
||||
age.secrets = {
|
||||
"nextcloud-secrets.json" = {
|
||||
file = ../../../secrets/nextcloud-secrets.json.age;
|
||||
owner = "nextcloud";
|
||||
group = "nextcloud";
|
||||
};
|
||||
nextcloud-adminpass = {
|
||||
file = ../../../secrets/nextcloud-adminpass.age;
|
||||
owner = "nextcloud";
|
||||
group = "nextcloud";
|
||||
};
|
||||
};
|
||||
}
|
||||
59
aspects/hosts/_alexandria/nginx.nix
Normal file
59
aspects/hosts/_alexandria/nginx.nix
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
utils = import ../../../utils.nix { inherit inputs lib; };
|
||||
inherit (utils) mkNginxVHosts services;
|
||||
|
||||
# Get all unique domains from shared services that have LAN IPs (served by this host)
|
||||
localDomains = lib.unique (map (s: s.domain) (lib.filter (s: s.host == "alexandria") services));
|
||||
|
||||
# Generate ACME cert configs for all local domains
|
||||
acmeCerts = lib.genAttrs localDomains (domain: {
|
||||
group = "nginx";
|
||||
});
|
||||
in
|
||||
|
||||
{
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults = {
|
||||
email = "baduhai@proton.me";
|
||||
dnsResolver = "1.1.1.1:53";
|
||||
dnsProvider = "cloudflare";
|
||||
credentialsFile = config.age.secrets.cloudflare.path;
|
||||
};
|
||||
certs = acmeCerts;
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
virtualHosts = {
|
||||
"_" = {
|
||||
default = true;
|
||||
locations."/".return = "444";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.nginx.extraGroups = [ "acme" ];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
];
|
||||
|
||||
age.secrets.cloudflare = {
|
||||
file = ../../../secrets/cloudflare.age;
|
||||
owner = "nginx";
|
||||
group = "nginx";
|
||||
};
|
||||
}
|
||||
58
aspects/hosts/_alexandria/unbound.nix
Normal file
58
aspects/hosts/_alexandria/unbound.nix
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{ inputs, lib, ... }:
|
||||
|
||||
let
|
||||
utils = import ../../../utils.nix { inherit inputs lib; };
|
||||
in
|
||||
|
||||
{
|
||||
services.unbound = {
|
||||
enable = true;
|
||||
enableRootTrustAnchor = true;
|
||||
settings = {
|
||||
server = {
|
||||
interface = [
|
||||
"0.0.0.0"
|
||||
"::"
|
||||
];
|
||||
access-control = [
|
||||
"127.0.0.0/8 allow"
|
||||
"192.168.0.0/16 allow"
|
||||
"::1/128 allow"
|
||||
];
|
||||
|
||||
num-threads = 2;
|
||||
msg-cache-size = "50m";
|
||||
rrset-cache-size = "100m";
|
||||
cache-min-ttl = 300;
|
||||
cache-max-ttl = 86400;
|
||||
prefetch = true;
|
||||
prefetch-key = true;
|
||||
hide-identity = true;
|
||||
hide-version = true;
|
||||
so-rcvbuf = "1m";
|
||||
so-sndbuf = "1m";
|
||||
|
||||
# LAN-only DNS records
|
||||
local-zone = ''"baduhai.dev." transparent'';
|
||||
local-data = map (e: ''"${e.domain}. IN A ${e.lanIP}"'')
|
||||
(lib.filter (e: e ? lanIP) utils.services);
|
||||
};
|
||||
|
||||
forward-zone = [
|
||||
{
|
||||
name = ".";
|
||||
forward-addr = [
|
||||
"1.1.1.1@853#cloudflare-dns.com"
|
||||
"1.0.0.1@853#cloudflare-dns.com"
|
||||
];
|
||||
forward-tls-upstream = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 53 ];
|
||||
allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
}
|
||||
26
aspects/hosts/_alexandria/vaultwarden.nix
Normal file
26
aspects/hosts/_alexandria/vaultwarden.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
utils = import ../../../utils.nix { inherit inputs lib; };
|
||||
inherit (utils) mkNginxVHosts;
|
||||
in
|
||||
{
|
||||
services.vaultwarden = {
|
||||
enable = true;
|
||||
config = {
|
||||
DOMAIN = "https://pass.baduhai.dev";
|
||||
SIGNUPS_ALLOWED = false;
|
||||
ROCKET_ADDRESS = "127.0.0.1";
|
||||
ROCKET_PORT = 58222;
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = mkNginxVHosts {
|
||||
domains."pass.baduhai.dev".locations."/".proxyPass =
|
||||
"http://${config.services.vaultwarden.config.ROCKET_ADDRESS}:${toString config.services.vaultwarden.config.ROCKET_PORT}/";
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue