major refactor

This commit is contained in:
Henri Dohmen 2025-12-23 23:05:32 +01:00
parent 20472f8d1b
commit d778875a1b
Signed by: hd
GPG key ID: AB79213B044674AE
32 changed files with 495 additions and 428 deletions

30
mod/build-machines.nix Normal file
View file

@ -0,0 +1,30 @@
{ lib, config, ... }:
with lib;
{
options.hd.buildMachines.enable = mkEnableOption "Use standard remote builders";
config = mkIf config.hd.buildMachines.enable {
nix = {
buildMachines = [
{
hostName = "noravm"; # TODO: do not rely on mutable ssh config
sshUser = "nixremote";
system = "x86_64-linux";
protocol = "ssh-ng";
maxJobs = 32;
speedFactor = 2;
supportedFeatures = [
"nixos-test"
"benchmark"
"big-parallel"
"kvm"
];
mandatoryFeatures = [ ];
}
];
distributedBuilds = true;
extraOptions = ''
builders-use-substitutes = true
'';
};
};
}

71
mod/common/default.nix Normal file
View file

@ -0,0 +1,71 @@
{
var,
inputs,
lib,
config,
...
}:
with lib;
{
options.hd.common.enable = mkOption {
type = types.bool;
default = true;
description = "Common options that are used on every host by default.";
};
options.hd.common = {
locale = {
enable = mkOption {
type = types.bool;
default = config.hd.common.enable;
description = "Enable locale settings";
};
};
nix = {
enable = mkOption {
type = types.bool;
default = config.hd.common.enable;
description = "Enable Nix-related configuration";
};
};
security = {
enable = mkOption {
type = types.bool;
default = config.hd.common.enable;
description = "Enable security-related configuration";
};
};
shell = {
enable = mkOption {
type = types.bool;
default = config.hd.common.enable;
description = "Enable basic shell utilities";
};
};
users = {
enable = mkOption {
type = types.bool;
default = config.hd.common.enable;
description = "Enable default user accounts";
};
};
};
imports = [
inputs.agenix.nixosModules.default
./locale.nix
./nix.nix
./security.nix
./shell.nix
./users.nix
];
config = mkIf config.hd.common.enable {
environment.defaultPackages = [ ];
networking.extraHosts = var.lan-dns.hostsFile;
};
}

28
mod/common/locale.nix Normal file
View file

@ -0,0 +1,28 @@
{ config, lib, ... }:
with lib;
{
config = mkIf config.hd.common.locale.enable {
time.timeZone = "Europe/Berlin";
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "de_DE.UTF-8";
LC_IDENTIFICATION = "de_DE.UTF-8";
LC_MEASUREMENT = "de_DE.UTF-8";
LC_MONETARY = "de_DE.UTF-8";
LC_NAME = "de_DE.UTF-8";
LC_NUMERIC = "de_DE.UTF-8";
LC_PAPER = "de_DE.UTF-8";
LC_TELEPHONE = "de_DE.UTF-8";
LC_TIME = "de_DE.UTF-8";
};
console.keyMap = "de";
# Configure keymap in X11
services.xserver.xkb = {
layout = "de";
variant = "";
};
};
}

24
mod/common/nix.nix Normal file
View file

@ -0,0 +1,24 @@
{
lib,
inputs,
config,
...
}:
with lib;
{
config = mkIf config.hd.common.nix.enable {
nix.settings = {
experimental-features = [
"nix-command"
"flakes"
];
trusted-users = [ "root" ];
auto-optimise-store = true;
};
nix.registry = {
hd.flake = inputs.self;
nixpkgs.flake = inputs.nixpkgs;
};
nixpkgs.config.allowUnfree = false;
};
}

104
mod/common/security.nix Normal file
View file

