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

feat(sire): init host: main media storage server

This commit is contained in:
oddlama 2024-01-04 19:06:23 +01:00
parent 36cb1d31cb
commit 1a96a4b8df
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
33 changed files with 364 additions and 69 deletions

View file

@ -14,6 +14,10 @@ system = "x86_64-linux"
type = "nixos"
system = "x86_64-linux"
[sire]
type = "nixos"
system = "x86_64-linux"
[zackbiene]
type = "nixos"
system = "aarch64-linux"

View file

@ -31,7 +31,7 @@
#};
};
zpool = with lib.disko.zfs; {
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
rpool = mkZpool {datasets = impermanenceZfsDatasets;};
};
};

View file

@ -30,7 +30,7 @@
};
};
zpool = with lib.disko.zfs; {
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
rpool = mkZpool {datasets = impermanenceZfsDatasets;};
};
};

View file

@ -20,7 +20,7 @@
};
};
zpool = with lib.disko.zfs; {
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
rpool = mkZpool {datasets = impermanenceZfsDatasets;};
};
};

100
hosts/sire/default.nix Normal file
View file

@ -0,0 +1,100 @@
{
config,
inputs,
lib,
nodes,
minimal,
...
}: {
imports = [
inputs.nixos-hardware.nixosModules.common-cpu-intel
inputs.nixos-hardware.nixosModules.common-pc-ssd
../../modules/optional/hardware/intel.nix
../../modules/optional/hardware/physical.nix
../../modules
../../modules/optional/initrd-ssh.nix
../../modules/optional/zfs.nix
./fs.nix
./net.nix
];
boot.mode = "efi";
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"];
meta.promtail = {
enable = true;
proxy = "sentinel";
};
# Connect safely via wireguard to skip authentication
networking.hosts.${nodes.sentinel.config.meta.wireguard.proxy-sentinel.ipv4} = [nodes.sentinel.config.networking.providedDomains.influxdb];
meta.telegraf = {
enable = true;
influxdb2 = {
domain = nodes.sentinel.config.networking.providedDomains.influxdb;
organization = "machines";
bucket = "telegraf";
node = "ward-influxdb";
};
};
# TODO track my github stats
# services.telegraf.extraConfig.inputs.github = {};
guests = let
mkGuest = guestName: {
autostart = true;
zfs."/state" = {
pool = "rpool";
dataset = "local/guests/${guestName}";
};
zfs."/persist" = {
pool = "rpool";
dataset = "safe/guests/${guestName}";
};
modules = [
../../modules
./guests/common.nix
./guests/${guestName}.nix
{node.secretsDir = ./secrets/${guestName};}
];
};
mkMicrovm = guestName: {
${guestName} =
mkGuest guestName
// {
backend = "microvm";
microvm = {
system = "x86_64-linux";
macvtap = "lan";
baseMac = config.repo.secrets.local.networking.interfaces.lan.mac;
};
};
};
# deadnix: skip
mkContainer = guestName: {
${guestName} =
mkGuest guestName
// {
backend = "container";
container.macvlan = "lan";
};
};
in
lib.mkIf (!minimal) (
{}
// mkMicrovm "samba"
// mkMicrovm "grafana"
// mkMicrovm "influxdb"
// mkMicrovm "loki"
// mkMicrovm "paperless"
#// mkMicrovm "minecraft"
#// mkMicrovm "immich"
#// mkMicrovm "firefly"
#// mkMicrovm "fasten-health"
);
}

118
hosts/sire/fs.nix Normal file
View file

