# # Server module — import this instead of configuration_server.nix + manual virtualisation imports. # # Usage in hosts//default.nix: # # imports = [ # ./hardware-configuration.nix # ../../modules/server # ]; # # myServer.virtualisation.enable = true; # myServer.virtualisation.cpu = "amd"; # amd | intel | none (default) # # myServer.sshPort = 2220; # default # myServer.fail2ban.enable = true; # # myServer.extraSystemPackages = with pkgs; [ some-tool ]; # { config, lib, pkgs, user, ... }: let cfg = config.myServer; in { # ── Options ────────────────────────────────────────────────────────────── options.myServer = with lib; { uid = mkOption { type = types.int; default = 3000; description = "UID for the server user."; }; sshPort = mkOption { type = types.port; default = 2220; description = "Port openssh listens on."; }; sudoRequiresPassword = mkOption { type = types.bool; default = true; description = "Whether wheel users must enter a password for sudo."; }; autoUpgrade.enable = mkOption { type = types.bool; default = true; description = "Enable automatic NixOS upgrades (inherits flake URL from configuration_common.nix)."; }; virtualisation = { enable = mkEnableOption "container/VM stack (podman with docker-compat, KVM tuning)"; cpu = mkOption { type = types.enum [ "amd" "intel" "none" ]; default = "none"; description = "CPU type — selects KVM kernel parameters when virtualisation is enabled."; }; }; extraGroups = mkOption { type = types.listOf types.str; default = []; description = "Additional groups for the server user beyond the defaults."; }; extraSystemPackages = mkOption { type = types.listOf types.package; default = []; description = "Additional system packages specific to this host."; }; fail2ban = { enable = mkEnableOption "fail2ban intrusion prevention"; }; }; # ── Configuration ──────────────────────────────────────────────────────── config = lib.mkMerge [ # ── Base server config ──────────────────────────────────────────────── { users.users.${user} = { isNormalUser = true; uid = cfg.uid; extraGroups = [ "wheel" "networkmanager" "kvm" "libvirtd" ] ++ cfg.extraGroups; }; security.sudo.wheelNeedsPassword = cfg.sudoRequiresPassword; environment.systemPackages = with pkgs; [ ffmpeg smartmontools htop ] ++ cfg.extraSystemPackages; services.openssh = { ports = [ cfg.sshPort ]; openFirewall = true; }; nix.extraOptions = '' keep-outputs = true keep-derivations = true ''; system.autoUpgrade.enable = cfg.autoUpgrade.enable; } # ── Virtualisation (podman/docker-compat) ───────────────────────────── (lib.mkIf cfg.virtualisation.enable { virtualisation.podman = { enable = true; autoPrune.enable = true; dockerCompat = true; }; users.groups.docker.members = [ user ]; }) # ── KVM – AMD ───────────────────────────────────────────────────────── (lib.mkIf (cfg.virtualisation.enable && cfg.virtualisation.cpu == "amd") { boot.extraModprobeConfig = '' options kvm_amd nested=0 avic=1 npt=1 ''; }) # ── KVM – Intel ─────────────────────────────────────────────────────── (lib.mkIf (cfg.virtualisation.enable && cfg.virtualisation.cpu == "intel") { boot.extraModprobeConfig = '' options kvm_intel nested=1 options kvm_intel emulate_invalid_guest_state=0 options kvm ignore_nsrs=1 ''; }) # ── Fail2ban ────────────────────────────────────────────────────────── (lib.mkIf cfg.fail2ban.enable { services.fail2ban = { enable = true; maxretry = 5; jails.DEFAULT.settings.findtime = "15m"; }; }) ]; }