From 08297376a85a1719518507e54fca9de954d2376a Mon Sep 17 00:00:00 2001 From: Petri Hienonen Date: Thu, 23 May 2024 13:56:00 +0300 Subject: Agenix configuration --- roles/shared.nix | 818 ++++++++++++++++++++++++++++++++++++++++++++++++++++ roles/wallpaper.nix | 23 ++ 2 files changed, 841 insertions(+) create mode 100644 roles/shared.nix create mode 100644 roles/wallpaper.nix (limited to 'roles') diff --git a/roles/shared.nix b/roles/shared.nix new file mode 100644 index 0000000..47aaf6f --- /dev/null +++ b/roles/shared.nix @@ -0,0 +1,818 @@ +{ + 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 = false; + enableNg = true; + }; + + system.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"; + }; + extraConfig = '' + 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-tools + bluez-alsa + glfw + glm + glxinfo + gotop + libva + libva-utils + nixfmt-rfc-style + shaderc.static + shaderc.dev + 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 = { + systemPackages = with pkgs; [ + agenix.packages.${system}.default + clinfo + coreutils + curl + git + gnumake + gnupg + greetd.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; + vt = 1; + restart = true; + settings = { + initial_session = { + command = "/etc/greetd/hyprland-wrapper.sh"; + user = "${vars.user}"; + }; + default_session = { + command = "${pkgs.greetd.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 + }; + }; +} diff --git a/roles/wallpaper.nix b/roles/wallpaper.nix new file mode 100644 index 0000000..3cc4f91 --- /dev/null +++ b/roles/wallpaper.nix @@ -0,0 +1,23 @@ +{ pkgs, ... }: + +{ + systemd.user.services.wallpaper = { + description = "wallpaper"; + script = '' + ${pkgs.hyprland}/bin/hyprctl hyprpaper wallpaper ,$(find -L /etc/nixos/home/wallpapers -type f | shuf -n 1) + ''; + serviceConfig = { + Type = "oneshot"; + }; + }; + + systemd.user.timers.wallpaper = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "10m"; + OnUnitActiveSec = "10m"; + Unit = "wallpaper.service"; + Persistent = true; + }; + }; +} -- cgit v1.2.3-70-g09d2