From 863abb4fd3c9365f22b614ab7d87f2161b73a08e Mon Sep 17 00:00:00 2001 From: Nexoniarz Date: Fri, 2 Oct 2026 21:07:55 +0200 Subject: [PATCH] Switch to the PC config layout: Plasma, Limine, shared configs/ Same modules and settings as nexoniarz-config-nixos; only hardware.nix differs. Pantheon/LightDM -> Plasma 6/SDDM, systemd-boot -> Limine, system.nix/drivers.nix split into focused modules, Firefox prefs and fastfetch config in configs/. Laptop hardware kept: AMD 680M + RTX 4050 PRIME offload (bus IDs unchanged), NVIDIA suspend fix, asusd + supergfxd, tablet driver, DualSense ERTM fix, laptop scripts (brightness, hotspot, telemetry, weather). Dropped: GoPro v4l2loopback webcam, blueman. Co-Authored-By: Claude Opus 5.5 --- .gitignore | 3 + README.md | 53 +++++---- configs/fastfetch/config.jsonc | 80 +++++++++++++ configs/firefox/prefs.js | 121 +++++++++++++++++++ configuration.nix | 32 ++++-- modules/apps.nix | 99 +++++++++++++--- modules/audio.nix | 25 ++++ modules/boot.nix | 39 +++++++ modules/default-apps.nix | 80 +++++++++++++ modules/desktop.nix | 82 +++++++++---- modules/drivers.nix | 79 ------------- modules/fastfetch.nix | 7 ++ modules/firefox.nix | 11 ++ modules/hardware.nix | 76 ++++++++++++ modules/locale.nix | 19 +++ modules/networking.nix | 38 ++++++ modules/nix-settings.nix | 14 +++ modules/scripts.nix | 2 - modules/security.nix | 38 ++++++ modules/system.nix | 204 --------------------------------- modules/users.nix | 15 ++- 21 files changed, 752 insertions(+), 365 deletions(-) create mode 100644 .gitignore create mode 100644 configs/fastfetch/config.jsonc create mode 100644 configs/firefox/prefs.js create mode 100644 modules/audio.nix create mode 100644 modules/boot.nix create mode 100644 modules/default-apps.nix delete mode 100644 modules/drivers.nix create mode 100644 modules/fastfetch.nix create mode 100644 modules/firefox.nix create mode 100644 modules/hardware.nix create mode 100644 modules/locale.nix create mode 100644 modules/networking.nix create mode 100644 modules/nix-settings.nix create mode 100644 modules/security.nix delete mode 100644 modules/system.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b37743 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.claude +result +result-* diff --git a/README.md b/README.md index b714743..a309f59 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,43 @@ # nexoniarz-config-nixos-laptop -My personal NixOS system configuration tailored for daily use on an -**ASUS TUF Gaming A15 (FA507NU)**. +My personal NixOS configuration for an ASUS TUF Gaming A15 (FA507NU). +Shares its layout and settings with my PC config +([nexoniarz-config-nixos](https://github.com/Nexoniarz/nexoniarz-config-nixos)); +only the hardware differs. ## Overview -- **OS:** NixOS -- **DE / Compositor:** Pantheon (gala, Wayland) -- **Display manager:** LightDM (elementary greeter) +- **OS:** NixOS 26.05 (unstable channel) +- **Desktop:** KDE Plasma 6 on Wayland (KWin), SDDM +- **Bootloader:** Limine +- **Terminal:** Konsole - **Shell:** Zsh +- **Audio:** PipeWire - **CPU:** AMD Ryzen 5 7535HS -- **GPU:** AMD Radeon 680M (iGPU, drives the internal panel) + NVIDIA RTX - 4050 Max-Q (dGPU, PRIME render offload only — run anything through it with - `nvidia-offload `) -- **Laptop control:** `asusctl` (fan curves, keyboard backlight, battery - charge limit) + `supergfxctl` (dGPU power-state switching) +- **GPU:** AMD Radeon 680M (iGPU, drives the panel) + NVIDIA RTX 4050 Max-Q + (PRIME render offload only; run things on it with `nvidia-offload `) +- **Laptop control:** asusctl (fans, keyboard backlight, charge limit) + supergfxctl (dGPU power state) ## Layout -- `configuration.nix` — top-level imports -- `hardware-configuration.nix` — generated by `nixos-generate-config`, don't - hand-edit -- `modules/system.nix` — bootloader, networking, time, sound, hardening, - nix-ld -- `modules/drivers.nix` — hybrid graphics (NVIDIA PRIME offload), ASUS - daemons, misc hardware (webcam loopback, tablet driver) -- `modules/desktop.nix` — Pantheon desktop environment -- `modules/users.nix` — user account, Steam, Firefox, Flatpak -- `modules/apps.nix` — all installed packages -- `modules/scripts.nix` + `modules/scripts/` — small custom CLI helpers - (encrypted vault toggle, metadata stripping, brightness control, Wi-Fi - hotspot, system telemetry, weather fetch) +| File | Contents | +|---|---| +| `configuration.nix` | Imports only | +| `modules/boot.nix` | Limine, kernel, zram/swap | +| `modules/networking.nix` | NetworkManager, firewall, DNS-over-TLS, MAC randomization | +| `modules/locale.nix` | Timezone, locale, console keymap | +| `modules/nix-settings.nix` | Nix features, GC, unfree | +| `modules/security.nix` | sysctl hardening, sudo, firejail, GnuPG, polkit | +| `modules/hardware.nix` | Hybrid graphics (PRIME offload), ASUS daemons, tablet, Bluetooth, I2C, RTL-SDR, printing | +| `modules/audio.nix` | PipeWire | +| `modules/desktop.nix` | Plasma, SDDM, fonts, theming | +| `modules/users.nix` | Account, shell, Steam, Flatpak | +| `modules/apps.nix` | Installed packages, nix-ld | +| `modules/default-apps.nix` | MIME associations | +| `modules/scripts.nix` | Custom scripts in `modules/scripts/` (vault, metadata stripping, brightness, Wi-Fi hotspot, telemetry, weather) | +| `modules/fastfetch.nix` | Installs `configs/fastfetch/config.jsonc` system-wide | +| `modules/firefox.nix` | Firefox, with prefs from `configs/firefox/prefs.js` (reapplied each start, not locked) | +| `configs/` | Plain app config files (Firefox prefs, fastfetch) used by the modules | --- diff --git a/configs/fastfetch/config.jsonc b/configs/fastfetch/config.jsonc new file mode 100644 index 0000000..8cf04e2 --- /dev/null +++ b/configs/fastfetch/config.jsonc @@ -0,0 +1,80 @@ +// Gruvbox-themed fastfetch, matching the Limine and icon theme. +// Colors: yellow fabd2f, aqua 8ec07c, blue 83a598, orange fe8019, gray 928374. +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "source": "nixos", + "color": { + "1": "38;2;131;165;152", + "2": "38;2;142;192;124", + "3": "38;2;131;165;152", + "4": "38;2;142;192;124", + "5": "38;2;131;165;152", + "6": "38;2;142;192;124" + }, + "padding": { "top": 1, "left": 1, "right": 3 } + }, + "display": { + "separator": " ", + "color": { + "keys": "38;2;250;189;47", + "title": "38;2;254;128;25", + "output": "38;2;235;219;178" + }, + "key": { "width": 13 }, + "bar": { + "char": { "elapsed": "■", "total": "■" }, + "border": { "left": "", "right": "" }, + "color": { "total": "38;2;80;73;69" }, + "width": 12 + }, + "percent": { + "type": ["num", "bar"], + "color": { + "green": "38;2;184;187;38", + "yellow": "38;2;250;189;47", + "red": "38;2;251;73;52" + } + }, + "size": { "binaryPrefix": "iec", "ndigits": 1 } + }, + "modules": [ + { + "type": "title", + "format": "{#1}󱄅 {#38;2;254;128;25}{user-name}{#38;2;146;131;116}@{#38;2;142;192;124}{host-name}" + }, + { + "type": "custom", + "format": "{#38;2;146;131;116}╭─────────────── {#38;2;131;165;152}system{#38;2;146;131;116} ───────────────" + }, + { "type": "os", "key": "│ 󱄅 os", "keyColor": "38;2;131;165;152", "format": "{pretty-name}" }, + { "type": "kernel", "key": "│ 󰌽 kernel", "keyColor": "38;2;131;165;152" }, + { "type": "packages", "key": "│ 󰏖 pkgs", "keyColor": "38;2;131;165;152", "format": "{nix-system} sys · {nix-user} user · {flatpak-all} flatpak" }, + { "type": "uptime", "key": "│ 󰔟 uptime", "keyColor": "38;2;131;165;152" }, + { "type": "shell", "key": "│ 󰆍 shell", "keyColor": "38;2;131;165;152" }, + { + "type": "custom", + "format": "{#38;2;146;131;116}├─────────────── {#38;2;142;192;124}desktop{#38;2;146;131;116} ──────────────" + }, + { "type": "de", "key": "│ 󰕮 de", "keyColor": "38;2;142;192;124" }, + { "type": "wm", "key": "│ 󰖲 wm", "keyColor": "38;2;142;192;124" }, + { "type": "icons", "key": "│ 󰀻 icons", "keyColor": "38;2;142;192;124", "format": "{1}" }, + { "type": "cursor", "key": "│ 󰇀 cursor", "keyColor": "38;2;142;192;124" }, + { + "type": "custom", + "format": "{#38;2;146;131;116}├─────────────── {#38;2;254;128;25}hardware{#38;2;146;131;116} ─────────────" + }, + { "type": "host", "key": "│ 󰍹 board", "keyColor": "38;2;254;128;25" }, + { "type": "cpu", "key": "│ 󰻠 cpu", "keyColor": "38;2;254;128;25", "temp": true, "format": "{name} ({cores-logical}) @ {freq-max}" }, + { "type": "gpu", "key": "│ 󰢮 gpu", "keyColor": "38;2;254;128;25", "format": "{name}" }, + { "type": "display", "key": "│ 󰍺 display","keyColor": "38;2;254;128;25", "format": "{width}x{height} @ {refresh-rate} Hz" }, + { "type": "memory", "key": "│ 󰑭 ram", "keyColor": "38;2;254;128;25", "format": "{percentage-bar} {used} / {total} ({percentage})" }, + { "type": "disk", "key": "│ 󰋊 disk", "keyColor": "38;2;254;128;25", "folders": "/", "format": "{size-percentage-bar} {size-used} / {size-total} ({size-percentage})" }, + { + "type": "custom", + "format": "{#38;2;146;131;116}╰──────────────────────────────────────────" + }, + "break", + { "type": "colors", "symbol": "circle", "paddingLeft": 2 } + ] +} diff --git a/configs/firefox/prefs.js b/configs/firefox/prefs.js new file mode 100644 index 0000000..b1b0eee --- /dev/null +++ b/configs/firefox/prefs.js @@ -0,0 +1,121 @@ +// Nexoniarz's Firefox prefs (Firefox 157, "Nova" design) +// +// Loaded by NixOS (modules/firefox.nix) into Firefox's autoconfig. pref() +// sets the value on every Firefox start but doesn't lock it: you can still +// change things in Settings/about:config, they just reset on next start. +// To change a setting permanently, edit it here and nixos-rebuild. +// To stop managing a setting, delete its line (Firefox then keeps +// whatever value it last had). +// +// GPU video decoding also needs env vars set in modules/hardware.nix: +// LIBVA_DRIVER_NAME=nvidia NVD_BACKEND=direct MOZ_DISABLE_RDD_SANDBOX=1 + +/*** PRIVACY: tracking & fingerprinting ***/ + +// Strict Enhanced Tracking Protection: blocks trackers, cryptominers and +// known fingerprinters, isolates cookies per site (Total Cookie Protection), +// strips tracking parameters from URLs, and turns on fingerprintingProtection +// (randomized canvas, fewer exposed hardware details). +// If a site breaks: click the shield in the address bar and turn it off +// for that site only. +pref("browser.contentblocking.category", "strict"); + +// resistFingerprinting replaced by the fingerprintingProtection above. RFP +// forced light mode, UTC time and English pages on every site. +pref("privacy.resistFingerprinting", false); +pref("privacy.spoof_english", 0); +// First-party isolation stays ON. Every existing cookie in this profile was +// saved with a first-party tag; turning this off makes Firefox ignore them +// all (logged out everywhere). Works alongside Strict mode. +pref("privacy.firstparty.isolate", true); + +// Cross-site requests only send the origin (https://site.com/), not the +// full page URL you came from. +pref("network.http.referer.XOriginTrimmingPolicy", 2); + +// Tell sites not to sell/share your data (legally binding in some places). +pref("privacy.globalprivacycontrol.enabled", true); + +// No WebRTC: stops IP leaks. Web video calls (Meet, Discord in-browser) +// need this set to true. +pref("media.peerconnection.enabled", false); + +/*** PRIVACY: Mozilla data collection ***/ + +pref("datareporting.healthreport.uploadEnabled", false); +pref("datareporting.policy.dataSubmissionEnabled", false); +pref("datareporting.usage.uploadEnabled", false); +pref("toolkit.telemetry.enabled", false); +pref("toolkit.telemetry.unified", false); +pref("app.shield.optoutstudies.enabled", false); +pref("app.normandy.enabled", false); +pref("nimbus.rollouts.enabled", false); +pref("browser.discovery.enabled", false); + +// Firefox Suggest launched in Poland with Firefox 157; it adds sponsored +// results to the address bar. +pref("browser.urlbar.quicksuggest.enabled", false); +pref("browser.urlbar.suggest.quicksuggest.sponsored", false); +pref("browser.urlbar.suggest.quicksuggest.nonsponsored", false); +pref("browser.newtabpage.activity-stream.showSponsored", false); +pref("browser.newtabpage.activity-stream.showSponsoredTopSites", false); + +/*** SECURITY ***/ + +// HTTPS-Only: upgrade every site to HTTPS and warn before loading plain +// HTTP. Was enabled once, but it's off now. +pref("dom.security.https_only_mode", true); + +// Safe Browsing back on for malware/phishing. It checks a local list and +// only sends a partial hash when a URL matches, never your history. +// The remote download check (which uploads file metadata to Google) stays off. +pref("browser.safebrowsing.malware.enabled", true); +pref("browser.safebrowsing.phishing.enabled", true); +pref("browser.safebrowsing.downloads.enabled", true); +pref("browser.safebrowsing.downloads.remote.enabled", false); + +/*** NETWORK ***/ + +// DNS: use the system resolver (systemd-resolved with DNS-over-TLS) and +// never let Firefox switch itself to its own DNS-over-HTTPS provider. +pref("network.trr.mode", 5); + +// No preloading pages or DNS you didn't ask for. +pref("network.dns.disablePrefetch", true); +pref("network.prefetch-next", false); +pref("network.http.speculative-parallel-limit", 0); +pref("browser.urlbar.speculativeConnect.enabled", false); +pref("network.captive-portal-service.enabled", false); +pref("network.connectivity-service.enabled", false); + +/*** GPU VIDEO DECODING (RTX 3060 Ti, nvidia-vaapi-driver) ***/ + +// Firefox blocklists VA-API on NVIDIA; force it on. The 3060 Ti decodes +// H.264, VP9 and AV1 in hardware. (media.ffmpeg.vaapi.enabled is gone +// since Firefox 137; this pref replaced it.) +pref("media.hardware-video-decoding.force-enabled", true); +pref("media.rdd-ffmpeg.enabled", true); +pref("gfx.webrender.all", true); + +/*** LOOK & FEEL ***/ + +// Compact mode (back in Firefox 157): thinner tabs and toolbars. +// Switch back via ☰ > More tools > Customize toolbar > Density. +pref("browser.compactmode.show", true); +pref("browser.uidensity", 1); + +// Smoother, momentum-based scrolling, nicer at 240 Hz. +pref("general.smoothScroll.msdPhysics.enabled", true); + +// Middle-click on a page to autoscroll (like on Windows). +pref("general.autoScroll", true); + +// Closing the last tab doesn't close the window. +pref("browser.tabs.closeWindowWithLastTab", false); + +// Show the full URL including https:// so you always see what site you're on. +pref("browser.urlbar.trimHttps", false); +pref("browser.urlbar.trimURLs", false); + +// No "proceed with caution" page every time you open about:config. +pref("browser.aboutConfig.showWarning", false); diff --git a/configuration.nix b/configuration.nix index 4f14d8d..56ab189 100644 --- a/configuration.nix +++ b/configuration.nix @@ -1,18 +1,30 @@ -# Main NixOS configuration file importing modular configurations. - { config, pkgs, ... }: { imports = [ - ./hardware-configuration.nix # Generated hardware scan results - ./modules/system.nix # Bootloader, networking, time, sound, hardening, nix-ld - ./modules/drivers.nix # AMD/NVIDIA hybrid graphics (PRIME) and ASUS laptop control - ./modules/desktop.nix # Pantheon desktop environment (LightDM + gala) - ./modules/users.nix # User accounts and global configurations - ./modules/apps.nix # All installed packages: apps, CLI tools, dev toolchains - ./modules/scripts.nix # Custom system scripts and helpers + ./hardware-configuration.nix + + # Core system + ./modules/boot.nix + ./modules/networking.nix + ./modules/locale.nix + ./modules/nix-settings.nix + ./modules/security.nix + + # Hardware + ./modules/hardware.nix + ./modules/audio.nix + + # Desktop & user + ./modules/desktop.nix + ./modules/users.nix + ./modules/apps.nix + ./modules/default-apps.nix + ./modules/scripts.nix + ./modules/fastfetch.nix + ./modules/firefox.nix ]; # Do not change this value. Read documentation before updating. - system.stateVersion = "26.05"; + system.stateVersion = "26.05"; } diff --git a/modules/apps.nix b/modules/apps.nix index 631d2aa..cf0c365 100644 --- a/modules/apps.nix +++ b/modules/apps.nix @@ -1,16 +1,46 @@ { config, pkgs, ... }: +let + + # Both SDR++ and rtl_433 default to supporting every radio ever made, which + # drags in UHD (USRP firmware), BladeRF and LimeSuite — ~1.5 GB for + # hardware we don't own. These two overrides cut that down to the RTL-SDR paths. + + soapysdrLean = pkgs.soapysdr.override { + extraPackages = with pkgs; [ + soapyrtlsdr + soapyremote + ]; + }; + + rtl433Lean = pkgs.rtl_433.override { + soapysdr-with-plugins = soapysdrLean; + }; + + # Leaves the RTL-SDR, rtl_tcp, file and network sources on. + sdrppLean = pkgs.sdrpp.override { + soapy_source = false; + bladerf_source = false; + limesdr_source = false; + plutosdr_source = false; + airspy_source = false; + airspyhf_source = false; + hermes_source = false; + rfspace_source = false; + dragonlabs_source = false; + spectran_http_source = false; + }; + +in { - # Every installed package — GUI apps, CLI tools, and dev toolchains alike. - # If it's "install X", it goes here. users.users."nexoniarz".packages = with pkgs; [ - # Hardware control (Pantheon itself ships Files/Terminal/Screenshot/ - # notifications/dock/launcher — see services.desktopManager.pantheon - # in modules/desktop.nix, nothing to list here for those) - brightnessctl # Backlight brightness (internal laptop panel) - ddcutil # DDC/CI brightness (external monitors) - lm_sensors # sensors-detect helps ddcutil find I2C buses; also feeds asusctl + + tumbler + brightnessctl + ddcutil + lm_sensors networkmanager # nmcli, for the Wi-Fi hotspot script + xdg-user-dirs # Apps blender @@ -22,35 +52,74 @@ vlc filezilla chromium + obs-studio + sdrppLean + rtl433Lean + lmms + krita # Games prismlauncher - pkgs.osu-lazer-bin + osu-lazer-bin - # Dev: compilers, runtimes, languages + # Dev glibc musl cmake - gnumake # Provides the 'make' command + gnumake gcc python3 openjdk25 - claude-code # AI Developer Assistant + go + claude-code + codex ]; - # Global command-line utilities available everywhere environment.systemPackages = with pkgs; [ git - gh # GitHub CLI — was only installed ad-hoc before (login didn't survive) + gh vim fastfetch gparted + efibootmgr firejail gnupg lmstudio + kdePackages.ark p7zip unzip unrar - libreoffice # GTK3 build — matches Pantheon's native GTK theming, unlike the Qt build + kdePackages.gwenview + kdePackages.kate + kdePackages.qqc2-desktop-style + linphonePackages.linphone-desktop + kdePackages.kcalc + kdePackages.okular + kdePackages.elisa + kdePackages.konsole + kdePackages.dolphin + kdePackages.plasma-systemmonitor + kdePackages.kdialog + qt5.qtwayland + qt6.qtwayland + qemu + file + wineWow64Packages.stable + ghidra + jdk + python3 + radare2 + binwalk + ]; + + # Lets non-Nix binaries (e.g. the Tor Browser bundle) find an FHS linker. + programs.nix-ld.enable = true; + programs.nix-ld.libraries = with pkgs; [ + glib gtk3 gdk-pixbuf pango cairo atk + dbus dbus-glib fontconfig freetype + libx11 libxext libxrender libxtst + libxi libxcomposite libxdamage libxfixes + libxrandr libxcursor libxcb libxkbcommon + alsa-lib mesa zlib stdenv.cc.cc ]; } diff --git a/modules/audio.nix b/modules/audio.nix new file mode 100644 index 0000000..72b30bb --- /dev/null +++ b/modules/audio.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +{ + security.rtkit.enable = true; + services.pulseaudio.enable = false; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + + # Bluetooth headphones are playback-only here (mic comes from the USB + # codec). Disable HSP/HFP so they never drop to 8/16 kHz mono call mode. + wireplumber.extraConfig."11-bluetooth-policy" = { + "wireplumber.settings" = { + "bluetooth.autoswitch-to-headset-profile" = false; + }; + "monitor.bluez.properties" = { + # PC only sends audio. Allowing a2dp_sink lets the Monitor II (which + # also advertises an A2DP source) connect backwards as "audio gateway". + "bluez5.roles" = [ "a2dp_source" ]; + }; + }; + }; +} diff --git a/modules/boot.nix b/modules/boot.nix new file mode 100644 index 0000000..be787ce --- /dev/null +++ b/modules/boot.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +{ + boot.loader.efi.canTouchEfiVariables = true; + boot.loader.limine = { + enable = true; + maxGenerations = 5; + + # Gruvbox, to match the icon theme. + style = { + wallpapers = [ ]; # Solid background; a path here would be used instead + interface = { + branding = "NixOS"; + brandingColor = "fabd2f"; + helpColor = "928374"; + helpColorBright = "d79921"; + }; + graphicalTerminal = { + foreground = "ebdbb2"; + background = "00282828"; + brightForeground = "fbf1c7"; + palette = "282828;cc241d;98971a;d79921;458588;b16286;689d6a;a89984"; + brightPalette = "928374;fb4934;b8bb26;fabd2f;83a598;d3869b;8ec07c;ebdbb2"; + margin = 32; + }; + }; + }; + + boot.kernelPackages = pkgs.linuxPackages; + boot.supportedFilesystems = [ "fuse" ]; + programs.fuse.userAllowOther = true; + + # zram instead of disk swap: nothing sensitive is written to disk in + # plaintext. systemd's gpt-auto-generator would otherwise re-activate the + # old swap partition regardless of swapDevices, hence the kernel param. + zramSwap.enable = true; + swapDevices = lib.mkForce [ ]; + boot.kernelParams = [ "systemd.gpt_auto=0" ]; +} diff --git a/modules/default-apps.nix b/modules/default-apps.nix new file mode 100644 index 0000000..8f43767 --- /dev/null +++ b/modules/default-apps.nix @@ -0,0 +1,80 @@ +{ config, pkgs, lib, ... }: + +{ + environment.systemPackages = with pkgs; [ + libreoffice-qt6 + ]; + + # GIO picks the terminal from here for "Open Terminal" style actions. + environment.etc."xdg/xdg-terminals.list".text = '' + org.kde.konsole.desktop + ''; + + # System-level fallbacks. Per the XDG spec these are only consulted for a + # mimetype the user's own ~/.config/mimeapps.list doesn't already claim, + # so any "Open With" choice you make later still wins over this. + # + # One mimetype=desktopfile pair per line. The semicolon only separates + # multiple candidates for the SAME key — it does not chain separate pairs, + # and parsers match by scanning for a line starting with "mimetype=", so + # cramming several onto one line silently hides all but the first. + environment.etc."xdg/mimeapps.list".text = + let + gwenviewMimes = [ + "image/avif" "image/gif" "image/heif" "image/jpeg" + "image/jxl" "image/png" "image/bmp" "image/x-eps" "image/x-icns" + "image/x-ico" "image/x-portable-bitmap" "image/x-portable-graymap" + "image/x-portable-pixmap" "image/x-xbitmap" "image/x-xpixmap" + "image/tiff" "image/x-psd" "image/x-webp" "image/webp" "image/x-tga" + "image/x-xcf" "image/openraster" "image/svg+xml" "image/svg+xml-compressed" + ]; + arkMimes = [ + "application/x-cd-image" "application/x-bcpio" "application/x-cpio" + "application/x-cpio-compressed" "application/x-rpm" "application/x-compress" + "application/gzip" "application/x-bzip" "application/x-bzip2" + "application/x-lzma" "application/x-xz" "application/zstd" "application/x-lz4" + "application/x-source-rpm" "application/vnd.debian.binary-package" + "application/vnd.ms-cab-compressed" "application/x-archive" "application/x-tar" + "application/x-compressed-tar" "application/x-bzip-compressed-tar" + "application/x-bzip2-compressed-tar" "application/x-tarz" + "application/x-xz-compressed-tar" "application/x-lzma-compressed-tar" + "application/x-7z-compressed" "application/vnd.rar" "application/zip" + "application/x-java-archive" "application/x-arj" + ]; + okularMimes = [ + "application/pdf" "application/x-pdf" "image/vnd.djvu" "application/epub+zip" + "application/x-fictionbook+xml" "application/x-mobipocket-ebook" + "image/x-portable-document" "application/x-cbr" "application/x-cbz" + "application/x-cbt" "application/x-cb7" "application/postscript" + ]; + vlcMimes = [ + "video/mp4" "video/x-matroska" "video/webm" "video/x-msvideo" + "video/quicktime" "video/mpeg" "video/x-ms-wmv" "video/x-flv" + "video/3gpp" "video/ogg" "video/x-theora+ogg" "video/x-ogm+ogg" + "application/x-matroska" "application/vnd.rn-realmedia" + ]; + elisaMimes = [ + "audio/mpeg" "audio/flac" "audio/x-flac" "audio/ogg" "audio/x-vorbis+ogg" + "audio/opus" "audio/x-opus+ogg" "audio/mp4" "audio/aac" "audio/x-wav" + "audio/wav" "audio/x-ms-wma" "audio/x-aiff" "audio/x-musepack" + ]; + kateMimes = [ + "text/plain" "text/markdown" "text/x-csrc" "text/x-c++src" "text/x-chdr" + "text/x-c++hdr" "text/x-python" "text/x-java" "text/x-shellscript" + "text/x-nix" "text/css" "text/html" "text/xml" "application/json" + "application/x-yaml" "application/toml" "application/javascript" + "application/x-shellscript" "text/x-log" + ]; + line = desktop: mime: "${mime}=${desktop}"; + in + '' + [Default Applications] + inode/directory=org.kde.dolphin.desktop + ${lib.concatMapStringsSep "\n" (line "org.kde.gwenview.desktop") gwenviewMimes} + ${lib.concatMapStringsSep "\n" (line "org.kde.ark.desktop") arkMimes} + ${lib.concatMapStringsSep "\n" (line "org.kde.okular.desktop") okularMimes} + ${lib.concatMapStringsSep "\n" (line "vlc.desktop") vlcMimes} + ${lib.concatMapStringsSep "\n" (line "org.kde.elisa.desktop") elisaMimes} + ${lib.concatMapStringsSep "\n" (line "org.kde.kate.desktop") kateMimes} + ''; +} diff --git a/modules/desktop.nix b/modules/desktop.nix index 32d30b5..387ff37 100644 --- a/modules/desktop.nix +++ b/modules/desktop.nix @@ -1,38 +1,72 @@ { config, pkgs, ... }: { - # --- Pantheon: elementary OS's desktop environment (gala compositor, Wayland) --- - # Pulls in its own session (pantheon-wayland), top panel (Wingpanel), dock, - # app launcher, Files, Terminal, Screenshot, Photos, notifications, and - # GTK/icon theming — no separate compositor config or dotfile symlinking - # needed, unlike the previous Hyprland setup. + # Plasma ships a proper Wayland session (KWin) with solid Xwayland + # support; xserver stays on for that Xwayland layer and for the xkb + # layout below, not because the session itself needs it. services.xserver.enable = true; - services.xserver.displayManager.lightdm.enable = true; - services.desktopManager.pantheon.enable = true; + services.desktopManager.plasma6.enable = true; + + # SDDM is KDE's own greeter — Qt-based, and launches Wayland sessions + # natively, Plasma included. + services.displayManager.sddm = { + enable = true; + wayland.enable = true; + }; - # Keyboard layout for LightDM/XWayland; Pantheon's own session picks this - # up too. services.xserver.xkb = { layout = "pl"; variant = ""; }; - security.polkit.enable = true; + services.tumbler.enable = true; + services.gvfs.enable = true; - # Native Wayland backend for Electron/Chromium-based apps - environment.sessionVariables.NIXOS_OZONE_WL = "1"; + # xserver.nix installs xterm unconditionally; Konsole is the terminal here. + services.xserver.excludePackages = [ pkgs.xterm ]; - # Comfortable trackpad defaults for a laptop — tap-to-click and natural - # scrolling aren't on by default, and gala reads touchpad settings from - # GSettings at runtime (not services.libinput, which is X11-only), so - # they're set here as a dconf default instead. - programs.dconf.profiles.user.databases = [ - { - settings."org/gnome/desktop/peripherals/touchpad" = { - tap-to-click = true; - natural-scroll = true; - two-finger-scrolling-enabled = true; - }; - } + # Icon/cursor theme packages. Plasma has no gsettings-style declarative + # knob for this the way Budgie did — pick them in System Settings, or + # bring in plasma-manager later for a fully declarative setup. + environment.systemPackages = [ + pkgs.gruvbox-plus-icons + pkgs.bibata-cursors + ]; + + # The third-party "Bouncing Popups" KWin effect (~/.local/share/kwin/effects) + # stacks on top of Plasma's own slidingpopups/fadingpopups and forces blur + # on every popup and the panel, making applet popups and panel settings + # open sluggishly. [$i] locks the key so ~/.config/kwinrc can't re-enable it. + environment.etc."xdg/kwinrc".text = '' + [Plugins] + bouncingPopupsEnabled[$i]=false + ''; + + # Breeze Dark as the default Plasma (panel/popup) theme. Avoid sparse + # third-party themes like "Darkly" (18 files): every SVG they lack falls + # back via an uncached search of all ~89 XDG_DATA_DIRS, which made applet + # popups and panel settings take 2-6 s to open. Not locked, so the theme + # can still be changed in System Settings. + environment.etc."xdg/plasmarc".text = '' + [Theme] + name=breeze-dark + ''; + + environment.extraInit = '' + export XDG_DATA_DIRS="$XDG_DATA_DIRS:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}" + ''; + + fonts.packages = with pkgs; [ + corefonts + dejavu_fonts + noto-fonts + noto-fonts-cjk-sans + noto-fonts-color-emoji + nerd-fonts.fira-code + nerd-fonts.jetbrains-mono + nerd-fonts.hack + inter + liberation_ttf + roboto ]; } diff --git a/modules/drivers.nix b/modules/drivers.nix deleted file mode 100644 index 0efa83e..0000000 --- a/modules/drivers.nix +++ /dev/null @@ -1,79 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - # Enable graphics driver support and 32-bit acceleration (for Steam/gaming) - hardware.graphics = { - enable = true; - enable32Bit = true; - }; - - #OpenTabletDriver - hardware.opentabletdriver.enable = true; - hardware.uinput.enable = true; - boot.kernelModules = [ "uinput" "v4l2loopback" ]; - - # Virtual webcam device so ffmpeg (fed by the GoPro's stream) can appear - # as a normal camera to apps like Discord. exclusive_caps=1 is required - # for Chromium/WebRTC-based apps to recognize it as a real capture device. - boot.extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ]; - boot.extraModprobeConfig = '' - options v4l2loopback devices=1 video_nr=10 card_label="GoPro Webcam" exclusive_caps=1 - # PS4/PS5 controllers (e.g. DualSense) connect over Bluetooth then - # immediately disconnect — a well-known Linux Bluetooth stack issue - # where many adapters' Enhanced Retransmission Mode implementation is - # broken. Disabling ERTM is the standard, widely-documented fix. - options bluetooth disable_ertm=1 - ''; - - # I2C bus, for DDC/CI monitor control (brightness) via ddcutil, when - # driving an external monitor over DisplayPort/HDMI. The internal panel - # uses the kernel backlight class instead (brightness-ctl picks whichever - # applies — see modules/scripts/brightness-ctl.sh). - hardware.i2c.enable = true; - - # --- Hybrid graphics: AMD Radeon 680M (iGPU, drives the internal panel) - # + NVIDIA RTX 4050 Max-Q (dGPU, offload-only) — ASUS TUF Gaming A15 - # FA507NU. Bus IDs come straight from `lspci` on this machine, not - # guessed: 01:00.0 (NVIDIA) -> PCI:1:0:0, 35:00.0 (AMD) -> PCI:53:0:0. - services.xserver.videoDrivers = [ "nvidia" ]; - - hardware.nvidia = { - # Required settings - modesetting.enable = true; - - # Enable NVIDIA Open GPU Kernel Modules (Turing architecture or newer — - # this RTX 4050 is Ada Lovelace, well within support) - open = true; - - # Enable the NVIDIA settings menu - nvidiaSettings = true; - - # Use the stable driver package matching current kernel - package = config.boot.kernelPackages.nvidiaPackages.stable; - - # Fixes suspend/resume hangs that are common with NVIDIA on laptops. - powerManagement.enable = true; - - # PRIME render offload: the AMD iGPU drives the display at all times - # (much better battery life than keeping the dGPU powered on), and the - # NVIDIA GPU is only spun up on demand for a specific process — run - # anything with `nvidia-offload ` (generated by - # enableOffloadCmd) to route it through the RTX 4050, e.g. games or - # Blender's Cycles renderer. - prime = { - offload = { - enable = true; - enableOffloadCmd = true; - }; - amdgpuBusId = "PCI:53:0:0"; - nvidiaBusId = "PCI:1:0:0"; - }; - }; - - # ASUS laptop control: keyboard backlight/fan curves/battery charge limit - # (asusctl) and dGPU power-state switching between Integrated/Hybrid modes - # (supergfxctl) — the two standard asus-linux.org daemons for ROG/TUF - # laptops, both packaged directly in nixpkgs. - services.asusd.enable = true; - services.supergfxd.enable = true; -} diff --git a/modules/fastfetch.nix b/modules/fastfetch.nix new file mode 100644 index 0000000..9fc70ce --- /dev/null +++ b/modules/fastfetch.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + # System-wide config; fastfetch searches /etc/xdg/fastfetch/ after + # ~/.config/fastfetch/, so a user config there would still win. + environment.etc."xdg/fastfetch/config.jsonc".source = ../configs/fastfetch/config.jsonc; +} diff --git a/modules/firefox.nix b/modules/firefox.nix new file mode 100644 index 0000000..71ee5ea --- /dev/null +++ b/modules/firefox.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +{ + programs.firefox = { + enable = true; + # Not locked: values are reapplied on every Firefox start, but can be + # changed in the UI for the current session. (Read as text: the module + # doesn't copy autoConfigFiles paths into the store.) + autoConfig = builtins.readFile ../configs/firefox/prefs.js; + }; +} diff --git a/modules/hardware.nix b/modules/hardware.nix new file mode 100644 index 0000000..bb8a4f9 --- /dev/null +++ b/modules/hardware.nix @@ -0,0 +1,76 @@ +{ config, lib, pkgs, ... }: + +{ + hardware.graphics = { + enable = true; + enable32Bit = true; + }; + + # Hybrid graphics on the ASUS TUF Gaming A15 (FA507NU): AMD Radeon 680M + # iGPU drives the internal panel, NVIDIA RTX 4050 Max-Q is offload-only. + # Run something on the dGPU with `nvidia-offload `. + # Bus IDs from `lspci` on this machine: 01:00.0 (NVIDIA) -> PCI:1:0:0, + # 35:00.0 (AMD) -> PCI:53:0:0. + services.xserver.videoDrivers = [ "nvidia" ]; + + hardware.nvidia = { + modesetting.enable = true; + open = true; + nvidiaSettings = true; + package = config.boot.kernelPackages.nvidiaPackages.stable; + + # Fixes suspend/resume hangs common with NVIDIA on laptops. + powerManagement.enable = true; + + prime = { + offload = { + enable = true; + enableOffloadCmd = true; + }; + amdgpuBusId = "PCI:53:0:0"; + nvidiaBusId = "PCI:1:0:0"; + }; + }; + # No LIBVA/NVD env vars here (unlike the PC): video decoding runs on the + # AMD iGPU, which libva picks automatically (radeonsi). + + # asusctl (fan curves, keyboard backlight, battery charge limit) and + # supergfxctl (dGPU power-state switching), from asus-linux.org. + services.asusd.enable = true; + services.supergfxd.enable = true; + + hardware.opentabletdriver.enable = true; + hardware.uinput.enable = true; + boot.kernelModules = [ "uinput" ]; + + hardware.bluetooth = { + enable = true; + powerOnBoot = true; + settings = { + General = { + Experimental = true; # Battery level of connected devices + FastConnectable = true; # Faster reconnects, more power draw + }; + Policy = { + AutoEnable = true; + }; + }; + }; + # Plasma ships its own Bluetooth UI (Bluedevil); blueman just duplicated it. + + boot.extraModprobeConfig = '' + # DualSense/PS4 pads pair over Bluetooth then drop instantly; broken + # ERTM in many adapters. Disabling it is the standard fix. + options bluetooth disable_ertm=1 + ''; + + # Blog V4 needs the rtlsdrblog fork of librtlsdr, which is what + # pkgs.rtl-sdr already is here. Also blacklists the DVB-T drivers. + hardware.rtl-sdr.enable = true; + + # For ddcutil on an external monitor; the internal panel uses the kernel + # backlight instead (brightness-ctl picks whichever applies). + hardware.i2c.enable = true; + + services.printing.enable = true; +} diff --git a/modules/locale.nix b/modules/locale.nix new file mode 100644 index 0000000..5cb596e --- /dev/null +++ b/modules/locale.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: + +{ + time.timeZone = "Europe/Warsaw"; + i18n.defaultLocale = "pl_PL.UTF-8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "pl_PL.UTF-8"; + LC_IDENTIFICATION = "pl_PL.UTF-8"; + LC_MEASUREMENT = "pl_PL.UTF-8"; + LC_MONETARY = "pl_PL.UTF-8"; + LC_NAME = "pl_PL.UTF-8"; + LC_NUMERIC = "pl_PL.UTF-8"; + LC_PAPER = "pl_PL.UTF-8"; + LC_TELEPHONE = "pl_PL.UTF-8"; + LC_TIME = "pl_PL.UTF-8"; + }; + + console.keyMap = "pl2"; +} diff --git a/modules/networking.nix b/modules/networking.nix new file mode 100644 index 0000000..69dcd7e --- /dev/null +++ b/modules/networking.nix @@ -0,0 +1,38 @@ +{ config, pkgs, ... }: + +{ + networking.hostName = "nixos"; + networking.networkmanager.enable = true; + + networking.firewall = { + enable = true; + allowPing = true; + allowedTCPPortRanges = [ { from = 1714; to = 1764; } ]; + allowedUDPPortRanges = [ { from = 1714; to = 1764; } ]; + allowedTCPPorts = [ 80 443 ]; + }; + + # DNS-over-TLS via systemd-resolved; NetworkManager defers to it rather + # than writing its own /etc/resolv.conf. + networking.nameservers = [ "1.1.1.1#cloudflare-dns.com" "9.9.9.9#dns.quad9.net" ]; + services.resolved = { + enable = true; + settings.Resolve = { + DNSSEC = "allow-downgrade"; + DNSOverTLS = "true"; + }; + }; + networking.networkmanager.dns = "systemd-resolved"; + + # Ethernet stays "stable" (pseudonymous but consistent) so static DHCP + # reservations on the router keep working; Wi-Fi is fully random. + networking.networkmanager.wifi.macAddress = "random"; + networking.networkmanager.wifi.scanRandMacAddress = true; + networking.networkmanager.ethernet.macAddress = "stable"; + + # Disable NetworkManager's periodic captive-portal probe. + networking.networkmanager.settings.connectivity = { + uri = ""; + interval = 0; + }; +} diff --git a/modules/nix-settings.nix b/modules/nix-settings.nix new file mode 100644 index 0000000..4c04710 --- /dev/null +++ b/modules/nix-settings.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + nixpkgs.config.allowUnfree = true; + + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + nix.settings.auto-optimise-store = true; + + nix.gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 7d"; + }; +} diff --git a/modules/scripts.nix b/modules/scripts.nix index a6a61d8..b720dbc 100644 --- a/modules/scripts.nix +++ b/modules/scripts.nix @@ -1,7 +1,6 @@ { config, pkgs, ... }: let - # Wrap external shell scripts into system executables vaultToggle = pkgs.writeShellScriptBin "vault-toggle" (builtins.readFile ./scripts/vault-toggle.sh); stripMetadata = pkgs.writeShellScriptBin "strip-metadata" (builtins.readFile ./scripts/strip-metadata.sh); brightnessCtl = pkgs.writeShellScriptBin "brightness-ctl" (builtins.readFile ./scripts/brightness-ctl.sh); @@ -10,7 +9,6 @@ let weatherFetch = pkgs.writeShellScriptBin "weather-fetch" (builtins.readFile ./scripts/weather-fetch.sh); in { - # Install CLI dependencies required by the scripts environment.systemPackages = with pkgs; [ gocryptfs exiftool diff --git a/modules/security.nix b/modules/security.nix new file mode 100644 index 0000000..d2621bc --- /dev/null +++ b/modules/security.nix @@ -0,0 +1,38 @@ +{ config, pkgs, ... }: + +{ + security.polkit.enable = true; + + security.sudo.extraConfig = '' + Defaults pwfeedback + ''; + + programs.firejail.enable = true; + + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + pinentryPackage = pkgs.pinentry-rofi; + }; + + boot.kernel.sysctl = { + "kernel.kptr_restrict" = 2; + "kernel.dmesg_restrict" = 1; + "net.ipv4.conf.all.rp_filter" = 1; + "net.ipv4.conf.default.rp_filter" = 1; + "net.ipv4.conf.all.accept_redirects" = false; + "net.ipv4.conf.default.accept_redirects" = false; + "net.ipv6.conf.all.accept_redirects" = false; + "net.ipv6.conf.default.accept_redirects" = false; + "net.ipv4.conf.all.send_redirects" = false; + "net.ipv4.conf.default.send_redirects" = false; + # Only bites ad-hoc `gdb -p ` on a non-child process. + "kernel.yama.ptrace_scope" = 1; + "net.ipv4.tcp_timestamps" = 0; + }; + + systemd.coredump.enable = false; + security.protectKernelImage = true; + + services.geoclue2.enable = false; +} diff --git a/modules/system.nix b/modules/system.nix deleted file mode 100644 index 8118a20..0000000 --- a/modules/system.nix +++ /dev/null @@ -1,204 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - # Bootloader & Kernel - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = true; - boot.loader.systemd-boot.configurationLimit = 5; - boot.kernelPackages = pkgs.linuxPackages; - boot.supportedFilesystems = [ "fuse" ]; - - # Networking - networking.hostName = "nixos"; - networking.networkmanager.enable = true; - - # Firewall Configuration - networking.firewall = { - enable = true; - - # Allow local ping diagnostic queries - allowPing = true; - - allowedTCPPortRanges = [ { from = 1714; to = 1764; } ]; - allowedUDPPortRanges = [ { from = 1714; to = 1764; } ]; - allowedTCPPorts = [ 80 443 ]; - # allowedUDPPorts = [ ]; - }; - - # Time zone and Internationalization - time.timeZone = "Europe/Warsaw"; - i18n.defaultLocale = "pl_PL.UTF-8"; - i18n.extraLocaleSettings = { - LC_ADDRESS = "pl_PL.UTF-8"; - LC_IDENTIFICATION = "pl_PL.UTF-8"; - LC_MEASUREMENT = "pl_PL.UTF-8"; - LC_MONETARY = "pl_PL.UTF-8"; - LC_NAME = "pl_PL.UTF-8"; - LC_NUMERIC = "pl_PL.UTF-8"; - LC_PAPER = "pl_PL.UTF-8"; - LC_TELEPHONE = "pl_PL.UTF-8"; - LC_TIME = "pl_PL.UTF-8"; - }; - - nix.settings.auto-optimise-store = true; - nix.gc = { - automatic = true; - dates = "weekly"; - options = "--delete-older-than 7d"; - }; - - # Console keymap - console.keyMap = "pl2"; - - # Sound and Audio (Pipewire) - security.rtkit.enable = true; - services.pulseaudio.enable = false; - services.pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - }; - - hardware.bluetooth = { - enable = true; - powerOnBoot = true; - settings = { - General = { - # Shows battery charge of connected devices on supported - # Bluetooth adapters. Defaults to 'false'. - Experimental = true; - # When enabled other devices can connect faster to us, however - # the tradeoff is increased power consumption. Defaults to - # 'false'. - FastConnectable = true; - }; - Policy = { - # Enable all controllers when they are found. This includes - # adapters present on start as well as adapters that are plugged - # in later on. Defaults to 'true'. - AutoEnable = true; - }; - }; - }; - - services.blueman.enable = true; - - #Firejail - programs.firejail = { - enable = true; - }; - - #FUSE shit - programs.fuse.userAllowOther = true; - - # Enable GnuPG Agent with GUI pinentry support - programs.gnupg.agent = { - enable = true; - enableSSHSupport = true; - pinentryPackage = pkgs.pinentry-gnome3; # Matches Pantheon's GTK/gnome-keyring stack - }; - - security.sudo.extraConfig = '' - Defaults pwfeedback - ''; - - # Printing services - services.printing.enable = true; - - nixpkgs.config.allowUnfree = true; - - fonts.packages = with pkgs; [ - corefonts - dejavu_fonts - noto-fonts - noto-fonts-cjk-sans - noto-fonts-color-emoji - nerd-fonts.fira-code - nerd-fonts.jetbrains-mono - nerd-fonts.hack - inter - liberation_ttf - roboto - ]; - - # --- Loader shim for running non-Nix-packaged binaries (e.g. the official - # Tor Browser bundle) that expect a standard FHS dynamic linker/libraries. --- - programs.nix-ld.enable = true; - programs.nix-ld.libraries = with pkgs; [ - glib gtk3 gdk-pixbuf pango cairo atk - dbus dbus-glib fontconfig freetype - libx11 libxext libxrender libxtst - libxi libxcomposite libxdamage libxfixes - libxrandr libxcursor libxcb libxkbcommon - alsa-lib mesa zlib stdenv.cc.cc - ]; - environment.systemPackages = [ pkgs.file ]; - - # --- Hardening: swap, kernel sysctls, DNS, MAC randomization --- - - # Swap: replace disk swap with compressed in-RAM swap. Nothing sensitive - # (decrypted vault contents, browser memory, GPG session data) ever gets - # written to disk in plaintext via swap. Also faster than disk swap under - # memory pressure. - zramSwap.enable = true; - swapDevices = lib.mkForce [ ]; - # systemd's gpt-auto-generator independently re-discovers and activates any - # GPT partition tagged as Linux swap, regardless of the swapDevices list - # above — this disables that auto-discovery so the old disk swap partition - # actually stays off. Doesn't affect /, /home, /nix, /boot: those are - # already explicitly declared in hardware-configuration.nix, not relying on - # gpt-auto. Takes effect on next reboot. - boot.kernelParams = [ "systemd.gpt_auto=0" ]; - - # Kernel/system hardening sysctls - boot.kernel.sysctl = { - # Hide kernel pointers from unprivileged users (blocks a common - # local info-leak used in exploit chains). - "kernel.kptr_restrict" = 2; - # Restrict dmesg access to root. - "kernel.dmesg_restrict" = 1; - # Reverse-path filtering: drop packets with spoofed source addresses. - "net.ipv4.conf.all.rp_filter" = 1; - "net.ipv4.conf.default.rp_filter" = 1; - # Don't accept/send ICMP redirects (blocks a classic local MITM trick). - "net.ipv4.conf.all.accept_redirects" = false; - "net.ipv4.conf.default.accept_redirects" = false; - "net.ipv6.conf.all.accept_redirects" = false; - "net.ipv6.conf.default.accept_redirects" = false; - "net.ipv4.conf.all.send_redirects" = false; - "net.ipv4.conf.default.send_redirects" = false; - }; - - # Crash dumps can contain decrypted memory contents, passwords, keys — - # never write them to disk. - systemd.coredump.enable = false; - - # Blocks kexec-based kernel image tampering. - security.protectKernelImage = true; - - # DNS-over-TLS system-wide (Tor Browser already routes its own DNS - # through Tor, so this only affects everything else). Cloudflare + Quad9 - # both support DoT; "allow-downgrade" avoids hard failures on domains - # with broken DNSSEC deployment. - networking.nameservers = [ "1.1.1.1#cloudflare-dns.com" "9.9.9.9#dns.quad9.net" ]; - services.resolved = { - enable = true; - settings.Resolve = { - DNSSEC = "allow-downgrade"; - DNSOverTLS = "true"; - }; - }; - networking.networkmanager.dns = "systemd-resolved"; - - # MAC address randomization. - # WiFi: fully random per connection (you're on ethernet now, but this - # protects you if you ever use WiFi). - # Ethernet: "stable" — a consistent pseudonymous MAC per connection - # profile rather than your real hardware MAC, so it won't break any - # static DHCP reservation/MAC filtering on your OpenWRT router, while - # still not exposing your real hardware identity. - networking.networkmanager.wifi.macAddress = "random"; - networking.networkmanager.wifi.scanRandMacAddress = true; - networking.networkmanager.ethernet.macAddress = "stable"; -} diff --git a/modules/users.nix b/modules/users.nix index fe92cf7..e2e28eb 100644 --- a/modules/users.nix +++ b/modules/users.nix @@ -1,27 +1,26 @@ { config, pkgs, ... }: { - # Primary user account configuration (Access and settings only) users.users."nexoniarz" = { isNormalUser = true; description = "Nexoniarz"; - extraGroups = [ "networkmanager" "wheel" "fuse" "i2c" "video" ]; + extraGroups = [ "networkmanager" "wheel" "fuse" "i2c" "video" "plugdev" ]; shell = pkgs.zsh; }; - # Default shell (ZSH) programs.zsh.enable = true; - # Web browser configuration - programs.firefox.enable = true; - - # Enable Steam with optimized system configurations programs.steam = { enable = true; remotePlay.openFirewall = true; dedicatedServer.openFirewall = true; }; - # Enable Flatpak support services.flatpak.enable = true; + + # Flatpak's exported .desktop files aren't on XDG_DATA_DIRS by default, + # so Bottles would otherwise not show up in the launcher. + systemd.tmpfiles.rules = [ + "L+ /var/lib/flatpak/exports/share/applications - - - - /var/lib/flatpak/app/com.usebottles.bottles/current/active/export/share/applications" + ]; }