@ -0,0 +1,118 @@
{
config,
lib,
...
}: {
disko.devices = {
disk =
{
m2-ssd-1 = {
type = "disk";
device = "/dev/disk/by-id/${config.repo.secrets.local.disk.m2-ssd-1}";
content = with lib.disko.gpt; {
type = "table";
format = "gpt";
partitions = [
(partEfi "efi" "0%" "1GiB")
(partLuksZfs "rpool" "1GiB" "100%")
];
};
};
m2-ssd-2 = {
type = "disk";
device = "/dev/disk/by-id/${config.repo.secrets.local.disk.m2-ssd-2}";
content = lib.disko.content.luksZfs "rpool";
};
}
// lib.genAttrs config.repo.secrets.local.disk.hdds-tank (disk: {
type = "disk";
device = "/dev/disk/by-id/${disk}";
content = lib.disko.content.luksZfs "tank";
});
zpool = with lib.disko.zfs; {
rpool = mkZpool {
mode = "mirror";
datasets =
impermanenceZfsDatasets
// {
"safe/guests" = unmountable;
};
};
tank = mkZpool {
mode = "raidz1";
datasets = {
"safe/guests" = unmountable;
};
};
};
};
services.zrepl = {
enable = true;
settings = {
global = {
logging = [
{
type = "syslog";
level = "info";
format = "human";
}
];
# TODO zrepl monitor
#monitoring = [
# {
# type = "prometheus";
# listen = ":9811";
# listen_freebind = true;
# }
#];
};
jobs = [
{
name = "local-snapshots";
type = "snap";
filesystems = {
"rpool/local/state<" = true;
"rpool/safe<" = true;
"tank/safe<" = true;
};
snapshotting = {
type = "periodic";
prefix = "zrepl-";
timestamp_format = "iso-8601";
interval = "15m";
};
pruning.keep = [
# Keep all manual snapshots
{
type = "regex";
regex = "^zrepl-.*$";
negate = true;
}
# Keep last n snapshots
{
type = "last_n";
regex = "^zrepl-.*$";
count = 10;
}
# Prune periodically
{
type = "grid";
regex = "^zrepl-.*$";
grid = lib.concatStringsSep " | " [
"72x1h"
"90x1d"
"60x1w"
"24x30d"
];
}
];
}
];
};
};
boot.initrd.luks.devices.enc-rpool.allowDiscards = true;
boot.initrd.luks.devices.enc-tank.allowDiscards = true;
}

View file

@ -0,0 +1,27 @@
{
config,
lib,
nodes,
...
}: let
sentinelCfg = nodes.sentinel.config;
in {
meta.wireguard-proxy.sentinel = {};
meta.promtail = {
enable = true;
proxy = "sentinel";
};
# Connect safely via wireguard to skip http authentication
networking.hosts.${sentinelCfg.meta.wireguard.proxy-sentinel.ipv4} = [sentinelCfg.networking.providedDomains.influxdb];
meta.telegraf = lib.mkIf (!config.boot.isContainer) {
enable = true;
scrapeSensors = false;
influxdb2 = {
domain = sentinelCfg.networking.providedDomains.influxdb;
organization = "machines";
bucket = "telegraf";
node = "ward-influxdb";
};
};
}

66
hosts/sire/net.nix Normal file
View file

@ -0,0 +1,66 @@
{config, ...}: {
networking.hostId = config.repo.secrets.local.networking.hostId;
boot.initrd.systemd.network = {
enable = true;
networks."10-lan" = {
address = ["192.168.1.2"];
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac;
networkConfig = {
IPv6PrivacyExtensions = "yes";
MulticastDNS = true;
};
linkConfig.RequiredForOnline = "routable";
};
};
# Create a MACVTAP for ourselves too, so that we can communicate with
# our guests on the same interface.
systemd.network.netdevs."10-lan-self" = {
netdevConfig = {
Name = "lan-self";
Kind = "macvlan";
};
extraConfig = ''
[MACVLAN]
Mode=bridge
'';
};
systemd.network.networks = {
"10-lan" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac;
# This interface should only be used from attached macvtaps.
# So don't acquire a link local address and only wait for
# this interface to gain a carrier.
networkConfig.LinkLocalAddressing = "no";
linkConfig.RequiredForOnline = "carrier";
extraConfig = ''
[Network]
MACVLAN=lan-self
'';
};
"20-lan-self" = {
address = ["192.168.1.2"];
matchConfig.Name = "lan-self";
networkConfig = {
IPv6PrivacyExtensions = "yes";
MulticastDNS = true;
};
linkConfig.RequiredForOnline = "routable";
};
# Remaining macvtap interfaces should not be touched.
"90-macvtap-ignore" = {
matchConfig.Kind = "macvtap";
linkConfig.ActivationPolicy = "manual";
linkConfig.Unmanaged = "yes";
};
};
networking.nftables.firewall = {
zones.untrusted.interfaces = ["lan-self"];
};
# Allow accessing influx
meta.wireguard.proxy-sentinel.client.via = "sentinel";
}

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFMbumSAJX2MOuQO+5tFoL52Fe+TRD2dZwzNCGilACQ/

