{ 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"; }; # All modules are imported but non-essential modules are activated by # configuration options imports = [ ../pkgs/modules.nix ./ausweisapp.nix ./cups.nix ./docker.nix ./fancontrol.nix ./fonts.nix ./games.nix ./grub.nix ./gui.nix ./initrd-ssh.nix ./locales.nix ./logitech.nix ./mailserver.nix ./media-mount.nix ./media-proxy.nix ./mullvad ./network-manager.nix ./nginx-interactive-index ./nginx.nix ./nix.nix ./office.nix ./pipewire.nix ./prometheus/node_exporter.nix ./pubkeys.nix ./qbittorrent ./restic ./secrets.nix ./ssh.nix ./syncthing.nix ./tmux.nix ./tools.nix ./udev.nix ./unfree.nix ./wireguard ]; 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 vim ]; # Clean temporary files on boot boot.cleanTmpDir = 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; # Hard drive monitoring services.smartd.enable = lib.mkDefault true; # Network monitoring services.vnstat.enable = true; # Support for exotic file systems boot.supportedFilesystems = lib.optional config.sbruder.full "ntfs"; # Authentication/Encryption agents programs.gnupg.agent.enable = true; programs.ssh.startAgent = true; # 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; }; }; # Globally set Let’s Encrypt requirements security.acme = { acceptTerms = true; defaults = { email = "security@sbruder.de"; }; }; system.activationScripts.diff = '' [ -L /run/current-system ] && ${pkgs.nixFlakes}/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 ''; }; } (lib.mkIf config.sbruder.full { services.fwupd.enable = true; }) (lib.mkIf (!config.sbruder.full) { documentation.enable = lib.mkDefault false; }) ]; }