{ pkgs, vars, lib, inputs, config, agenix, ... }: { age = { identityPaths = [ "/home/petri/.ssh/id_ed25519" ]; secrets = { s3fs.file = ../secrets/s3fs.age; duckdns = { file = ../secrets/duckdns_login_token.age; }; }; }; nixpkgs.config = { allowUnfree = true; qt.enable = true; }; nix = { optimise = { automatic = true; }; sshServe = { trusted = true; enable = true; }; daemonCPUSchedPolicy = "idle"; daemonIOSchedClass = "idle"; gc = { automatic = true; }; settings = { #substituters = [ "https://nix-community.cachix.org" ]; #trusted-public-keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; trusted-users = [ "${vars.user}" ]; auto-optimise-store = true; nix-path = [ "nixpkgs=${pkgs.path}" ]; experimental-features = "nix-command flakes"; system-features = [ "benchmark" "big-parallel" "kvm" "gccarch-x86-64-v3" ]; }; registry = (lib.mapAttrs (_: flake: { inherit flake; })) ( (lib.filterAttrs (_: lib.isType "flake")) inputs ); extraOptions = '' http2 = true keep-outputs = true keep-derivations = true ''; }; system = { switch = { enable = true; }; activationScripts.diff = { supportsDryActivation = true; text = '' ${pkgs.nvd}/bin/nvd --nix-bin-dir=${pkgs.nix}/bin diff \ /run/current-system "$systemConfig" ''; }; }; zramSwap = { enable = true; algorithm = "zstd"; }; boot = { tmp = { tmpfsHugeMemoryPages = "within_size"; useTmpfs = true; }; binfmt.emulatedSystems = [ "aarch64-linux" "riscv64-linux" ]; kernel.sysctl = { "kernel.sysrq" = 1; "net.core.netdev_max_backlog" = 25000; "net.core.rmem_default" = 67108864; # allow network stack 64MB "net.core.rmem_max" = 67108864; # allow network stack 64MB "net.core.wmem_default" = 67108864; "net.core.wmem_max" = 67108864; "net.core.default_qdisc" = "fq"; "net.ipv4.tcp_congestion_control" = "bbr"; "net.ipv4.tcp_ecn" = 1; "net.ipv4.tcp_fastopen" = 3; "net.ipv4.tcp_fin_timeout" = 10; "net.ipv4.tcp_low_latency" = 1; "net.ipv4.tcp_mtu_probing" = 2; # recommended for hosts with jumbo frames enabled "net.ipv4.tcp_no_metrics_save" = 1; "net.ipv4.tcp_rmem" = "4096 87380 33554432"; # increase Linux autotuning TCP buffer limit to 32MB "net.ipv4.tcp_slow_start_after_idle" = 0; "net.ipv4.tcp_syncookies" = 1; "net.ipv4.tcp_timestamps" = 1; "net.ipv4.tcp_wmem" = "4096 65536 33554432"; "net.ipv6.conf.default.accept_ra" = 2; "net.ipv6.conf.default.router_solicitations" = 3; "net.ipv6.conf.default.router_solicitation_interval" = 1; "net.ipv6.conf.default.router_solicitation_delay" = 0; "net.ipv6.conf.default.dad_transmits" = 1; "net.ipv6.conf.default.accept_dad" = 1; "net.ipv6.conf.default.optimistic_dad" = 1; "net.mptcp.enabled" = 1; "vm.nr_hugepages" = 512; "vm.dirty_background_ratio" = 5; "vm.swappiness" = 10; "kernel.sched_wakeup_granularity_ns" = 500000; }; loader = { systemd-boot = { memtest86.enable = true; configurationLimit = lib.mkDefault 8; consoleMode = lib.mkDefault "max"; enable = true; }; efi.canTouchEfiVariables = true; }; initrd = { systemd = { enable = true; dbus.enable = true; network = { enable = true; networks."99-dhcp" = { matchConfig.Name = "*"; networkConfig.DHCP = "yes"; }; }; }; }; }; networking = { nftables.enable = true; useDHCP = false; firewall = { enable = true; allowPing = true; allowedTCPPorts = [ 22 443 5353 ]; }; wireless.iwd = { enable = true; settings = { Network = { EnableIPv6 = true; }; }; }; useNetworkd = true; nameservers = [ "2001:14ba:a300:e5ba::1#adguard.tammi.cc" "87.92.90.90#adguard.tammi.cc" ]; }; systemd = { user.tmpfiles.users = { ${vars.user}.rules = [ "D %C - - - 7d" ]; }; tmpfiles.rules = [ "d /tmp 1777 root root 10d" "d /run/pam_timestamp 0700 root root -" ]; services = { "systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug"; }; settings.Manager = { DefaultTimeoutStopSec = 10; DefaultLimitNOFILE = 2048; }; # watchdog = { # device = "/dev/watchdog"; # runtimeTime = "30s"; #}; sleep.extraConfig = '' AllowSuspend=yes AllowHibernation=yes AllowHybridSleep=yes AllowSuspendThenHibernate=yes HibernateDelaySec=3600 ''; services.nix-daemon = { environment.TMPDIR = "/var/tmp"; }; }; powerManagement = { enable = true; }; console = { font = "${pkgs.tamzen}/share/consolefonts/Tamzen8x16.psf"; packages = with pkgs; [ tamzen ]; earlySetup = true; colors = [ "3b4252" "bf616a" "a3be8c" "ebcb8b" "81a1c1" "b48ead" "88c0d0" "e5e9f0" "4c566a" "bf616a" "a3be8c" "ebcb8b" "81a1c1" "b48ead" "8fbcbb" "eceff4" ]; keyMap = "us"; }; security = { pam.services = { hyprlock = { }; greetd = { enableGnomeKeyring = true; }; }; polkit = { enable = true; extraConfig = '' polkit.addRule(function(action, subject) { if (subject.isInGroup("wheel") && subject.local) { // Always allow local wheel users without password return polkit.Result.YES; } }); ''; }; rtkit.enable = true; sudo.extraConfig = '' Defaults timestamp_timeout=60 ''; }; time.timeZone = "Europe/Helsinki"; i18n = { defaultLocale = "en_US.UTF-8"; extraLocaleSettings = { LC_ADDRESS = "fi_FI.UTF-8"; LC_IDENTIFICATION = "fi_FI.UTF-8"; LC_MEASUREMENT = "fi_FI.UTF-8"; LC_MONETARY = "fi_FI.UTF-8"; LC_NAME = "fi_FI.UTF-8"; LC_NUMERIC = "fi_FI.UTF-8"; LC_PAPER = "fi_FI.UTF-8"; LC_TELEPHONE = "fi_FI.UTF-8"; LC_TIME = "fi_FI.UTF-8"; }; extraLocales = [ "fi_FI.UTF-8/UTF-8" ]; }; users.users.${vars.user} = { isNormalUser = true; description = "${vars.name}"; extraGroups = [ "adm" "audio" "bluetooth" "input" "lp" "network" "plugdev" "render" "systemd-journal" "video" "wheel" "wireshark" "render" ]; ignoreShellProgramCheck = true; packages = with pkgs; [ alsa-utils blis bluez bluez-alsa bluez-tools glfw glm gotop libva libva-utils mesa-demos nixfmt-rfc-style shaderc.dev shaderc.static vulkan-headers vulkan-loader vulkan-tools vulkan-validation-layers ]; shell = pkgs.${vars.shell}; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHIXKjutIlv3CS9dmo9bDUUt3UR9O9xUKFXzci3LvNTQ petri.hienonen@gmail.com" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJzUFgqZF3U6RfbvQLKBdzNgWHGp3z+9FGvqjgTY8N6K petri@saarni" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIimbOBDKbTNi8b+P0wWaZRszRV59lnokqrGQRIdgqOj petri@kataja" ]; }; environment = { pathsToLink = [ "/share/xdg-desktop-portal" "/share/applications" ]; systemPackages = with pkgs; [ agenix.packages.${system}.default clinfo coreutils curl git gnumake gnupg tuigreet linux-firmware lm_sensors mimalloc minio-client neovim nvd procps s3fs sysfsutils unrar unzip usbutils zstd ]; variables = { EDITOR = "${pkgs.neovim}/bin/nvim"; LD_LIBRARY_PATH = "${pkgs.vulkan-loader}/lib:$LD_LIBRARY_PATH"; NIXPKGS_ALLOW_UNFREE = 1; QT_QPA_PLATFORM = "xcb"; SYSTEMD_COLORS = 256; SYSTEMD_LOG_COLOR = 1; SYSTEMD_URLIFY = 1; VULKAN_SDK = "${pkgs.vulkan-headers}"; }; }; fileSystems."/media/llm" = { device = "llm"; fsType = "fuse./run/current-system/sw/bin/s3fs"; noCheck = true; options = [ "_netdev" "allow_other" "umask=0007" "uid=1000" "use_path_request_style" "url=https://s3.tammi.cc" "passwd_file=${config.age.secrets.s3fs.path}" ]; }; fileSystems."/media/skydrive" = { device = "skydrive"; fsType = "fuse./run/current-system/sw/bin/s3fs"; noCheck = true; options = [ "_netdev" "allow_other" "umask=0007" "uid=1000" "use_path_request_style" "url=https://s3.tammi.cc" "passwd_file=${config.age.secrets.s3fs.path}" ]; }; fonts = { enableDefaultPackages = true; packages = with pkgs; [ nerd-fonts.iosevka nerd-fonts.iosevka-term nerd-fonts.zed-mono nixos-icons roboto-serif roboto-mono roboto-flex twitter-color-emoji ]; fontDir.enable = true; fontconfig = { enable = true; hinting = { enable = true; autohint = true; style = "medium"; }; useEmbeddedBitmaps = true; cache32Bit = true; antialias = true; subpixel = { rgba = lib.mkDefault "rgb"; lcdfilter = "default"; }; defaultFonts = { serif = [ "Roboto Serif" ]; sansSerif = [ "Roboto Flex" ]; monospace = [ "Iosevka Nerd Font" ]; emoji = [ "Twitter Color Emoji" ]; }; }; }; programs = { ssh = { extraConfig = '' Compression = yes ControlMaster = yes Protocol = 2 ServerAliveInterval = 1 ServerAliveCountMax = 3 TCPKeepAlive = yes ''; hostKeyAlgorithms = [ "ssh-ed25519-cert-v01@openssh.com" "ssh-rsa-cert-v01@openssh.com" "ssh-ed25519" "ssh-rsa" "ecdsa-sha2-nistp521-cert-v01@openssh.com" "ecdsa-sha2-nistp384-cert-v01@openssh.com" "ecdsa-sha2-nistp256-cert-v01@openssh.com" "ecdsa-sha2-nistp521" "ecdsa-sha2-nistp384" "ecdsa-sha2-nistp256" ]; kexAlgorithms = [ "curve25519-sha256@libssh.org" "ecdh-sha2-nistp521" "ecdh-sha2-nistp384" "ecdh-sha2-nistp256" "diffie-hellman-group-exchange-sha256" ]; macs = [ "hmac-sha2-512-etm@openssh.com" "hmac-sha2-256-etm@openssh.com" "umac-128-etm@openssh.com" "hmac-sha2-512" "hmac-sha2-256" "umac-128@openssh.com" ]; ciphers = [ "chacha20-poly1305@openssh.com" "aes256-gcm@openssh.com" "aes128-gcm@openssh.com" "aes256-ctr" "aes192-ctr" "aes128-ctr" ]; }; arp-scan.enable = true; appimage = { enable = true; binfmt = true; }; ccache.enable = true; wireshark.enable = true; command-not-found.enable = false; # enabled by default, does not work with flakes dconf.enable = true; # needed by gnome application, such as firefox mosh = { enable = true; withUtempter = true; openFirewall = true; }; xwayland.enable = true; gnupg.agent = { enable = true; enableSSHSupport = true; }; alvr = { enable = true; openFirewall = true; }; gamescope = { enable = true; }; steam = { enable = true; gamescopeSession.enable = true; remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server localNetworkGameTransfers.openFirewall = true; # Open ports in the firewall for Steam Local Network Ga extraCompatPackages = [ pkgs.proton-ge-bin ]; }; }; systemd.network.networks."50-bluetooth-pan" = { matchConfig.Name = "bnep*"; networkConfig = { DHCP = true; IPv6AcceptRA = true; }; }; hardware = { enableAllFirmware = true; enableRedistributableFirmware = true; graphics = { enable = true; }; bluetooth = { enable = true; powerOnBoot = true; settings = { General = { ControllerMode = "bredr"; DiscoverableTimeout = 0; Experimental = true; FastConnectable = true; JustWorksRepairing = "always"; KernelExperimental = true; MultiProfile = "multiple"; Privacy = "off"; Testing = true; }; Policy = { AutoEnable = true; }; LE = { ConnectionLatency = 0; ConnectionSupervisionTimeout = 2000; EnableAdvMonInterleaveScan = 1; MaxConnectionInterval = 16; MinConnectionInterval = 16; ScanIntervalAutoConnect = 300; }; GATT = { Channels = 6; }; }; }; }; services = { pipewire = { enable = true; alsa.enable = true; pulse = { enable = true; }; audio.enable = true; wireplumber = { enable = true; extraConfig = { "10-bluez" = { "monitor.bluez.properties" = { "bluez5.enable-sbc-xq" = true; "bluez5.enable-msbc" = true; "bluez5.enable-hw-volume" = true; "bluez5.roles" = [ "hsp_hs" "hsp_ag" "hfp_hf" "hfp_ag" ]; }; }; }; }; extraConfig.pipewire-pulse = { "switch-on-connect.conf" = { "pulse.cmd" = [ { cmd = "load-module"; args = "module-switch-on-connect"; } ]; }; }; }; libinput = { enable = true; }; geoclue2 = { package = pkgs.geoclue2-with-demo-agent; enableDemoAgent = true; enable = true; }; systembus-notify.enable = true; dbus = { implementation = "broker"; packages = [ pkgs.bluez ]; }; timesyncd = { enable = true; servers = [ "time1.mikes.fi" "time2.mikes.fi" ]; }; printing.enable = true; upower = { enable = true; }; devmon.enable = true; # automatic device mounting daemon journald = { audit = true; extraConfig = '' ReadKMsg=1 SystemMaxUse=200M ''; }; xserver = { enable = true; # Required by steam xkb = { layout = "us"; variant = ""; }; updateDbusEnvironment = true; }; udev.extraRules = '' # Blinkstick nano SUBSYSTEM=="usb", ATTR{idVendor}=="20a0", ATTR{idProduct}=="41e5", MODE:="0666" # ESP32 waveshare SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="55d3", MODE:="0666" ''; getty.autologinUser = "${vars.user}"; kmscon = { enable = true; hwRender = true; extraOptions = "--xkb-layout=fi"; fonts = [ { name = "Iosevka Nerd Font"; package = pkgs.nerd-fonts.iosevka; } ]; }; openssh = { enable = true; openFirewall = true; settings = { UseDns = true; AllowUsers = [ "petri" ]; KexAlgorithms = [ "curve25519-sha256@libssh.org" "ecdh-sha2-nistp521" "ecdh-sha2-nistp384" "ecdh-sha2-nistp256" "diffie-hellman-group-exchange-sha256" ]; Ciphers = [ "chacha20-poly1305@openssh.com" "aes256-gcm@openssh.com" "aes128-gcm@openssh.com" "aes256-ctr" "aes192-ctr" "aes128-ctr" ]; Macs = [ "hmac-sha2-512-etm@openssh.com" "hmac-sha2-256-etm@openssh.com" "umac-128-etm@openssh.com" "hmac-sha2-512" "hmac-sha2-256" "umac-128@openssh.com" ]; PermitRootLogin = "no"; PasswordAuthentication = false; }; extraConfig = '' ClientAliveCountMax 0 ClientAliveInterval 300 LoginGraceTime 60 AllowTcpForwarding no AllowAgentForwarding no MaxAuthTries 3 MaxSessions 2 TCPKeepAlive no ''; }; earlyoom = { enableNotifications = true; enable = true; }; ananicy = { enable = true; package = pkgs.ananicy-cpp; rulesProvider = pkgs.ananicy-rules-cachyos; }; fwupd = { enable = true; extraRemotes = [ "lvfs-testing" ]; }; resolved = { enable = true; dnssec = "true"; llmnr = "true"; dnsovertls = "true"; domains = [ "~." ]; extraConfig = '' MulticastDNS=true Cache=no-negative ''; fallbackDns = [ "2606:4700:4700::1111#cloudflare-dns.com" "2606:4700:4700::1001#cloudflare-dns.com" "1.1.1.1#cloudflare-dns.com" "1.0.0.1#cloudflare-dns.com" "9.9.9.9#dns.quad9.net" "149.112.112.112#dns.quad9.net" ]; }; fstrim.enable = true; smartd = { notifications = { test = true; systembus-notify.enable = true; }; enable = true; }; greetd = { enable = true; restart = true; settings = { initial_session = { command = "/etc/greetd/hyprland-wrapper.sh"; user = "${vars.user}"; }; default_session = { command = "${pkgs.tuigreet}/bin/tuigreet --cmd /etc/greetd/hyprland-wrapper.sh"; }; }; }; }; environment.etc = { "greetd/hyprland-wrapper.sh" = { text = '' #!/bin/sh # Session export XDG_SESSION_TYPE=wayland export XDG_SESSION_DESKTOP=Hyprland export XDG_CURRENT_DESKTOP=Hyprland # Wayland stuff export MOZ_ENABLE_WAYLAND=1 export QT_QPA_PLATFORM=wayland export SDL_VIDEODRIVER=wayland dbus-run-session ${pkgs.hyprland}/bin/Hyprland ''; mode = "0755"; }; "bluetooth-tether.sh" = { mode = "0755"; text = '' #!/bin/sh DEVICE_MAC="3C:01:EF:D9:0D:96" # Phone shares the internet ADAPTER="hci0" # Replace if your adapter is different (check with `bluetoothctl list`) # Ensure Bluetooth is powered on ${pkgs.bluez}/bin/bluetoothctl power on # Scan for the device briefly (5 seconds) ${pkgs.bluez}/bin/bluetoothctl scan on & sleep 5 ${pkgs.bluez}/bin/bluetoothctl scan off # Check if the device is present if ${pkgs.bluez}/bin/bluetoothctl devices | grep -q "$DEVICE_MAC"; then echo "Device $DEVICE_MAC found, attempting to connect to NAP..." # Ensure device is trusted (optional, for reliability) ${pkgs.bluez}/bin/bluetoothctl trust "$DEVICE_MAC" # Connect to NAP profile ${pkgs.dbus}/bin/dbus-send --system --type=method_call --dest=org.bluez \ /org/bluez/$ADAPTER/dev_$(echo $DEVICE_MAC | tr ':' '_') \ org.bluez.Network1.Connect string:'nap' || { echo "Failed to connect to NAP for $DEVICE_MAC" exit 1 } echo "Connected to NAP for $DEVICE_MAC" else echo "Device $DEVICE_MAC not found, skipping connection" exit 0 fi ''; }; }; systemd.services.bluetooth-tether = { description = "Auto-connect to Bluetooth tethering PAN if device is detected"; after = [ "bluetooth.service" ]; partOf = [ "bluetooth.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; ExecStart = "/etc/bluetooth-tether.sh"; RemainAfterExit = true; Restart = "on-failure"; RestartSec = "30s"; # Retry every 30 seconds if the device isn't found }; }; }