@ -0,0 +1,104 @@
{
config,
lib,
pkgs,
...
}:
with lib;
{
config = mkIf config.hd.common.security.enable {
boot = {
kernel.sysctl = {
"net.ipv4.icmp_ignore_bogus_error_responses" = 1;
"net.ipv4.conf.default.rp_filter" = 1;
"net.ipv4.conf.all.rp_filter" = 1;
"net.ipv4.conf.all.accept_source_route" = 0;
"net.ipv6.conf.all.accept_source_route" = 0;
"net.ipv4.conf.all.send_redirects" = 0;
"net.ipv4.conf.default.send_redirects" = 0;
"net.ipv4.conf.all.accept_redirects" = 0;
"net.ipv4.conf.default.accept_redirects" = 0;
"net.ipv4.conf.all.secure_redirects" = 0;
"net.ipv4.conf.default.secure_redirects" = 0;
"net.ipv6.conf.all.accept_redirects" = 0;
"net.ipv6.conf.default.accept_redirects" = 0;
"net.ipv4.tcp_syncookies" = 1;
"net.ipv4.tcp_rfc1337" = 1;
"net.ipv4.tcp_fastopen" = 3;
"kernel.kptr_restrict" = 2;
"randomize_kstack_offset" = "on";
"spec_store_bypass_disable" = "on";
};
# otherwise /tmp is on disk. This *may* be problematic as nix
# builds in /tmp but I think my swap is large enough...
tmp.useTmpfs = lib.mkDefault true;
tmp.cleanOnBoot = lib.mkDefault (!config.boot.tmp.useTmpfs);
kernelParams = [
"init_on_free=1" # zero freed pages
"page_alloc.shuffle=1"
"page_poison=1"
"slab_nomerge"
# "slub_debug=FZ" # disabled due to https://lore.kernel.org/all/20210601182202.3011020-5-swboyd@chromium.org/T/#u
"vsyscall=none" # diable virtual syscalls
];
blacklistedKernelModules = [
"ax25"
"netrom"
"rose"
"adfs"
"affs"
"bfs"
"befs"
"cramfs"
"efs"
"erofs"
"exofs"
"freevxfs"
"f2fs"
"hfs"
"hpfs"
"jfs"
"minix"
"nilfs2"
"ntfs"
"omfs"
"qnx4"
"qnx6"
"sysv"
"ufs"
];
};
networking.firewall.enable = true;
security = {
protectKernelImage = true;
forcePageTableIsolation = true;
apparmor.enable = true;
apparmor.killUnconfinedConfinables = true;
sudo.enable = false;
doas = {
enable = true;
extraRules = [
{
groups = [ "wheel" ];
persist = true;
keepEnv = true;
}
];
};
pki.certificateFiles = [ ../../pki/ca.cert ];
};
};
}

56
mod/common/shell.nix Normal file
View file

@ -0,0 +1,56 @@
{
config,
lib,
pkgs,
inputs,
...
}:
with lib;
{
config = mkIf config.hd.common.shell.enable {
environment.shells = with pkgs; [
bashInteractive
fish
];
environment.systemPackages = with pkgs; [
colmena
dnsutils
fd
htop
killall
nettools
podman-compose
podman-tui
ripgrep
unison
unzip
wget
];
programs = {
fish.enable = true;
tmux = {
enable = true;
clock24 = true;
};
neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
};
};
# --- Excludes ---
programs.nano.enable = false;
# Enabled by fish but takes soooo long.
# This is apparently used by some of fish's
# autocomplete features.
documentation.man.generateCaches = false;
# To stop the annoying error on entering wrong commands
programs.command-not-found.enable = false;
};
}

36
mod/common/users.nix Normal file
View file

@ -0,0 +1,36 @@
{
config,
lib,
options,
pkgs,
secrets,
var,
...
}:
with lib;
{
config = mkIf config.hd.common.users.enable {
age.secrets.hd-password = {
file = secrets."hd-password.age";
};
users = {
mutableUsers = false;
users."hd" = {
description = "Henri";
isNormalUser = true;
createHome = true;
home = "/home/hd";
extraGroups = [ "wheel" ];
shell = pkgs.fish;
packages = [ ];
openssh.authorizedKeys.keys = var.ssh-keys.trusted;
hashedPasswordFile = config.age.secrets.hd-password.path;
};
users.root = {
hashedPassword = "!";
openssh.authorizedKeys.keys = var.ssh-keys.root;
};
};
};
}

View file

@ -1,6 +1,9 @@
{ ... }:
{
imports = [
./build-machines.nix
./common
./desktop
./nginx.nix
];
}

106
mod/desktop/accounts.nix Normal file
View file