Binary file not shown.

View file

@ -0,0 +1,12 @@
age-encryption.org/v1
-> X25519 fKbik0Nwn3w0RFtyYjRx3NIRR6p1ePjwN1rQeQUKnC0
FESp5Xwwuu3hifwpoalYD75/g994HsDJb6a7lasAH98
-> piv-p256 xqSe8Q A/f8+j/94A2oU2/SynYRewGBZbPWy1rGU5pnUPksXkwH
n+KeTBbXvjCu9GZypD8Vmz2uuN1XaZpDfX40TNk74js
-> *:l-grease D8U!RlB wkBn7Zl4
PLWQ+OcE+p/gZ9AaOl5RmO8C5IO5rQD3GIazmdWs/ImIbPFgSY7NM+Tb4j/qrQez
--- 2ucK0s28/BTrnfxnm0vOvqsmOXLXBEnsxHMRHYUyLHo
¼b˜à¹oѯVo}¼å]3Kпâppú\­ÉYiæ}:FH÷Ó^ÉU°>ÚRÿô¿eM`0Î+îíÕ¯·±ÞÜÓ놪…Œ1¡50:F‚Y2M“^[u�ÇáZMy;„ký]z8û÷a~MæÔŸÿ1­cô/™óU¦3)–r–è¢Ç–Uõ>•÷˜‘ºóx?ý6xò¤6`!R_ψ¦�»’éæŒ¦£á·Žòû÷&ž(.«{x•›? rëhåÙêÂB}̨Në°#Œ–¿g[•õù2aR¯­lRØT§Ï£æ9W“”Û ]ŸÇ£ IŽ›œ26¼¨¨lô?íµäô·áÆ
~ÑXßµ½„”O·…φ#‚!àø.�‰�*äĤmjh*C˜¨¨}­{!¸ µ›
Ã&ÒN¿Ðm#vEFbË–3C´d\}·ajRÆ[…È[Ñ+ïp2%ÜãÊÈ­†óÀ/|5³þ(øÂ-à�žÝîa¹°dÝÔ_@Éà…g¬|.Á…o¦+à[œVÇ`‹tP©²¼

View file

@ -22,7 +22,7 @@
];
boot.mode = "efi";
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"];
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "e1000e" "alx"];
meta.promtail = {
enable = true;
@ -76,6 +76,7 @@
};
};
# deadnix: skip
mkContainer = guestName: {
${guestName} =
mkGuest guestName
@ -88,29 +89,9 @@
lib.mkIf (!minimal) (
{}
// mkMicrovm "adguardhome"
// mkMicrovm "samba"
// mkContainer "forgejo"
// mkContainer "grafana"
// mkContainer "influxdb"
// mkContainer "kanidm"
// mkContainer "loki"
// mkContainer "paperless"
// mkContainer "radicale"
// mkContainer "vaultwarden"
// mkMicrovm "forgejo"
// mkMicrovm "kanidm"
// mkMicrovm "radicale"
// mkMicrovm "vaultwarden"
);
#ddclient = defineVm;
#samba+wsdd = defineVm;
#fasten-health = defineVm;
#immich = defineVm;
#paperless = defineVm;
#radicale = defineVm;
#minecraft = defineVm;
#firefly
#maddy = defineVm;
#anonaddy = defineVm;
#automatic1111 = defineVm;
#invokeai = defineVm;
}

View file

@ -20,15 +20,13 @@
};
};
zpool = with lib.disko.zfs; {
rpool =
defaultZpoolOptions
// {
datasets =
defaultZfsDatasets
// {
"safe/guests" = unmountable;
};
};
rpool = mkZpool {
datasets =
impermanenceZfsDatasets
// {
"safe/guests" = unmountable;
};
};
};
};

View file

