diff --git a/system/flake.nix b/system/flake.nix index 691f807..30d0e78 100644 --- a/system/flake.nix +++ b/system/flake.nix @@ -51,16 +51,8 @@ ./modules/vfio.nix ./modules/ccache.nix ./modules/impermanence.nix + ./modules/common.nix impermanence.nixosModule - { - # make this flake's nixpkgs available to the whole system - nix = { - generateNixPathFromInputs = true; - generateRegistryFromInputs = true; - linkInputs = true; - }; - nixpkgs.overlays = [ (self: super: import ./pkgs { pkgs = super; inherit lib; }) ]; - } ]; hosts = { nixmsi = mkHost { diff --git a/system/hosts/nixmsi.nix b/system/hosts/nixmsi.nix index e9f79da..8bf0e46 100644 --- a/system/hosts/nixmsi.nix +++ b/system/hosts/nixmsi.nix @@ -65,7 +65,6 @@ in { # resume_offset = $(btrfs inspect-internal map-swapfile -r path/to/swapfile) "resume_offset=533760" "fbcon=font:TER16x32" - "consoleblank=60" # disable PSR to *hopefully* avoid random hangs # this one didnt help "amdgpu.dcdebugmask=0x10" @@ -102,25 +101,16 @@ in { nixpkgs.config.allowUnfreePredicate = pkg: (lib.getName pkg) == "steam-original"; hardware = { steam-hardware.enable = true; - enableRedistributableFirmware = true; opengl.driSupport32Bit = true; # needed for sway WLR_RENDERER=vulkan opengl.extraPackages = with pkgs; [ vulkan-validation-layers ]; }; - services.openssh = { - enable = true; - settings.PasswordAuthentication = false; - }; + # services.openssh.enable = true; services.tlp.enable = true; - services.tlp.settings = { - USB_EXCLUDE_PHONE = 1; - START_CHARGE_THRESH_BAT0 = 75; - STOP_CHARGE_THRESH_BAT0 = 80; - # fix for my realtek usb ethernet adapter - USB_DENYLIST = "0bda:8156"; - }; + # fix for my realtek usb ethernet adapter + services.tlp.settings.USB_DENYLIST = "0bda:8156"; # see modules/vfio.nix vfio.enable = true; @@ -190,15 +180,6 @@ in { }; ### SECTION 2: SYSTEM CONFIG/ENVIRONMENT ### - i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; - i18n.supportedLocales = lib.mkDefault [ - "C.UTF-8/UTF-8" - "en_US.UTF-8/UTF-8" - "en_DK.UTF-8/UTF-8" - ]; - # ISO-8601 - i18n.extraLocaleSettings.LC_TIME = "en_DK.UTF-8"; - console.font = "${pkgs.terminus_font}/share/consolefonts/ter-v32n.psf.gz"; networking.useDHCP = true; @@ -213,7 +194,6 @@ in { networking.firewall.allowedUDPPorts = lib.range 1714 1764; networking.wireless.iwd.enable = true; - #networking.networkmanager.enable = true; services.ratbagd.enable = true; @@ -239,111 +219,22 @@ in { environment.etc."system76-scheduler/exceptions.ron".source = "${pkgs.system76-scheduler}/etc/system76-scheduler/exceptions.ron"; - # i wanted to be able to use both x and wayland... but honestly wayland is enough for me - services.xserver.libinput.enable = true; - /* - services.xserver = { - enable = true; - libinput.enable = true; - desktopManager.xterm.enable = false; - # I couldn't get lightdm to start sway, so let's just do this - displayManager.startx.enable = true; - windowManager.i3.enable = true; - }; - */ - - programs.sway.enable = true; - programs.firejail.enable = true; + common.workstation = true; + common.gettyAutologin = true; + # programs.firejail.enable = true; # doesn't work: # programs.wireshark.enable = true; # users.groups.wireshark.members = [ "user "]; - environment.systemPackages = with pkgs; [ - vim - wget - git - man-pages man-pages-posix - ]; - services.dbus.enable = true; - # I don't remember whether I really need this... - security.polkit.enable = true; services.printing.enable = true; - - # pipewire: - security.rtkit.enable = true; - services.pipewire = { + # from nix-gaming + services.pipewire.lowLatency = { enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - jack.enable = true; - # from nix-gaming - lowLatency = { - enable = true; - # 96 is mostly fine but has some xruns - # 128 has xruns every now and then too, but is overall fine - quantum = 128; - rate = 48000; - }; + # 96 is mostly fine but has some xruns + # 128 has xruns every now and then too, but is overall fine + quantum = 128; + rate = 48000; }; - # environment.pathsToLink = [ "/share/zsh" "/share/fish" ]; - programs.fish = { - enable = true; - }; - /*programs.zsh = { - enable = true; - enableBashCompletion = true; - };*/ - - programs.fuse.userAllowOther = true; - programs.ccache.enable = true; - - xdg.portal = { - enable = true; - extraPortals = with pkgs; [ xdg-desktop-portal-gtk xdg-desktop-portal-wlr ]; - }; - - users.mutableUsers = false; - users.users.user = { - uid = 1000; - isNormalUser = true; - extraGroups = [ "networkmanager" "wheel" ]; - # initialHashedPassword = ...set in private.nix; - }; - # users.users.root.initialHashedPassword = ...set in private.nix; - nix = { - settings = { - allowed-users = [ "user" ]; - auto-optimise-store = true; - }; - gc = { - automatic = true; - dates = "weekly"; - options = "--delete-older-than 30d"; - }; - package = pkgs.nixFlakes; - extraOptions = '' - experimental-features = nix-command flakes - ''; - }; - systemd.services.nix-daemon.serviceConfig.LimitSTACKSoft = "infinity"; - - documentation.dev.enable = true; - - # autologin once after boot - # --skip-login means directly call login instead of first asking for username - # (normally login asks for username too, but getty prefers to do it by itself for whatever reason) - services.getty.extraArgs = [ "--skip-login" ]; - services.getty.loginProgram = let - lockfile = "/tmp/login-once.lock"; - in with pkgs; writeShellScript "login-once" '' - if [ -f '${lockfile}' ]; then - exec ${shadow}/bin/login $@ - else - ${coreutils}/bin/touch '${lockfile}' - exec ${shadow}/bin/login -f user - fi - ''; } diff --git a/system/hosts/nixserver/default.nix b/system/hosts/nixserver/default.nix index 6be0920..cfc69b6 100644 --- a/system/hosts/nixserver/default.nix +++ b/system/hosts/nixserver/default.nix @@ -43,9 +43,6 @@ in { availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" "sr_mod" "rtsx_pci_sdmmc" ]; }; kernelModules = [ "kvm-intel" ]; - kernelParams = [ - "consoleblank=60" - ]; loader = { grub = { enable = true; @@ -59,7 +56,6 @@ in { efi.efiSysMountPoint = "/boot/efi"; }; }; - hardware.enableRedistributableFirmware = true; fileSystems = { "/" = { device = "none"; fsType = "tmpfs"; neededForBoot = true; options = [ "defaults" "size=2G" "mode=755" ]; }; @@ -95,14 +91,6 @@ in { extraOptions = [ "--loadavg-target" "8.0" ]; }; }; - i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; - i18n.supportedLocales = lib.mkDefault [ - "C.UTF-8/UTF-8" - "en_US.UTF-8/UTF-8" - "en_DK.UTF-8/UTF-8" - ]; - # ISO-8601 - i18n.extraLocaleSettings.LC_TIME = "en_DK.UTF-8"; console.font = "${pkgs.terminus_font}/share/consolefonts/ter-v24n.psf.gz"; networking.useDHCP = true; networking.resolvconf.extraConfig = '' @@ -178,55 +166,30 @@ in { startWhenNeeded = false; }; - programs.fish.enable = true; - users.defaultUserShell = pkgs.fish; - users.users.user = { - isNormalUser = true; - extraGroups = [ "wheel" config.services.unbound.group ]; - }; - - environment.systemPackages = with pkgs; [ - comma - git - vim - wget - # rxvt-unicode-unwrapped.terminfo - kitty.terminfo - tmux - ]; + users.users.user.extraGroups = [ config.services.unbound.group ]; services.postgresql.enable = true; services.postgresql.package = pkgs.postgresql_13; - nix = { - settings = { - allowed-users = [ "user" ]; - auto-optimise-store = true; - }; - gc = { - automatic = true; - dates = "weekly"; - options = "--delete-older-than 30d"; - }; - package = pkgs.nixFlakes; - extraOptions = '' - experimental-features = nix-command flakes - ''; - }; - systemd.services.nix-daemon.serviceConfig.LimitSTACKSoft = "infinity"; - # SSH services.openssh = { enable = true; - # settings.PermitRootLogin = "no"; - settings.PasswordAuthentication = false; - listenAddresses = [{ + # settings.PermitRootLogin = false; + /*listenAddresses = [{ addr = "0.0.0.0"; } { addr = "::"; - }]; + }];*/ + }; + services.fail2ban = { + enable = true; + ignoreIP = lib.optionals (cfg.lanCidrV4 != "0.0.0.0/0") [ cfg.lanCidrV4 ] + ++ (lib.optionals (cfg.lanCidrV6 != "::/0") [ cfg.lanCidrV6 ]); + jails.dovecot = '' + enabled = true + filter = dovecot + ''; }; - services.fail2ban.enable = true; # SEARXNG services.searx.enable = true; @@ -242,14 +205,13 @@ in { services.searx.uwsgiConfig = let inherit (config.services.searx) settings; in { socket = "${lib.quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}"; }; - users.groups.searx.members = [ "nginx" ]; - services.searx.environmentFile = "/etc/nixos/private/searx.env"; + services.searx.environmentFile = /var/lib/searx/searx.env; services.searx.settings = { use_default_settings = true; search = { - safe_search = 0; # Filter results. 0: None, 1: Moderate, 2: Strict - autocomplete = "duckduckgo"; # Existing autocomplete backends: "dbpedia", "duckduckgo", "google", "startpage", "swisscows", "qwant", "wikipedia" - leave blank to turn it off by default - default_lang = ""; # Default search language - leave blank to detect from browser information or use codes from 'languages.py' + safe_search = 0; + autocomplete = "duckduckgo"; # dbpedia, duckduckgo, google, startpage, swisscows, qwant, wikipedia - leave blank to turn off + default_lang = ""; # leave blank to detect from browser info or use codes from languages.py }; server = { @@ -273,10 +235,6 @@ in { pool_maxsize = 10; # Number of allowable keep-alive connections, or null enable_http2 = true; # See https://www.python-httpx.org/http2/ }; - /* = { - name = "soundcloud"; - disabled = true; - };*/ }; services.nginx.virtualHosts."search.${cfg.domainName}" = let inherit (config.services.searx) settings; in { enableACME = true; @@ -292,9 +250,7 @@ in { services.nginx.enable = true; services.nginx.streamConfig = let - cert = config.security.acme.certs."${cfg.domainName}".directory + "/fullchain.pem"; - certKey = config.security.acme.certs."${cfg.domainName}".directory + "/key.pem"; - trustedCert = config.security.acme.certs."${cfg.domainName}".directory + "/chain.pem"; + inherit (config.security.acme.certs."${cfg.domainName}") directory; in '' upstream dns { zone dns 64k; @@ -302,9 +258,9 @@ in { } server { listen 853 ssl; - ssl_certificate ${cert}; - ssl_certificate_key ${certKey}; - ssl_trusted_certificate ${trustedCert}; + ssl_certificate ${directory}/fullchain.pem; + ssl_certificate_key ${directory}/key.pem; + ssl_trusted_certificate ${directory}/chain.pem; proxy_pass dns; } ''; @@ -333,7 +289,7 @@ in { ''; }; }; - + services.nginx.virtualHosts."www.${cfg.domainName}" = { enableACME = true; globalRedirect = cfg.domainName; @@ -372,7 +328,8 @@ in { sendOnly = true; }; services.dovecot2.extraConfig = - let passwd = builtins.toFile "dovecot2-local-passwd" '' + let + passwd = builtins.toFile "dovecot2-local-passwd" '' noreply@${cfg.domainName}:{plain}${cfg.unhashedNoreplyPassword}::::::allow_nets=local,127.0.0.0/8,::1 ''; in '' diff --git a/system/modules/common.nix b/system/modules/common.nix new file mode 100644 index 0000000..5712d16 --- /dev/null +++ b/system/modules/common.nix @@ -0,0 +1,138 @@ +{ lib +, pkgs +, config +, ... }: + +{ + options.common = with lib; mkOption { + type = types.submodule { + options = { + workstation = mkOption { + type = types.bool; + default = false; + description = "whether this device is a workstation (meaning a device for personal use rather than a server)"; + }; + mainUsername = mkOption { + type = types.str; + default = "user"; + description = "main user's username"; + }; + gettyAutologin = mkOption { + type = types.bool; + default = false; + description = "make getty autologin to the main user"; + }; + }; + }; + default = { }; + }; + config = let + cfg = config.common; + in { + nix = { + settings = { + allowed-users = [ cfg.mainUsername ]; + auto-optimise-store = true; + }; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + package = pkgs.nixFlakes; + extraOptions = '' + experimental-features = nix-command flakes + ''; + # from flake-utils-plus: make this flake's nixpkgs available to the whole system + generateNixPathFromInputs = true; + generateRegistryFromInputs = true; + linkInputs = true; + }; + systemd.services.nix-daemon.serviceConfig.LimitSTACKSoft = "infinity"; + boot.kernelParams = [ + "consoleblank=60" + ]; + + nixpkgs.overlays = [ (self: super: import ../pkgs { pkgs = super; inherit lib; }) ]; + hardware.enableRedistributableFirmware = true; + services.openssh.settings.PasswordAuthentication = false; + services.tlp.settings.USB_EXCLUDE_PHONE = 1; + services.tlp.settings.START_CHARGE_THRESH_BAT0 = 75; + services.tlp.settings.STOP_CHARGE_THRESH_BAT0 = 80; + i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; + i18n.supportedLocales = lib.mkDefault [ + "C.UTF-8/UTF-8" + "en_US.UTF-8/UTF-8" + "en_DK.UTF-8/UTF-8" + ]; + # ISO-8601 + i18n.extraLocaleSettings.LC_TIME = "en_DK.UTF-8"; + environment.systemPackages = with pkgs; ([ + wget + git + ] ++ (if cfg.workstation then [ + comma + neovim + man-pages man-pages-posix + ] else [ + kitty.terminfo + # rxvt-unicode-unwrapped.terminfo + vim + tmux + ])); + documentation.dev.enable = lib.mkIf cfg.workstation true; + programs.fish.enable = true; + /*programs.zsh = { + enable = true; + enableBashCompletion = true; + };*/ + users.defaultUserShell = lib.mkIf (!cfg.workstation) pkgs.fish; + users.users.${cfg.mainUsername} = { + uid = 1000; + isNormalUser = true; + extraGroups = [ "wheel" ]; + }; + services.xserver.libinput.enable = lib.mkIf cfg.workstation true; + /* + services.xserver = { + enable = true; + libinput.enable = true; + desktopManager.xterm.enable = false; + # I couldn't get lightdm to start sway, so let's just do this + displayManager.startx.enable = true; + windowManager.i3.enable = true; + }; + */ + programs.sway.enable = lib.mkIf cfg.workstation true; + services.dbus.enable = lib.mkIf cfg.workstation true; + security.polkit.enable = lib.mkIf cfg.workstation true; + # pipewire: + security.rtkit.enable = lib.mkIf cfg.workstation true; + services.pipewire = lib.mkIf cfg.workstation { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + }; + programs.fuse.userAllowOther = true; + xdg.portal = lib.mkIf cfg.workstation { + enable = true; + extraPortals = with pkgs; [ xdg-desktop-portal-gtk xdg-desktop-portal-wlr ]; + }; + # autologin once after boot + # --skip-login means directly call login instead of first asking for username + # (normally login asks for username too, but getty prefers to do it by itself for whatever reason) + services.getty.extraArgs = lib.mkIf cfg.gettyAutologin [ "--skip-login" ]; + services.getty.loginProgram = lib.mkIf cfg.gettyAutologin (let + lockfile = "/tmp/login-once.lock"; + in with pkgs; writeShellScript "login-once" '' + if [ -f '${lockfile}' ]; then + exec ${shadow}/bin/login $@ + else + ${coreutils}/bin/touch '${lockfile}' + exec ${shadow}/bin/login -f user + fi + ''); + }; +} diff --git a/system/modules/impermanence.nix b/system/modules/impermanence.nix index 31da131..f3bb636 100644 --- a/system/modules/impermanence.nix +++ b/system/modules/impermanence.nix @@ -36,6 +36,7 @@ in { default = { }; }; config = lib.mkIf cfg.enable { + users.mutableUsers = false; # why is this not part of base NixOS? systemd.tmpfiles.rules = [ "d /var/lib/systemd/pstore 0755 root root 14d" ]; # as weird as it sounds, I won't use tmpfs for /tmp in case I'll have to put files over 2GB there @@ -100,6 +101,8 @@ in { { directory = /var/lib/postgresql; user = "postgres"; group = "postgres"; mode = "0755"; } ]) ++ (lib.optionals config.services.unbound.enable [ { directory = /var/lib/unbound; user = "unbound"; group = "unbound"; mode = "0755"; } + ]) ++ (lib.optionals config.services.searx.enable [ + { directory = /var/lib/searx; user = "searx"; group = "searx"; mode = "0700"; } ]) ++ (lib.optionals config.services.roundcube.enable [ { directory = /var/lib/roundcube; user = "roundcube"; group = "roundcube"; mode = "0700"; } ]) ++ (lib.optionals config.services.rspamd.enable [