187 lines
5.5 KiB
Nix
187 lines
5.5 KiB
Nix
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de>
|
||
#
|
||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||
|
||
{ config, lib, options, pkgs, ... }:
|
||
|
||
{
|
||
# Options that affect multiple modules
|
||
options.sbruder = {
|
||
full = lib.mkOption {
|
||
type = lib.types.bool;
|
||
description = ''
|
||
Whether to build the full system. If disabled, the system closure will
|
||
be smaller, but some features will not be available.
|
||
'';
|
||
default = true;
|
||
};
|
||
trusted = (lib.mkEnableOption "the trusted status of this machine (i.e. encrypted root)") // { default = true; };
|
||
gui.enable = lib.mkEnableOption "gui";
|
||
machine = {
|
||
isVm = lib.mkOption {
|
||
type = lib.types.bool;
|
||
description = "Whether this machine is a virtual machine.";
|
||
default = false;
|
||
};
|
||
};
|
||
};
|
||
|
||
# All modules are imported but non-essential modules are activated by
|
||
# configuration options
|
||
imports = [
|
||
../pkgs/modules.nix
|
||
./ausweisapp.nix
|
||
./authoritative-dns.nix
|
||
./cups.nix
|
||
./fancontrol.nix
|
||
./flatpak.nix
|
||
./fonts.nix
|
||
./games.nix
|
||
./grub.nix
|
||
./gui.nix
|
||
./infovhost.nix
|
||
./initrd-ssh.nix
|
||
./locales.nix
|
||
./logitech.nix
|
||
./mailserver
|
||
./media-mount.nix
|
||
./media-proxy.nix
|
||
./mullvad
|
||
./network-manager.nix
|
||
./nginx-interactive-index
|
||
./nginx.nix
|
||
./nitrokey.nix
|
||
./nix.nix
|
||
./office.nix
|
||
./pipewire.nix
|
||
./podman.nix
|
||
./prometheus/node_exporter.nix
|
||
./prometheus/smartctl_exporter.nix
|
||
./pubkeys.nix
|
||
./qbittorrent
|
||
./restic
|
||
./secrets.nix
|
||
./ssh.nix
|
||
./static-webserver.nix
|
||
./syncthing.nix
|
||
./tmux.nix
|
||
./tools.nix
|
||
./udev.nix
|
||
./unfree.nix
|
||
./wireguard
|
||
./wkd
|
||
];
|
||
|
||
config = lib.mkMerge [
|
||
{
|
||
# Essential system tools
|
||
environment.systemPackages = with pkgs; [
|
||
git
|
||
git-crypt # used to store secrets in configuration
|
||
git-lfs # not so essential, but required to clone config
|
||
htop
|
||
tmux
|
||
];
|
||
|
||
programs.nano.enable = false;
|
||
programs.vim.defaultEditor = true;
|
||
|
||
# Clean temporary files on boot
|
||
boot.tmp.cleanOnBoot = true;
|
||
|
||
# Set zsh as default shell with reasonable default config for all users
|
||
programs.zsh = {
|
||
enable = true;
|
||
loginShellInit = ''
|
||
# do not glob # (conflicts with nix flakes)
|
||
disable -p '#'
|
||
'';
|
||
histSize = 100000;
|
||
};
|
||
users.defaultUserShell = pkgs.zsh;
|
||
environment.etc."zshrc.local".source = "${pkgs.grml-zsh-config}/etc/zsh/zshrc";
|
||
|
||
# command-not-found does not work without channels
|
||
programs.command-not-found.enable = false;
|
||
|
||
# Network monitoring
|
||
services.vnstat.enable = true;
|
||
environment.etc."vnstat.conf".text = ''
|
||
UseUTC=1
|
||
'';
|
||
|
||
# Support for exotic file systems
|
||
boot.supportedFilesystems = lib.optional config.sbruder.full "ntfs";
|
||
|
||
programs.ssh.startAgent = lib.mkDefault (!config.sbruder.gui.enable);
|
||
|
||
# When this is set to true (default), routing everything through a
|
||
# wireguard tunnel does not work.
|
||
networking.firewall.checkReversePath = false;
|
||
|
||
# Open ports for quick tests
|
||
networking.firewall = {
|
||
allowedTCPPortRanges = lib.singleton { from = 9990; to = 9999; };
|
||
allowedUDPPortRanges = lib.singleton { from = 9990; to = 9999; };
|
||
};
|
||
|
||
# Use nftables by default,
|
||
# but allow it to be easily disabled on by-machine basis.
|
||
networking.nftables.enable = lib.mkDefault true;
|
||
|
||
# Globally set Let’s Encrypt requirements
|
||
security.acme = {
|
||
acceptTerms = true;
|
||
defaults = {
|
||
email = "security@sbruder.de";
|
||
};
|
||
};
|
||
|
||
system.activationScripts.diff = ''
|
||
[ -L /run/current-system ] && ${config.nix.package}/bin/nix \
|
||
--experimental-features 'nix-command' \
|
||
store \
|
||
diff-closures /run/current-system "$systemConfig"
|
||
'';
|
||
|
||
# Allow users to set allow_other for fuse mounts
|
||
programs.fuse.userAllowOther = true;
|
||
|
||
i18n.supportedLocales = (options.i18n.supportedLocales.default) ++ (lib.optionals config.sbruder.full [
|
||
"de_DE.UTF-8/UTF-8"
|
||
]);
|
||
|
||
services.resolved = {
|
||
# Set systemd-resolved’s fallback to Quad9 (instead of cloudflare/google)
|
||
fallbackDns = [ "9.9.9.9" "149.112.112.112" "2620:fe::fe" "2620:fe::9" ];
|
||
# Allow resolving single lable hostnames (e.g., hostnames on the local network)
|
||
llmnr = "false";
|
||
# resolved does not automatically append the search domain (for whatever reason)
|
||
extraConfig = ''
|
||
ResolveUnicastSingleLabel=yes
|
||
Cache=no-negative
|
||
'';
|
||
};
|
||
}
|
||
(lib.mkIf (!config.sbruder.machine.isVm) {
|
||
# Hard drive monitoring
|
||
services.smartd.enable = lib.mkDefault true;
|
||
# Firmware updates (only work on EFI systems, so enable only when using systemd-boot)
|
||
services.fwupd.enable = lib.mkDefault (config.boot.loader.systemd-boot.enable);
|
||
})
|
||
(lib.mkIf (!config.sbruder.full) {
|
||
documentation.enable = lib.mkDefault false;
|
||
})
|
||
(lib.mkIf (config.services.resolved.enable) {
|
||
# With NixOS’s default database order for hosts,
|
||
# resolving the FQDN with hostname -f always returns “localhost”
|
||
# when resolved is enabled.
|
||
# This changes the priority of the files database,
|
||
# which fixes this.
|
||
# This workaround was taken from
|
||
# https://github.com/NixOS/nixpkgs/issues/132646#issuecomment-1782684381
|
||
system.nssDatabases.hosts = lib.mkOrder 500 [ "files" ];
|
||
})
|
||
];
|
||
}
|