@ -0,0 +1,106 @@
{ config, lib, ... }:
let
cfg = config.hd.desktop.accounts;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
home = {
accounts.email.accounts = {
"Posteo" = rec {
primary = true;
address = "henridohmen@posteo.com";
realName = "Henri Dohmen";
smtp = {
tls.enable = true;
host = "posteo.de";
port = 465;
};
imap = {
tls.enable = true;
host = "posteo.de";
port = 993;
};
userName = address;
thunderbird.enable = true;
gpg.key = "AB79213B044674AE";
};
"Uni" = {
address = "henri.dohmen@stud.tu-darmstadt.de";
realName = "Henri Dohmen";
smtp = {
tls.enable = true;
host = "smtp.tu-darmstadt.de";
port = 465;
};
imap = {
tls.enable = true;
host = "imap.stud.tu-darmstadt.de";
port = 993;
};
userName = "hd48xebi";
thunderbird.enable = true;
gpg.key = "24FCE000F3470BAC";
};
"Proton" = rec {
address = "dohmenhenri@proton.me";
realName = "Henri Dohmen";
smtp = {
tls.enable = true;
tls.useStartTls = true;
host = "127.0.0.1";
port = 1025;
};
imap = {
tls.enable = true;
tls.useStartTls = true;
host = "127.0.0.1";
port = 1143;
};
userName = address;
thunderbird.enable = true;
gpg.key = "AB79213B044674AE";
};
};
accounts.calendar.accounts = {
"Privat" = {
primary = true;
thunderbird = {
enable = true;
color = "#DC8ADD";
};
remote = {
type = "caldav";
url = "https://posteo.de:8443/calendars/henridohmen/default";
userName = "henridohmen";
};
};
"Uni" = {
thunderbird = {
enable = true;
color = "#FFBE6F";
};
remote = {
type = "caldav";
url = "https://posteo.de:8443/calendars/henridohmen/zqrobi";
userName = "henridohmen";
};
};
};
accounts.contact.accounts = {
"Kontakte" = {
thunderbird = {
enable = true;
};
remote = {
type = "carddav";
url = "https://posteo.de:8843/addressbooks/henridohmen/default/";
userName = "henridohmen";
};
};
};
};
};
}

26
mod/desktop/audio.nix Normal file
View file

@ -0,0 +1,26 @@
{
pkgs,
config,
lib,
...
}:
let
cfg = config.hd.desktop.audio;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
environment.systemPackages = with pkgs; [
pavucontrol
alsa-utils
];
services.pulseaudio.enable = false;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
};
}

126
mod/desktop/default.nix Normal file
View file

@ -0,0 +1,126 @@
{
inputs,
lib,
config,
options,
...
}:
with lib;
{
options.home = lib.mkOption {
# used by /home/default.nix
type = lib.types.attrsOf lib.types.str;
default = { };
description = "Home Manager configuration for user `hd`. Has no effect if `/home` is not loaded";
};
options.hd.desktop = {
enable = mkOption {
type = types.bool;
default = false;
description = "Common NixOS configuration of all desktops.";
};
audio = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable audio configuration";
};
};
gpg = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable GPG configuration";
};
};
network = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable network configuration";
};
};
security = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable desktop security configuration";
};
};
software = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable software installation";
};
development = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.software.enable;
description = "Enable development software";
};
};
};
windowManager = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable window manager configuration";
};
};
accounts = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable desktop user accounts";
};
};
fonts = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable font configuration";
};
};
services = {
enable = mkOption {
type = types.bool;
default = config.hd.desktop.enable;
description = "Enable desktop services";
};
};
};
imports = [
./accounts.nix
./audio.nix
./fonts.nix
./gpg.nix
./network.nix
./security.nix
./services.nix
./software
./window-manager.nix
];
config = mkIf config.hd.desktop.enable {
nixpkgs.config.allowUnfreePredicate =
pkg:
builtins.elem (lib.getName pkg) [
"nvidia-x11"
];
programs.nix-ld.enable = true;
};
}

24
mod/desktop/fonts.nix Normal file
View file

@ -0,0 +1,24 @@
{
pkgs,
config,
lib,
...
}:
let
cfg = config.hd.desktop.fonts;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
fonts = {
packages = with pkgs; [
noto-fonts
noto-fonts-cjk-sans
noto-fonts-color-emoji
nerd-fonts.noto
];
fontDir.enable = true;
fontconfig.defaultFonts.monospace = [ "Noto Nerd Font Mono" ];
};
};
}

38
mod/desktop/gpg.nix Normal file
View file

@ -0,0 +1,38 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.hd.desktop.gpg;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
home = {
home.packages = with pkgs; [
libsecret
gnome-keyring
];
programs.gpg = {
enable = true;
publicKeys = [
{
source = ../../pgp/id-priv.pgp;
trust = 5;
}
{
source = ../../pgp/id-uni.pgp;
trust = 5;
}
];
};
services.gpg-agent = {
enable = true;
enableSshSupport = true;
pinentry.package = pkgs.pinentry-gtk2;
};
};
};
}

86
mod/desktop/network.nix Normal file
View file

@ -0,0 +1,86 @@
{
config,
host,
lib,
pkgs,
var,
...
}:
let
cfg = config.hd.desktop.network;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
hardware.bluetooth.enable = true;
systemd.network.wait-online.enable = false;
services = {
mullvad-vpn.enable = true;
blueman.enable = true;
resolved = {
# TODO: find out why doh breaks moodle...
enable = true;
};
};
networking = {
enableIPv6 = true;
wireguard.enable = true;
wg-quick = {
interfaces = {
"onet" = {
address = var.wg.wireguard-network.${host}.ips;
privateKeyFile = var.wg.keyFile;
peers = [ (lib.removeAttrs var.wg.wireguard-network."roam" [ "ips" ]) ];
mtu = 1248;
};
};
};
networkmanager = {
enable = true;
plugins = with pkgs; [ networkmanager-openconnect ];
wifi.macAddress = "random";
ensureProfiles.profiles = {
"tuda-vpn" = {
connection = {
autoconnect = "false";
id = "tuda-vpn";
type = "vpn";
};
ipv4 = {
method = "auto";
};
ipv6 = {
addr-gen-mode = "stable-privacy";
method = "auto";
};
vpn = {
authtype = "password";
autoconnect-flags = "0";
certsigs-flags = "0";
cookie-flags = "2";
disable_udp = "no";
enable_csd_trojan = "no";
gateway = "vpn.hrz.tu-darmstadt.de";
gateway-flags = "2";
gwcert-flags = "2";
lasthost-flags = "0";
pem_passphrase_fsid = "no";
prevent_invalid_cert = "no";
protocol = "anyconnect";
resolve-flags = "2";
service-type = "org.freedesktop.NetworkManager.openconnect";
stoken_source = "disabled";
xmlconfig-flags = "0";
password-flags = 0;
};
};
};
};
};
};
}

21
mod/desktop/security.nix Normal file
View file

@ -0,0 +1,21 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.hd.desktop.security;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
security.pam = {
services.login.enableGnomeKeyring = true;
};
services = {
gnome.gnome-keyring.enable = true;
};
programs.seahorse.enable = true;
};
}

49
mod/desktop/services.nix Normal file
View file

@ -0,0 +1,49 @@
{
pkgs,
lib,
config,
...
}:
let
cfg = config.hd.desktop.services;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
services = {
printing.enable = true;
avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
udisks2.enable = true;
};
home.services.protonmail-bridge = {
enable = true;
extraPackages = with pkgs; [
pass
gnome-keyring
];
};
home.services = {
emacs.enable = true;
unison' = {
# TODO: parameterize
enable = true;
pairs = {
"docs".roots = [
"/home/hd/Documents"
"ssh://roam.lan//home/hd/Documents"
];
"desktop".roots = [
"/home/hd/Desktop"
"ssh://roam.lan//home/hd/Desktop"
];
};
};
};
};
}

View file

@ -0,0 +1,143 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.hd.desktop.software;
inherit (lib) mkEnableOption mkIf;
in
{
imports = [ ./development.nix ];
config = mkIf cfg.enable {
hd.desktop.software.development.enable = true;
environment.systemPackages = with pkgs; [
bitwarden-desktop
calibre
file
fuzzel
gh
nil
pciutils
signal-desktop
spotify-player
tor-browser
usbutils
vlc
wireguard-tools
wl-clipboard
yt-dlp
zotero
zulip
];
virtualisation = {
podman = {
enable = true;
dockerCompat = true;
defaultNetwork.settings.dns_enabled = true;
};
};
programs.kdeconnect.enable = true;
home = {
programs.fish = {
enable = true;
interactiveShellInit = ''
set -U fish_greeting
starship init fish | source
'';
};
programs.starship = {
enable = true;
enableFishIntegration = true;
settings = {
format = "[$username](green)@[$hostname](red)[\\[$directory\\]](cyan bold) $all";
username = {
show_always = true;
format = "$user";
};
hostname = {
ssh_only = false;
format = "$hostname";
};
directory.format = "$path";
character = {
format = "$symbol ";
success_symbol = "\\\$";
error_symbol = "[\\\$](red)";
};
git_branch.format = "[$symbol$branch(:$remote_branch)]($style)";
};
};
programs.librewolf = {
enable = true;
settings = {
"identity.fxaccounts.enabled" = true;
"identity.sync.tokenserver.uri" = "https://firefox-syncserver.roam.hdohmen.de/1.0/sync/1.5";
"privacy.resistFingerprinting" = true;
"signon.rememberSignons" = false;
"signon.autofillForms" = false;
"privacy.spoof_english" = 2;
"privacy.resistFingerprinting.block_mozAddonManager" = true;
"network.http.sendRefererHeader" = 1;
"intl.accept_languages" = "en,en-us";
"privacy.resistFingerprinting.letterboxing" = true;
};
};
programs.thunderbird = {
enable = true;
package = pkgs.thunderbird-latest;
profiles.default = {
isDefault = true;
withExternalGnupg = true;
settings = {
"intl.date_time.pattern_override.date_short" = "yyyy-MM-dd";
"mail.html_compose" = false;
"mail.identity.default.compose_html" = false;
};
};
};
programs.git = {
enable = true;
signing = {
signByDefault = true;
signer = "openpgp";
key = "AB79213B044674AE";
};
settings = {
user.name = "Henri Dohmen";
user.email = "henridohmen@posteo.com";
color.ui = "auto";
column.ui = "auto";
branch.sort = "-committerdate";
alias = {
staash = "stash --all";
};
core = {
editor = "nvim";
autocrlf = "input";
};
init.defaultBranch = "main";
credential.helper = "libsecret";
};
};
programs.foot = {
enable = true;
server.enable = true;
settings = {
main = {
"font" = "monospace:size=11";
};
};
};
};
# Some excludes
services.xserver.excludePackages = [ pkgs.xterm ];
};
}

View file

@ -0,0 +1,112 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.hd.desktop.software.development;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
documentation.dev.enable = true;
environment.systemPackages = with pkgs; [
(agda.withPackages (p: [ p.standard-library ]))
binutils
clang
elan
gcc
gdb
gnumake
man-pages
man-pages-posix
nixfmt-rfc-style
python313
python313Packages.mypy
rustup
# jetbrains.gateway
# jetbrains.rust-rover
];
home = {
xdg.configFile = {
"agda/libraries".text = ''
${pkgs.agdaPackages.standard-library}/standard-library.agda-lib
'';
};
programs.emacs = {
enable = true;
extraPackages =
epkgs: with epkgs; [
ace-window
agda2-mode
better-defaults
cmake-mode
company
consult
delight
doom-themes
editorconfig
exec-path-from-shell
fish-mode
haskell-mode
hl-todo
lsp-mode
magit
marginalia
markdown-mode
multiple-cursors
orderless
proof-general
pyvenv
rainbow-delimiters
restart-emacs
rust-mode
undo-tree
use-package
vertico
which-key
yaml-mode
];
extraConfig = builtins.readFile ../../../dotfiles/emacs/init.el;
};
programs.vscode = {
enable = true;
package = pkgs.vscodium;
mutableExtensionsDir = true;
profiles.default = {
enableExtensionUpdateCheck = true;
enableUpdateCheck = false;
extensions = with pkgs.vscode-marketplace; [
banacorn.agda-mode
dnut.rewrap-revived
editorconfig.editorconfig
james-yu.latex-workshop
jnoortheen.nix-ide
leanprover.lean4
ltex-plus.vscode-ltex-plus
maximedenes.vscoq
mkhl.direnv
ms-python.python
ms-toolsai.jupyter
ocamllabs.ocaml-platform
rust-lang.rust-analyzer
# ms-vscode-remote.remote-ssh
];
userSettings = {
"editor.rulers" = [ 80 ];
"editor.formatOnPaste" = false;
"editor.formatOnSave" = false;
"editor.formatOnType" = false;
# https://github.com/nix-community/nix-vscode-extensions/issues/123
"ltex.ltex-ls.path" = "${pkgs.ltex-ls-plus}";
"direnv.path.executable" = "${pkgs.direnv}/bin/direnv";
"latex-workshop.latex.autoBuild.run" = "never";
};
};
};
};
};
}

View file

@ -0,0 +1,20 @@
{
pkgs,
config,
lib,
...
}:
let
cfg = config.hd.desktop.windowManager;
inherit (lib) mkEnableOption mkIf;
in
{
config = mkIf cfg.enable {
# Enable the KDE Plasma Desktop Environment.
services.displayManager.sddm = {
enable = true;
wayland.enable = true;
};
services.desktopManager.plasma6.enable = true;
};
}