1205 lines
32 KiB
Nix
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";
|
|
}
|