infra/nix/hosts/pure-joy/configuration.nix
2026-01-05 23:09:19 +01:00

1205 lines
32 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
hostName = "pure-joy";
tailnet = "tail530c7.ts.net";
in
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
./disko-config.nix
# (let username = "${usr}"; in with username; ./disko-config.nix)
./modules/promtail/promtail.nix
./modules/caddy.nix
./modules/ta.nix
./modules/backups
./modules/transmission.nix
./modules/radarr.nix
./modules/sonarr.nix
./modules/bazarr.nix
../../modules/base.nix
../../modules/dnscrypt.nix
# ../../modules/waydroid.nix
../../modules/sanoid.nix
../../modules/zram.nix
];
sops = {
defaultSopsFile = ./secrets.yaml;
gnupg.sshKeyPaths = [ ];
age = {
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
generateKey = false;
};
secrets = {
rootPassphrase = {
neededForUsers = true;
};
dnscrypt-proxy-forwardingRules = {
sopsFile = lib.mkForce ./secrets.yaml;
restartUnits = [ "dnscrypt-proxy2.service" ];
};
#dnscrypt-proxy-cloaked = {
# owner = "dnscrypt-proxy";
# group = "dnscrypt-proxy";
# restartUnits = ["dnscrypt-proxy2.service"];
#};
domainName = {
sopsFile = ../../secrets/net.yaml;
restartUnits = [ "promtail.service" ];
};
"attic/netrc" = { };
z0Key.path = "/var/tmp/z0.key";
# z00p6CrdroidKey.path = "/var/tmp/z0-0p6-crdroid.key";
nixbldr-priv = {
path = "/root/.ssh/nixbldr-${hostName}";
mode = "0500";
};
a0Key = {
path = "/var/tmp/a0.key";
};
};
};
# nixpkgs.currentSystem = "x86_64-linux";
nix.gc.automatic = lib.mkForce false;
nix.optimise.automatic = lib.mkForce false;
nix.settings = {
trusted-users = [
"@wheel"
"root"
];
netrc-file = config.sops.secrets."attic/netrc".path;
};
boot = {
enableContainers = true;
consoleLogLevel = 3;
kernelParams = [
# "spl.spl_hostid=deadb33f"
"ip=dhcp" # FIXME: this is probably wrong...
# "i915.perf_stream_paranoid=0"
"i915.enable_guc=2" # for 9th GPU generation and upwards, likely skylake.
"consoleblank=600"
## forbid hibernation due to zfs-on-root --> no need to manually specify
## this as NixOS does adds by default when booting from zfs.
# "nohibernate" #
# "systemd.log_level=notice"
"rd.udev.log_level=4"
"udev.log_priority=4"
"boot.shell_on_fail"
];
# kernelPackages = pkgs.linuxPackages_6_12;
kernelPackages = pkgs.linuxPackages_6_17;
# kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages; # deprecated
kernel.sysctl = {
"dev.i915.perf_stream_paranoid" = 0;
# XXX redis
"vm.overcommit_memory" = 1;
};
#swraid = {
# enable = false;
# mdadmConf = ''
# MAILADDR=nobody@nowhere
# '';
#};
loader = {
timeout = 7;
# Use the systemd-boot EFI boot loader.
systemd-boot = {
enable = true;
configurationLimit = 75;
netbootxyz.enable = true;
memtest86.enable = true;
};
efi.canTouchEfiVariables = true;
};
plymouth.enable = false;
tmp = {
useTmpfs = true;
cleanOnBoot = true;
};
supportedFilesystems = [
"zfs"
"ext4"
"btrfs"
];
zfs =
let
xtrPools = [
# "z0"
];
in
{
forceImportRoot = true;
extraPools = [
# "z0"
]; # // xtrPools;
requestEncryptionCredentials = [
"zr"
# "z0" # not recursively dammit
]; # // xtrPools;
};
kernelModules = [
"zfs"
"i915"
"igc"
"r8169"
"br_netfilter"
];
initrd = {
# systemd.enable = true;
kernelModules = [
"zfs"
"i915"
"igc"
"r8169"
"br_netfilter"
];
# initrd.availableKernelModules = [ "nvme" "ehci_pci" "xhci_pci" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" "thinkpad_acpi" ];
availableKernelModules = [
"nvme"
"ehci_pci"
"xhci_pci"
"usb_storage"
"sd_mod"
"rtsx_pci_sdmmc"
"igc"
"r8169"
"i915"
"br_netfilter"
];
network = {
# This will use udhcp to get an ip address.
# Make sure you have added the kernel module for your network driver to `boot.initrd.availableKernelModules`,
# so your initrd can load it!
# Static ip addresses might be configured using the ip argument in kernel command line:
# https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt
enable = true;
ssh = {
enable = true;
# To prevent ssh clients from freaking out because a different host key is used,
# a different port for ssh is useful (assuming the same host has also a regular sshd running)
port = 2222;
# hostKeys paths must be unquoted strings, otherwise you'll run into issues with boot.initrd.secrets
# the keys are copied to initrd from the path specified; multiple keys can be set
# you can generate any number of host keys using
# `ssh-keygen -t ed25519 -N "" -f /path/to/ssh_host_ed25519_key`
# `ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key`
# hostKeys = [/root/.initrd-ssh_host_ed25519_key];
hostKeys = [ /etc/secrets/initrd/ssh_host_ed25519_key ];
ignoreEmptyHostKeys = true;
authorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIODmLwtQj6ylgdTPo1/H5jW7jsLzwaCTGdIsTQAdc896"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILPLzZkzWM+iiwRqbLX4+iyXSUqewojm74L7Zn2nSrAU"
];
};
};
};
# extraModprobeConfig = "options kvm_amd nested=1";
binfmt = {
emulatedSystems = [
"wasm32-wasi"
"aarch64-linux"
];
};
};
environment = {
# memoryAllocator.provider = "graphene-hardened"; # default is libc, alt scudo.
# memoryAllocator.provider = "scudo"; # default is libc, alt scudo.
memoryAllocator.provider = "libc";
# noXlibs = true; # graphical stuff breaks...
variables = {
EDITOR = "vim";
VISUAL = "vim";
NIXPKGS_ALLOW_UNFREE = "0";
};
systemPackages = with pkgs; [
efibootmgr
hddtemp
efibootmgr
openssl
### # libinput
dmidecode
fwupd
### incron
bridge-utils
moreutils # moar better
wol
vim
# helix
ranger
### # zed-editor
git
fio
viddy # watch reimplementation
pv
intel-gpu-tools
# XXX: deprecated in 24.11
# onevpl-intel-gpu
vpl-gpu-rt
intel-compute-runtime
clinfo
### passage # pass w/ support for age encryption
### # passExtensions.pass-tomb
btrfs-progs
ntfs3g
cryptsetup
squashfsTools
sasquatch
libguestfs
binwalk
ddrescue
sleuthkit
foremost
scalpel
testdisk
# scrounge-ntfs
#python3.pkgs.dissect-ntfs
#python3.pkgs.dissect
#python3.pkgs.dissect-util
## python3.pkgs.dissect-volume
#python3.pkgs.dissect-thumbcache
#python3.pkgs.dissect-shellitem
#python3.pkgs.dissect-xfs
#python3.pkgs.dissect-fat
#python3.pkgs.dissect-target
#python3.pkgs.dissect-sql
## python3.pkgs.dissect-fve
#python3.pkgs.dissect-archive
#python3.pkgs.dissect-regf
#python3.pkgs.dissect-etl
#python3.pkgs.dissect-evidence
#python3.pkgs.dissect-ole
#python3.pkgs.dissect-cim
#python3.pkgs.dissect-executable
#python3.pkgs.dissect-eventlog
#python3.pkgs.dissect-clfs
python3.pkgs.fusepy
### httm # zfs time machine-like tool
### htmlq # like jq, but for html
### httplz # a basic http server for hosting a folder
### htmldoc # convert html top postscript and pdf
### http-prompt # An interactive command-line HTTP client featuring autocomplete and syntax highlighting
wireguard-tools
wget
curl
inetutils # telnet
httpx
# traceroute
dublin-traceroute
mtr # a network diagnostic tool
starship
zellij
zoxide
### # ripgrep-all # provides rga with support for pdfs, zip files and such.
fzf
### fzy # a better fuzzy finder
### skim # a command-line fuzzy finder written in Rust
### ddh # a fast duplicate file finder
### docfd # a multiline fuzzy document finder
### zf # a fuzzy finder that prioritizes matches on filenames
### skim # a rust fuzzy finder
### nodePackages.json-diff
### pandoc
fastfetch
### freshfetch
### ghfetch
### w3m
### lynx
go_1_25
rustc
#cargo
### sccache
python3.pkgs.pip
### python3.pkgs.numpy
### python3.pkgs.pandas
### bitwarden-cli
### rbw
### pinentry-curses # a dep of rbw. can also use pinentry (gtk2?).
### poppler_utils
### zbar
### qrencode
bsd-finger
### # flatpak
### quickemu
### # virt-manager
### sshpass
### ssh-audit
### sshchecker
### ssh-key-confirmer
### ssh-mitm
### sshesame
### pssh
ssh-to-age
### # localsend
### lychee
### notcurses
### msgviewer # convert .msg to .eml
### libpst # read outlook profile files
### cmatrix
### # qbittorrent
### immich-go
### sdcv # console version of StarDict
### tmux
### tmate
### circumflex # hackernews in the terminal
### obfs4 # tor client-bridge transport mechanism
sysstat
ioztat # storage load analysis fro openzfs
cifs-utils
pciutils
sysfsutils
lshw
### libva-utils
sanoid
hdparm
];
};
console.keyMap = "uk";
networking = {
# hostId = pkgs.lib.mkForce "00000000";
hostId = "ae4db0ef";
inherit hostName;
nftables.enable = true;
networkmanager = {
enable = true;
dns = "none";
};
dhcpcd.extraConfig = "nohook resolv.conf";
nameservers = [
"127.0.0.1"
"::1"
];
resolvconf = {
dnsSingleRequest = true;
extraOptions = [
"single-request-reopen"
"attempts:5"
"timeout:5"
# "rotate"
"ndots:1"
# Sets RES_NOCHECKNAME in _res.options, which disables the modern BIND
# checking of incoming hostnames and mail names for invalid characters such
# as underscore (_), non-ASCII, or control characters.
"no-check-names"
# "trust-ad"
];
};
# interfaces.enp0s25.wakeOnLan.enable = true;
stevenblack = {
enable = true;
block = [
"fakenews"
"gambling"
];
};
firewall = {
allowPing = true;
checkReversePath = lib.mkForce false; # FIXME: fix the root issue instead.
logReversePathDrops = true;
logRefusedConnections = true;
trustedInterfaces = [
"virbr0"
# "bro"
"tailscale0"
];
# allowedTCPPorts = [config.wanderllama.immich.port];
};
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
};
users.users = {
root = {
shell = pkgs.zsh;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBtG6NCgdLHX4ztpfvYNRaslKWZcl6KdTc1DehVH4kAL"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJaXmXbNegxiXLldy/sMYX8kCsghY1SGqn2FZ5Jk7QJw"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZbkw9vjCfbMPEH7ZAFq20XE9oIJ4w/HRIMu2ivNcej caelum's nixbldr key"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGKzPC0ZK4zrOEBUdu1KNThEleVb1T5Pl3+n3KB3o0b8 surtur's nixbldr key"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5u4sBsu4ZpVRHJ9J2CfQ4JoojsdfsS0WzaFgiMCOe5 loki's nixbldr key"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILPLzZkzWM+iiwRqbLX4+iyXSUqewojm74L7Zn2nSrAU"
];
# hashedPasswordFile = config.sops.secrets.rootPassphrase.path;
hashedPassword = "$y$j9T$SfDsCD38SbyayLzPYNGVn.$CvbdKg0TdDmfENxwtKUuNQ7X/GnUiI5twD9DBA3QiAD";
autoSubUidGidRange = true;
};
lokicifs = {
isSystemUser = true;
group = "nobody";
};
m = {
isSystemUser = true;
group = "nobody";
};
caveman = {
isSystemUser = true;
group = "nobody";
};
};
users.groups = {
nobody = { };
};
nix.registry = {
nixpkgs.to = {
type = "github";
owner = "nixos";
repo = "nixpkgs";
};
};
# # services.xserver.displayManager.defaultSession = "plasmawayland";
# services.xserver.displayManager.defaultSession = "sway";
# services.xserver.desktopManager = {
# xterm.enable = false;
# # xfce.enable = true;
# # gnome.enable = true;
# plasma5.enable = true;
# };
programs = {
# adb.enable = true;
# https://nixos.wiki/wiki/Appimage
# appimage.binfmt = true;
# responsiveness over 9000.
cfs-zen-tweaks.enable = true;
#gnupg.agent = {
# enable = true;
# # pinentryFlavor = "curses"; # or "gnome3"
# pinentryPackage = pkgs.pinentry-curses;
# enableSSHSupport = false;
#};
# ssh.startAgent = true;
ssh.extraConfig = ''
Host z
Hostname z.${tailnet}
User root
IdentityFile ${config.sops.secrets.nixbldr-priv.path}
Host loki
Hostname loki.${tailnet}
User root
IdentityFile ${config.sops.secrets.nixbldr-priv.path}
Host t14
Hostname t14.${tailnet}
User root
IdentityFile ${config.sops.secrets.nixbldr-priv.path}
Host nixpi
Hostname nixpi.${tailnet}
User root
IdentityFile ${config.sops.secrets.nixbldr-priv.path}
Host caelum
Hostname caelum.${tailnet}
User root
IdentityFile ${config.sops.secrets.nixbldr-priv.path}
Host pure-joy
Hostname pure-joy.${tailnet}
User root
IdentityFile ${config.sops.secrets.nixbldr-priv.path}
Host monoceros
Hostname 158.220.120.164
User root
IdentityFile ${config.sops.secrets.nixbldr-priv.path}
'';
# macOS compatibility;
# darling.enable = true;
direnv.enable = true;
# nano.enable = lib.mkForce false;
# vim.defaultEditor = true;
# wireshark.enable = true;
};
security = {
sudo = {
enable = true;
# prevent's CVE-2021-3156-style exploits.
execWheelOnly = true;
# for wheel and root, kitty likes this.
keepTerminfo = true;
#extraConfig = ''
# Defaults lecture=always
# Defaults lecture_file=${./misc/groot.txt}
#'';
extraRules = [
{
commands = [
{
command = "${pkgs.systemd}/bin/systemctl suspend";
options = [ "NOPASSWD" ];
}
{
command = "${pkgs.systemd}/bin/reboot";
options = [ "NOPASSWD" ];
}
{
command = "${pkgs.systemd}/bin/poweroff";
options = [ "NOPASSWD" ];
}
];
groups = [ "wheel" ];
}
];
};
# polkit.enable = true;
# rtkit.enable = true;
};
fileSystems = {
# ext4 zvol, technically important but not enough to fall to emergency shell.
"/root/.local/share/atuin".options = [
"x-systemd.device-timeout=30s,x-systemd.mount-timeout=45s,nofail"
];
"/var/lib/docker".options = [ "x-systemd.mount-timeout=45s,nofail" ];
# backup boot.
"/.boot" = {
device = "/dev/disk/by-id/usb-Verbatim_STORE_N_GO_07B50C09D3E5B1CC-0:0-part1";
fsType = "vfat";
options = [
"relatime"
"fmask=0022"
"dmask=0022"
"codepage=437"
"iocharset=iso8859-1"
"shortname=mixed"
"errors=remount-ro"
"nofail"
];
};
};
systemd.paths.copyboot = {
unitConfig = {
Description = "Watch /boot change and copy to a backup location";
PathIsMountPoint = [
"/boot"
"/.boot"
];
# RequiresMountsFor = "/boot";
};
pathConfig = {
PathChanged = "/boot";
Unit = "copyboot.service";
# MakeDirectory = "yes";
};
wantedBy = [ "multi-user.target" ];
};
#systemd.mounts = [
# {
# "root-.local-share-atuin.mount" = {
# # options = "nofail";
# };
# }
#];
systemd.services = {
sshd = {
serviceConfig = {
# never-ever even think about killing sshd!
OOMScoreAdjust = -1000;
};
};
copyboot = {
unitConfig = {
Description = "Copy /boot to a backup location on change";
# RequiresMountsFor = "/boot";
PathIsMountPoint = [
"/boot"
"/.boot"
];
};
serviceConfig = {
RestartSec = 10;
ExecStart = "${pkgs.rsync}/bin/rsync -auvPXEogt --delete /boot/ /.boot/";
};
};
# immich docker.
immichd =
let
srv = "immich";
workdir = "/var/lib/${srv}";
compose = "/etc/${srv}/docker-compose.yml";
cmd = "${pkgs.docker}/bin/docker compose -p ${srv} -f ${compose}";
in
{
wants = [ "multi-user.target" ];
requires = [ "docker.service" ];
upholds = [
"docker.service"
"caddy.service"
];
wantedBy = [ "multi-user.target" ];
unitConfig = {
ConditionPathIsMountPoint = [
# "/var/lib/immich" # immich data dir.
workdir # immich data dir.
"${workdir}/postgres"
"${workdir}/photos"
"${workdir}/db-dumps"
];
RequiresMountsFor = [
# "/var/lib/immich" # immich data dir.
workdir # immich data dir.
"${workdir}/postgres"
"${workdir}/photos"
"${workdir}/db-dumps"
];
};
serviceConfig = {
ExecStartPre = "${cmd} down";
ExecStart = "${cmd} up --remove-orphans";
ExecStop = "${cmd} stop";
RestartSec = 30;
Nice = -3;
IOSchedulingClass = 1;
IOSchedulingPriority = 0;
CapabilityBoundingSet = "~CAP_SYS_ADMIN CAP_SYS_BOOT CAP_SYS_CHROOT CAP_AUDIT_*";
SystemCallFilter = "~memfd_create @reboot @swap @cpu-emulation @debug @module @clock @raw-io @obsolete";
ProtectProc = "invisible";
ProcSubset = "pid";
ReadOnlyPaths = [
"/etc/${srv}"
];
ReadWritePaths = [
workdir
];
#BindPaths = [
# workdir
#];
ProtectSystem = "strict";
PrivateTmp = true;
DeviceAllow = [
# needed for machine learning;
"/dev/dri"
];
# PrivateDevices=true;
# also allow access to standard pseudo
# devices including /dev/null, /dev/zero, /dev/full, /dev/random, and /dev/urandom.
DevicePolicy = "closed";
PrivateUsers = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
};
};
docker = {
wants = [ "multi-user.target" ];
unitConfig = {
ConditionPathIsMountPoint = [
"/var/lib/docker" # baseline.
];
RequiresMountsFor = [
"/var/lib/docker" # baseline.
];
};
};
zfs-zed.serviceConfig = {
LogLevelMax = "notice";
# StandardOutput = lib.mkForce "/dev/null";
StandardOutput = lib.mkForce "null";
StandardError = lib.mkForce "null";
};
tailscaled.serviceConfig = {
LogLevelMax = "notice";
# StandardOutput = "null";
LogsDirectory = "tailscaled";
StandardOutput = "append:%L/stdout.log";
};
NetworkManager-wait-online.serviceConfig.ExecStart = "${pkgs.coreutils}/bin/true";
# dnscrypt-proxy2.serviceConfig = {
# WorkingDirectory = lib.mkForce "/var/lib/dnscrypt-proxy2";
# BindPaths = [
# "/var/lib/dnscrypt-proxy"
# "/var/lib/dnscrypt-proxy2"
# ];
# };
};
services = {
atd.enable = true;
clamav = {
updater.enable = true;
daemon.enable = true;
};
fstrim.enable = true;
fwupd.enable = true;
logind = {
## XXX: deprecated in 25.11
# lidSwitch = "ignore";
# lidSwitchDocked = "ignore";
# extraConfig = "HandlePowerKey=suspend";
# XXX: 25.11
settings.Login = {
HandleLidSwitch = "ignore";
HandlePowerKey = "suspend";
};
};
# nixos-cli.enable = true;
udev.extraRules = ''
# wol
ACTION=="add", SUBSYSTEM=="net", NAME=="en*", RUN+="${pkgs.ethtool}/bin/ethtool -s $name wol g"
'';
# geoclue2.enable = true; # geolocation.
# dbus.enable = true;
# dnscrypt-proxy2.settings.cloaking_rules = config.sops.secrets.dnscrypt-proxy-cloaked.path;
dnscrypt-proxy2.settings.forwarding_rules = config.sops.secrets.dnscrypt-proxy-forwardingRules.path;
# dnscrypt-proxy2.settings.force_tcp = true;
# dnscrypt-proxy2.settings.log_level = 4;
# dnscrypt-proxy2.settings.netprobe_timeout = 30;
# dnscrypt-proxy2.settings.netprobe_address = "144.91.70.62:443";
# flatpak.enable = true;
power-profiles-daemon.enable = true;
prometheus = {
enable = false;
exporters = {
node = {
enable = true;
enabledCollectors = [
"logind"
"systemd"
"sysctl"
"network_route"
"zfs"
];
disabledCollectors = [
"arp"
"tapestats"
];
listenAddress = "${hostName}.${tailnet}";
port = 9100;
};
smartctl = {
enable = true;
listenAddress = "${hostName}.${tailnet}";
devices = [
"/dev/disk/by-id/ata-WDC_WDS240G2G0A-00JH30_19461B800819"
"/dev/disk/by-id/ata-Samsung_SSD_860_EVO_250GB_S4CJNF0NC09806A"
"/dev/disk/by-id/ata-ST16000NM000D-3PC101_ZVTAVVLC"
"/dev/disk/by-id/ata-ST16000NM000D-3PC101_ZVTC8VM9"
"/dev/disk/by-id/ata-ST18000NM000J-2TV103_ZR5CEXVT"
"/dev/disk/by-id/ata-ST18000NM000J-2TV103_ZR5DTF8Y"
"/dev/disk/by-id/ata-ST4000VN006-3CW104_ZW62BE5Z"
"/dev/disk/by-id/ata-ST4000VN008-2DR166_ZGY9EPLY"
"/dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K0CTH0RR"
"/dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K1CY22F0"
];
};
};
};
SystemdJournal2Gelf = {
enable = false;
graylogServer = "loki.tail530c7.ts.net:12201";
};
bazarr = {
enable = true;
# dataDir = "/media/dwl/bazarr";
};
prowlarr = {
enable = true;
# dataDir = "/media/dwl/prowlarr";
};
lidarr = {
enable = true;
# dataDir = "/media/dwl/lidarr";
dataDir = "/var/lib/lidarr";
};
samba-wsdd = {
# This enables autodiscovery on windows since SMB1 (and thus netbios) support was discontinued
enable = true;
openFirewall = true;
};
# ref: https://gist.github.com/vy-let/a030c1079f09ecae4135aebf1e121ea6
samba = {
# package = pkgs.samba4Full;
enable = true;
openFirewall = true;
#settings = {
##global = {
## "workgroup" = "WORKGROUP";
## "guest account" = "nobody";
##};
#"media-ro" = {
# "path" = "/media";
# browsable = "yes";
# "read only" = "yes";
# "guest ok" = "yes";
# "force user" = "root";
# "create mask" = "0640";
# "directory mask" = "0750";
# # "force user" = "username";
# # "force group" = "groupname";
#};
#};
# securityType = "user";
# securityType = "auto";
nmbd.enable = true;
settings = {
global = {
"server role" = "standalone server";
# server smb encrypt = required
# ^^ Note: Breaks `smbclient -L <ip/host> -U%` by default, might require the client to set `client min protocol`?
"server min protocol" = "SMB3_00";
"guest account" = "nobody";
"map to guest" = "Bad User";
"socket options" = "TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192";
"server multi channel support" = "yes";
"aio read size" = 1;
"aio write size" = "1g";
# log level 1
# server signing = mandatory
# client signing = mandatory
};
media = {
path = "/media";
browsable = "yes";
writable = "yes";
"read only" = "no";
"guest ok" = "no";
"valid users" = [
"lokicifs"
"caveman"
"m"
];
# "guest only" = "yes";
"force user" = "root";
# "create mask" = "0640";
# "directory mask" = "0750";
};
# This share allows anonymous (guest) access (RO) without authentication!
media-ro = {
path = "/media";
browsable = "yes";
writable = "no";
"read only" = "yes";
"guest ok" = "yes";
"guest only" = "yes";
# "force user" = "root";
# "create mask" = "0640";
# "directory mask" = "0750";
};
backups-m = {
path = "/backups/m";
# browsable = "yes";
writable = "yes";
"read only" = "no";
"guest ok" = "no";
"guest only" = "no";
"valid users" = [ "m" ];
"force user" = "root";
# "force user" = "root";
# "create mask" = "0640";
# "directory mask" = "0750";
};
smb-back = {
path = "/media/smb-back";
# browsable = "yes";
writable = "yes";
"read only" = "no";
"guest ok" = "yes";
"guest only" = "yes";
# "valid users" = ["m"];
"force user" = "root";
};
};
# XXX: deprecated in 24.11
### enableNmbd = true;
### extraConfig = ''
### server role = standalone server
### # server smb encrypt = required
### # ^^ Note: Breaks `smbclient -L <ip/host> -U%` by default, might require the client to set `client min protocol`?
### server min protocol = SMB3_00
### guest account = nobody
### map to guest = Bad User
### socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
### # log level 1
### # server signing = mandatory
### # client signing = mandatory
### #[media-ro]
### # path = /media
### # read only = yes
### # guest ok = yes
### # guest only = yes
### '';
### shares = {
### #testshare = {
### # path = "/DATA/test";
### # writable = "true";
### # comment = "Hello World!";
### # "guest ok" = "yes";
### #};
### media = {
### path = "/media";
### browsable = "yes";
### writable = "yes";
### "read only" = "no";
### "guest ok" = "no";
### "valid users" = ["lokicifs" "caveman" "m"];
### # "guest only" = "yes";
### "force user" = "root";
### # "create mask" = "0640";
### # "directory mask" = "0750";
### };
### # This share allows anonymous (guest) access (RO) without authentication!
### media-ro = {
### path = "/media";
### browsable = "yes";
### writable = "no";
### "read only" = "yes";
### "guest ok" = "yes";
### "guest only" = "yes";
### # "force user" = "root";
### # "create mask" = "0640";
### # "directory mask" = "0750";
### };
### backups-m = {
### path = "/backups/m";
### # browsable = "yes";
### writable = "yes";
### "read only" = "no";
### "guest ok" = "no";
### "guest only" = "no";
### "valid users" = ["m"];
### "force user" = "root";
### # "force user" = "root";
### # "create mask" = "0640";
### # "directory mask" = "0750";
### };
### };
};
pulseaudio.enable = false;
sanoid = {
enable = true;
interval = "*:0/5";
datasets = {
"zr/userdata" = {
useTemplate = [ "frequent" ];
# recursive = "zfs";
recursive = true;
};
"zr/system/nixos" = {
useTemplate = [ "production" ];
# recursive = "zfs";
recursive = true;
};
"zr/local/nix" = {
useTemplate = [ "production" ];
};
"z0/backups/nebula" = {
useTemplate = [ "production" ];
# frequently = 22;
};
"z0/backups/nebula-gitea" = {
useTemplate = [ "production" ];
# frequently = 22;
};
"z0/backups/m" = {
useTemplate = [ "frequent" ];
recursive = true;
};
"z0/containers/immich" = {
useTemplate = [ "production" ];
# recursive = "zfs";
recursive = true;
};
"z0/media/video" = {
useTemplate = [ "archive" ];
# recursive = "zfs";
recursive = true;
};
"z0/media/music" = {
useTemplate = [ "archive" ];
# recursive = "zfs";
recursive = true;
};
};
};
# TS is enabled in the imported module, this is additional config.
tailscale = {
useRoutingFeatures = "both";
# accept-routes = true;
};
zfs = {
trim.enable = true;
autoScrub = {
enable = true;
# interval = "monthly";
interval = "quarterly";
};
};
};
services.avahi.publish.userServices = true;
#wanderllama.borgmatic = {
# enable = true;
# username = "tw8vh7jl";
# hostname = "tw8vh7jl.repo.borgbase.com";
# directories = ["/home" "/root" "/secrets"];
# excludes = ["/root/.cache" "/home/*/.cache"];
#};
virtualisation = {
libvirtd = {
enable = false;
qemu.swtpm.enable = false; # XXX: fails to build rn.
};
podman = {
enable = true;
extraPackages = [ pkgs.gvisor ];
defaultNetwork.settings = {
dns_enabled = true;
};
# storageDriver = "zfs";
};
docker = {
enable = true;
storageDriver = "zfs";
};
};
# virtualisation.useSecureBoot = true;
# virtualisation.useBootLoader = true; # allows for testing of bootloader.
# virtualisation.podman.enable = true;
# virtualisation.podman.storageDriver = "zfs";
wanderllama.nebulaBackup = {
enable = true;
dstPath = "/backups/nebula";
dstPathGitea = "/backups/nebula-gitea";
privKey = config.sops.secrets.nixbldr-priv.path;
# bwLimit = 1000;
bwLimit = 10000;
};
hardware = {
cpu.intel.updateMicrocode = true;
enableRedistributableFirmware = true;
mcelog.enable = true;
bluetooth.enable = false;
#fancontrol = {
# enable = true;
# config = ''
# '';
#};
intel-gpu-tools.enable = true;
graphics = {
# Mesa
enable = true;
# Vulkan
# XXX: deprecated in 24.11
# driSupport = true;
# extraPackages = with pkgs; [
# vaapiVdpau
# libvdpau-va-gl
# ];
# extraPackages = [
# pkgs.amdvlk
# ];
extraPackages = with pkgs; [
vpl-gpu-rt # for newer GPUs on NixOS >24.05 or unstable
# onevpl-intel-gpu # for newer GPUs on NixOS <= 24.05
intel-media-driver
intel-compute-runtime
# intel-media-sdk # for older GPUs
];
};
};
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
# Does not work with flakes - yetâ„¢.
system.copySystemConfiguration = false;
# system.stateVersion = lib.mkForce "23.11";
}