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:
parent
36cb1d31cb
commit
1a96a4b8df
33 changed files with 364 additions and 69 deletions
|
@ -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"
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#};
|
||||
};
|
||||
zpool = with lib.disko.zfs; {
|
||||
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
|
||||
rpool = mkZpool {datasets = impermanenceZfsDatasets;};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
};
|
||||
};
|
||||
zpool = with lib.disko.zfs; {
|
||||
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
|
||||
rpool = mkZpool {datasets = impermanenceZfsDatasets;};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
};
|
||||
};
|
||||
zpool = with lib.disko.zfs; {
|
||||
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
|
||||
rpool = mkZpool {datasets = impermanenceZfsDatasets;};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
100
hosts/sire/default.nix
Normal file
100
hosts/sire/default.nix
Normal 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
118
hosts/sire/fs.nix
Normal 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;
|
||||
}
|
27
hosts/sire/guests/common.nix
Normal file
27
hosts/sire/guests/common.nix
Normal 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
66
hosts/sire/net.nix
Normal 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";
|
||||
}
|
1
hosts/sire/secrets/host.pub
Normal file
1
hosts/sire/secrets/host.pub
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFMbumSAJX2MOuQO+5tFoL52Fe+TRD2dZwzNCGilACQ/
|
BIN
hosts/sire/secrets/local.nix.age
Normal file
BIN
hosts/sire/secrets/local.nix.age
Normal file
Binary file not shown.
12
hosts/sire/secrets/samba/local.nix.age
Normal file
12
hosts/sire/secrets/samba/local.nix.age
Normal 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æÔŸÿ1cô/™ó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©²¼
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -20,15 +20,13 @@
|
|||
};
|
||||
};
|
||||
zpool = with lib.disko.zfs; {
|
||||
rpool =
|
||||
defaultZpoolOptions
|
||||
// {
|
||||
datasets =
|
||||
defaultZfsDatasets
|
||||
// {
|
||||
"safe/guests" = unmountable;
|
||||
};
|
||||
};
|
||||
rpool = mkZpool {
|
||||
datasets =
|
||||
impermanenceZfsDatasets
|
||||
// {
|
||||
"safe/guests" = unmountable;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
Binary file not shown.
|
@ -20,7 +20,7 @@
|
|||
};
|
||||
};
|
||||
zpool = with lib.disko.zfs; {
|
||||
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
|
||||
rpool = mkZpool {datasets = impermanenceZfsDatasets;};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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 "/"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue