{ lib, pkgs, ... }: let NixOSRelease = "23.11"; WAN_IFACE = "enp0s1"; LAN0_IFACE = "enp0s2"; LAN1_IFACE = "enp0s3"; LAN2_IFACE = "enp0s4"; LAN3_IFACE = "enp0s5"; LAN4_IFACE = "enp0s6"; in { imports = [ ./hardware-configuration.nix # generated by 'nixos-generate-config' ./host-specific-configuration.nix # specific to this host ]; # {{ networking section }} networking = { useDHCP = false; nameserver = [ "1.1.1.1" "1.0.0.1" "8.8.8.8" "8.8.4.4" ]; vlans = { wan = { id = 10; interface = "${WAN_IFACE}"; }; pratham_lan = { id = 20; interface = "${LAN0_IFACE}"; }; guest_lan = { id = 90; interface = "${LAN1_IFACE}"; }; }; interfaces = { # do not request DHCP on physical interfaces ${WAN_IFACE}.useDHCP = false; ${LAN0_IFACE}.useDHCP = false; ${LAN1_IFACE}.useDHCP = false; ${LAN2_IFACE}.useDHCP = false; ${LAN3_IFACE}.useDHCP = false; ${LAN4_IFACE}.useDHCP = false; # handle VLANs now wan.useDHCP = false; lan = { ipv4.addresses = [{ address = "10.0.0.1"; prefixLength = 24; }]; }; iot = { ipv4.addresses = [{ address = "10.255.255.1"; prefixLength = 24; }]; }; }; }; boot.kernel.sysctl = { ## Z-RAM-Swap # Kernel docs: https://docs.kernel.org/admin-guide/sysctl/vm.html # Pop!_OS "docs": https://github.com/pop-os/default-settings/pull/163/files # Using zramswap, penalty shouldn't be that high, since if you are under # high memory pressure, you likeky are under high CPU load too # at which point, you are performing computations and latency goes moot. "vm.swappiness" = 180; # Since zramSwap.algorithm is set to 'zstd', it is recommeded to set the # 'vm.page-cluster' paramater to '0'. "vm.page-cluster" = 0; # Ensure that at-least 512MBytes of total memory is free to avoid system freeze. # Not sure about the 512MBytes value since Pop!_OS sets it to 0.01% of total memory, # which is roughly equal to 3.7MBytes on a 3700MBytes RPi4. The value of 512MBytes # also does not leave lee-way for a 512M RPi Zero. # A value too LOW will result in system freeze. # A value too HIGH will result in OOM faster. "vm.min_free_kbytes"= 512000; # Disable 'vm.wwatermark_scale_factoratermark_boost_factor'. # https://groups.google.com/g/linux.debian.user/c/YcDYu-jM-to "vm.watermark_boost_factor" = 0; # Start swapping when 70% of memory is full (30% of memory is left). # 3000 is the MAX "vm.watermark_scale_factor" = 3000; # Increase the number of maximum mmaps a process may have (ZFS). # 2147483642 = 1.99-ish GiB "vm.max_map_count" = 2147483642; # The Magic SysRq key is a key combo that allows users connected to the # system console of a Linux kernel to perform some low-level commands. # Disable it, since we don't need it, and is a potential security concern. "kernel.sysrq" = 0; ## TCP hardening # Prevent bogus ICMP errors from filling up logs. "net.ipv4.icmp_ignore_bogus_error_responses" = 1; # Reverse path filtering causes the kernel to do source validation of # packets received from all interfaces. This can mitigate IP spoofing. "net.ipv4.conf.default.rp_filter" = 1; "net.ipv4.conf.all.rp_filter" = 1; # Refuse ICMP redirects (MITM mitigations) "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; # Protects against SYN flood attacks "net.ipv4.tcp_syncookies" = 1; # Incomplete protection again TIME-WAIT assassination "net.ipv4.tcp_rfc1337" = 1; ## TCP optimization # TCP Fast Open is a TCP extension that reduces network latency by packing # data in the sender’s initial TCP SYN. Setting 3 = enable TCP Fast Open for # both incoming and outgoing connections: "net.ipv4.tcp_fastopen" = 3; # Bufferbloat mitigations + slight improvement in throughput & latency "net.ipv4.tcp_congestion_control" = "bbr"; "net.core.default_qdisc" = "cake"; # add-ons for ze router "net.ipv4.conf.all.forwarding" = 1; # enable IPv4 forwarding "net.ipv6.conf.all.forwarding" = 1; # neable IPv6 forwarding # do not automatically configure any IPv6 addresses "net.ipv6.conf.all.accept_ra" = 0; "net.ipv6.conf.all.autoconf" = 0; "net.ipv6.conf.all.use_tempaddr" = 0; # allow IPv6 auto-configuration and temporary address use only on WAN "net.ipv6.conf.${WAN_IFACE}.accept_ra" = 2; "net.ipv6.conf.${WAN_IFACE}.autoconf" = 1; }; # {{ packages section }} nixpkgs.config.allowUnfree = false; # allow non-FOSS pkgs environment.systemPackages = with pkgs; [ acpi btop htop iperf # this is iperf3 iproute2 iputils lm_sensors nix-output-monitor nvd # diff between NixOS generations pciutils # provides lspci and setpci python3Minimal qemu_kvm ripgrep rsync tmux tree util-linux # provides blkid, losetup, lsblk, rfkill, fallocate, dmesg, etc ]; programs = { dconf.enable = true; git.enable = true; iotop.enable = true; mtr.enable = true; neovim.enable = true; }; # {{ user configuration }} users = { mutableUsers = false; # do not allow any more users on the system than what is defined here allowNoPasswordLogin = false; defaultUserShell = pkgs.bash; enforceIdUniqueness = true; users.root.hashedPassword = "$6$cxSzljtGpFNLRhx1$0HvOs4faEzUw9FYUF8ifOwBPwHsGVL7HenQMCOBNwqknBFHSlA6NIDO7U36HeQ/C9FN/B.dP.WBg3MzqQcubr0"; users.pratham = { isNormalUser = true; description = "Pratham Patel"; createHome = true; home = "/home/pratham"; group = "pratham"; uid = 1000; subUidRanges = [ { startUid = 10000; count = 65536; } ]; subGidRanges = [ { startGid = 10000; count = 65536; } ]; linger = true; hashedPassword = "$6$QLxAJcAeYARWFnnh$MaicewslNWkf/D8o6lDAWA1ECLMZLL3KWgIqPKuu/Qgt3iDBCEbEFjt3CUI4ENifvXW/blpze8IYeWhDjaKgS1"; extraGroups = [ "adm" "dialout" "kvm" "libvirt" "libvirtd" "log" "networkmanager" "rfkill" "sshusers" "sys" "systemd-journal" "wheel" "zfs-read" ]; }; groups.pratham = { name = "pratham"; gid = 1000; }; }; # {{ sudo configuration }} security.sudo = { enable = true; wheelNeedsPassword = true; }; # {{ system services' "parameters" go here }} services = { fwupd.enable = true; journald.storage = "persistent"; logrotate.enable = true; timesyncd.enable = true; # NTP # sshd_config openssh = { enable = true; extraConfig = "PermitEmptyPasswords no"; ports = [ 22 ]; openFirewall = true; settings = { Protocol = 2; MaxAuthTries = 2; PermitEmptyPasswords = false; PasswordAuthentication = false; PermitRootLogin = "prohibit-password"; X11Forwarding = false; }; }; }; systemd.timers = { "update-nixos-config" = { wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = "*-*-* 23:30:00"; Unit = "update-nixos-config.service"; }; }; }; systemd.services = { "update-nixos-config" = { serviceConfig = { Type = "oneshot"; User = "root"; ExecStart = "${pkgs.coreutils}/bin/cp -fR /home/pratham/my-git-repos/pratham/prathams-nixos/nixos-configuration/. /etc/nixos"; }; }; }; # {{ configuration options related to Nix and NixOS }} nix = { gc = { automatic = true; dates = "Sun *-*-* 00:00:00"; options = "--delete-older-than 14d"; }; settings = { trusted-users = [ "root" "pratham" ]; auto-optimise-store = true; experimental-features = [ "nix-command" "flakes" ]; }; }; system = { stateVersion = "${NixOSRelease}"; autoUpgrade = { enable = true; dates = "daily"; # *-*-* 00:00:00 allowReboot = false; operation = "boot"; persistent = true; }; }; # {{ misc }} time = { timeZone = "Asia/Kolkata"; hardwareClockInLocalTime = true; }; security = { polkit.enable = true; virtualisation = { flushL1DataCache = true; allowSimultaneousMultithreading = true; }; }; console = { enable = true; earlySetup = true; }; # {{ environment... stuff }} i18n = { defaultLocale = "en_IN"; extraLocaleSettings = { LC_ADDRESS = "en_IN"; LC_IDENTIFICATION = "en_IN"; LC_MEASUREMENT = "en_IN"; LC_MONETARY = "en_IN"; LC_NAME = "en_IN"; LC_NUMERIC = "en_IN"; LC_PAPER = "en_IN"; LC_TELEPHONE = "en_IN"; LC_TIME = "en_IN"; }; }; environment = { homeBinInPath = true; localBinInPath = true; variables = { # for 'sudo -e' EDITOR = "nvim"; VISUAL = "nvim"; # systemd SYSTEMD_PAGER = ""; SYSTEMD_EDITOR = "nvim"; TERM = "xterm-256color"; # set locale manually because even though NixOS handles the 'en_IN' locale # it doesn't append the string '.UTF-8' to LC_* # but, UTF-8 **is supported**, so just go ahead and set it manually LANG = lib.mkDefault "en_IN.UTF-8"; LC_ADDRESS = lib.mkDefault "en_IN.UTF-8"; LC_COLLATE = "en_IN.UTF-8"; LC_CTYPE = "en_IN.UTF-8"; LC_IDENTIFICATION = lib.mkDefault "en_IN.UTF-8"; LC_MEASUREMENT = lib.mkDefault "en_IN.UTF-8"; LC_MESSAGES = "en_IN.UTF-8"; LC_MONETARY = lib.mkDefault "en_IN.UTF-8"; LC_NAME = lib.mkDefault "en_IN.UTF-8"; LC_NUMERIC = lib.mkDefault "en_IN.UTF-8"; LC_PAPER = lib.mkDefault "en_IN.UTF-8"; LC_TELEPHONE = lib.mkDefault "en_IN.UTF-8"; LC_TIME = lib.mkDefault "en_IN.UTF-8"; LC_ALL = ""; # idk why, but some XDG vars aren't set, the missing ones are now set according to the # spec: (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) XDG_DATA_HOME = "$HOME/.local/share"; XDG_CONFIG_HOME = "$HOME/.config"; XDG_STATE_HOME = "$HOME/.local/state"; XDG_CACHE_HOME = "$HOME/.cache"; }; }; # yes, I want docs documentation = { enable = true; dev.enable = true; doc.enable = true; info.enable = true; man = { enable = true; generateCaches = true; }; }; # {{ virtualisation and container settings }} virtualisation = { libvirtd = { enable = true; onShutdown = "shutdown"; allowedBridges = [ "virbr0" ]; # TODO qemu = { runAsRoot = false; # not sure about this verbatimConfig = '' user = "pratham" group = "pratham" ''; }; }; }; boot = { kernelParams = [ "audit=0" "ignore_loglevel" "boot.shell_on_fail" "fsck.mode=auto" "plymouth.enable=0" "rd.plymouth=0" "no_console_suspend" ]; supportedFilesystems = [ "ext4" "f2fs" "vfat" "xfs" ]; loader = { timeout = 5; systemd-boot = { enable = true; }; }; }; hardware.enableRedistributableFirmware = true; }