@ -4,7 +4,7 @@
...
}: let
inherit (lib) net;
lanCidrv4 = "192.168.100.0/24";
lanCidrv4 = "192.168.1.0/24";
dnsIp = net.cidr.host 2 lanCidrv4;
in {
# TODO make meta.kea module?

View file

@ -3,7 +3,7 @@
lib,
...
}: let
lanCidrv4 = "192.168.100.0/24";
lanCidrv4 = "192.168.1.0/24";
lanCidrv6 = "fd10::/64";
in {
networking.hostId = config.repo.secrets.local.networking.hostId;
@ -44,13 +44,8 @@ in {
#dhcpV4Config.UseDNS = false;
#dhcpV6Config.UseDNS = false;
#ipv6AcceptRAConfig.UseDNS = false;
address = [
"192.168.178.7/24"
#"fdee::1/64"
];
gateway = [
"192.168.178.1"
];
address = ["192.168.178.2/24"];
gateway = ["192.168.178.1"];
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wan.mac;
networkConfig.IPv6PrivacyExtensions = "yes";
linkConfig.RequiredForOnline = "routable";

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> X25519 rGyfugBW1UJ6ufBn8FUWby1AG3ZnBDnNXMBGEXOi/GM
I87QSk3ZBL4FZjdwFd7RS2aRNizPRn/gAdQEUDrnTak
-> piv-p256 xqSe8Q ArQj/8FR6hO8vrqY+1e/YN+h46hSCMg0c3tqZ6U3ApMS
+XzFGrEz4z2tU6N7b2taf6j8V4WJi4NfQq4IJHV53l0
-> #=2[OV-grease cKs OHnI
iLqxxLbFIrTYFSDGKsOtZ8j7nw
--- Uu8dPdMbw1Zvs8ZuzNbm/LBoeexh3sEiXht6IrkYf8A
…!ÂŐB¦Řß*ÇZśZ20&bÉĘ×~d-Ń;¤,…J2î�§ăôažtć>P}gŐ…z’sóMÝ„6ŽíU° ŕYŢâFĚÖ”©o@ă‡rS«ÖVĹ�KA7ĺ$ť“�—�ńXD‰ 6ě˙ĺGćüć�m»i!IŹDCFĄ'�ĄĹŻŻ‘ŰŻC™[w$iG.U:PŹ8Óľűż…h›µŻićô¨ŘčüÉżŠŐ‹Ć{ŠĹá×vç8Zpľ9˙˘˙uPŁÝÚVj�e×€ĘJ`CÎ:K0¬W0čv�i˙G–!÷2T�2ůŠĎCGÔpzVĐđ€ě� —nN&2é8)¶Ť%˘Fäo‘gůľű¨VëeeUiz
�"Ô¤ŮÍ!Ž)î%áHŢcswă'Ş(íͦ" Îtl•E ţUŠâ[]Iľ`.>KˇÖfÂÄWŽ&�·çQ–®hĄ·{+ž7V

View file

@ -20,7 +20,7 @@
};
};
zpool = with lib.disko.zfs; {
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
rpool = mkZpool {datasets = impermanenceZfsDatasets;};
};
};
}

View file

@ -1,8 +1,19 @@
_inputs: _final: prev: {
_inputs: final: prev: {
lib =
prev.lib
// {
disko = {
content = {
luksZfs = name: {
type = "luks";
name = "enc-${name}";
extraOpenArgs = ["--allow-discards"];
content = {
type = "zfs";
pool = name;
};
};
};
gpt = {
partGrub = name: start: end: {
inherit name start end;
@ -30,19 +41,11 @@ _inputs: _final: prev: {
partLuksZfs = name: start: end: {
inherit start end;
name = "enc-${name}";
content = {
type = "luks";
name = "enc-${name}";
extraOpenArgs = ["--allow-discards"];
content = {
type = "zfs";
pool = name;
};
};
content = final.lib.disko.content.luksZfs name;
};
};
zfs = rec {
defaultZpoolOptions = {
mkZpool = prev.lib.recursiveUpdate {
type = "zpool";
rootFsOptions = {
compression = "zstd";
@ -57,7 +60,7 @@ _inputs: _final: prev: {
options.ashift = "12";
};
defaultZfsDatasets = {
impermanenceZfsDatasets = {
"local" = unmountable;
"local/root" =
filesystem "/"