mirror of
https://github.com/Nexoniarz/nexoniarz-config-nixos-laptop.git
synced 2026-11-03 04:24:27 +00:00
Bring laptop in line with desktop config: Plasma 6, Limine, module split
The laptop was still on the Hyprland-era Pantheon commit while the desktop moved to KDE Plasma 6 + Limine and split system.nix into focused modules. This brings over everything that isn't hardware, unchanged, so both machines stay diffable: - Plasma 6 on Wayland with SDDM, Konsole, gruvbox icons, KDE MIME defaults (replaces Pantheon/LightDM; libreoffice-qt6 replaces the GTK build) - Limine bootloader with the gruvbox theme, replacing systemd-boot - system.nix split into boot/networking/locale/nix-settings/security - flakes + nix-command, sysctl hardening extras (yama, tcp_timestamps), geoclue off, captive-portal probe off - package parity: obs-studio, lmms, go, qemu, KDE utilities, lean SDR++ and rtl_433 overrides with hardware.rtl-sdr Hardware and power are adapted rather than copied: - hardware.nix keeps the AMD 680M + RTX 4050 PRIME offload setup, asusd and supergfxd, v4l2loopback webcam and the DualSense ERTM fix; OpenRGB and the desktop's single-GPU block are dropped, keyboard lighting is asusctl - power.nix is new: power-profiles-daemon for Plasma's profile switcher, lid-close handling via the current logind.settings.Login spelling, powertop/acpi, notes on asusctl charge limits - no acpi_enforce_resources=lax, ACPI owns the EC asusd drives here - touchpad defaults, and firewall openings so the hotspot script's shared connection can hand out DHCP/DNS - pinentry-qt instead of the desktop's leftover pinentry-rofi, blueman dropped in favour of Plasma's bluedevil hardware-configuration.nix stays tracked here (unlike the desktop, which gitignores it) since it's the only record of this machine's disk layout. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
6bcd5e15ad
commit
654a689fe1
17 changed files with 634 additions and 356 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
.claude
|
||||||
|
result
|
||||||
|
result-*
|
||||||
63
README.md
63
README.md
|
|
@ -1,14 +1,18 @@
|
||||||
# nexoniarz-config-nixos-laptop
|
# nexoniarz-config-nixos-laptop
|
||||||
|
|
||||||
My personal NixOS system configuration tailored for daily use on an
|
My personal NixOS system configuration tailored for daily use on an
|
||||||
**ASUS TUF Gaming A15 (FA507NU)**.
|
**ASUS TUF Gaming A15 (FA507NU)**. Same layout and same choices as
|
||||||
|
[nexoniarz-config-nixos](https://github.com/Nexoniarz/nexoniarz-config-nixos)
|
||||||
|
(the desktop), with the hardware and power modules swapped for this machine.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
- **OS:** NixOS
|
- **OS:** NixOS 26.05 (unstable channel)
|
||||||
- **DE / Compositor:** Pantheon (gala, Wayland)
|
- **Desktop:** KDE Plasma 6 on Wayland (KWin), SDDM
|
||||||
- **Display manager:** LightDM (elementary greeter)
|
- **Bootloader:** Limine
|
||||||
|
- **Terminal:** Konsole
|
||||||
- **Shell:** Zsh
|
- **Shell:** Zsh
|
||||||
|
- **Audio:** PipeWire
|
||||||
- **CPU:** AMD Ryzen 5 7535HS
|
- **CPU:** AMD Ryzen 5 7535HS
|
||||||
- **GPU:** AMD Radeon 680M (iGPU, drives the internal panel) + NVIDIA RTX
|
- **GPU:** AMD Radeon 680M (iGPU, drives the internal panel) + NVIDIA RTX
|
||||||
4050 Max-Q (dGPU, PRIME render offload only — run anything through it with
|
4050 Max-Q (dGPU, PRIME render offload only — run anything through it with
|
||||||
|
|
@ -18,19 +22,44 @@ My personal NixOS system configuration tailored for daily use on an
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
- `configuration.nix` — top-level imports
|
| File | Contents |
|
||||||
- `hardware-configuration.nix` — generated by `nixos-generate-config`, don't
|
|---|---|
|
||||||
hand-edit
|
| `configuration.nix` | Imports only |
|
||||||
- `modules/system.nix` — bootloader, networking, time, sound, hardening,
|
| `hardware-configuration.nix` | Generated by `nixos-generate-config`, don't hand-edit |
|
||||||
nix-ld
|
| `modules/boot.nix` | Limine, kernel, zram/swap |
|
||||||
- `modules/drivers.nix` — hybrid graphics (NVIDIA PRIME offload), ASUS
|
| `modules/networking.nix` | NetworkManager, firewall, DNS-over-TLS, MAC randomization |
|
||||||
daemons, misc hardware (webcam loopback, tablet driver)
|
| `modules/locale.nix` | Timezone, locale, console keymap |
|
||||||
- `modules/desktop.nix` — Pantheon desktop environment
|
| `modules/nix-settings.nix` | Nix features, GC, unfree |
|
||||||
- `modules/users.nix` — user account, Steam, Firefox, Flatpak
|
| `modules/security.nix` | sysctl hardening, sudo, firejail, GnuPG, polkit |
|
||||||
- `modules/apps.nix` — all installed packages
|
| `modules/hardware.nix` | Hybrid graphics (PRIME offload), ASUS daemons, Bluetooth, I2C, RTL-SDR, webcam loopback, tablet, printing |
|
||||||
- `modules/scripts.nix` + `modules/scripts/` — small custom CLI helpers
|
| `modules/power.nix` | Power profiles, lid/suspend behaviour, battery notes |
|
||||||
(encrypted vault toggle, metadata stripping, brightness control, Wi-Fi
|
| `modules/audio.nix` | PipeWire |
|
||||||
hotspot, system telemetry, weather fetch)
|
| `modules/desktop.nix` | Plasma, SDDM, touchpad, 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/` |
|
||||||
|
|
||||||
|
Small custom CLI helpers live in `modules/scripts/`: encrypted vault toggle,
|
||||||
|
metadata stripping, brightness control (kernel backlight or DDC/CI), Wi-Fi
|
||||||
|
hotspot, system telemetry, weather fetch.
|
||||||
|
|
||||||
|
## Differences from the desktop config
|
||||||
|
|
||||||
|
Everything outside hardware is kept identical on purpose. What differs:
|
||||||
|
|
||||||
|
- `modules/hardware.nix` — AMD iGPU + NVIDIA dGPU on PRIME offload with
|
||||||
|
`asusd`/`supergfxd`, instead of the desktop's single NVIDIA card and
|
||||||
|
OpenRGB motherboard lighting. Keyboard lighting is `asusctl aura` here.
|
||||||
|
- `modules/power.nix` — laptop-only module: power-profiles-daemon (Plasma's
|
||||||
|
power profile switcher), lid-close behaviour, `powertop`/`acpi`.
|
||||||
|
- `modules/desktop.nix` — adds touchpad defaults and the Wayland/Ozone flag.
|
||||||
|
- `modules/boot.nix` — no `acpi_enforce_resources=lax`; ACPI owns the EC that
|
||||||
|
`asusd` talks to on this machine.
|
||||||
|
- `modules/networking.nix` — firewall openings for the hotspot script's
|
||||||
|
`ipv4.method shared` dnsmasq.
|
||||||
|
- `modules/security.nix` — `pinentry-qt` (Plasma) rather than the desktop's
|
||||||
|
leftover `pinentry-rofi`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,29 @@
|
||||||
# Main NixOS configuration file importing modular configurations.
|
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configuration.nix # Generated hardware scan results
|
./hardware-configuration.nix
|
||||||
./modules/system.nix # Bootloader, networking, time, sound, hardening, nix-ld
|
|
||||||
./modules/drivers.nix # AMD/NVIDIA hybrid graphics (PRIME) and ASUS laptop control
|
# Core system
|
||||||
./modules/desktop.nix # Pantheon desktop environment (LightDM + gala)
|
./modules/boot.nix
|
||||||
./modules/users.nix # User accounts and global configurations
|
./modules/networking.nix
|
||||||
./modules/apps.nix # All installed packages: apps, CLI tools, dev toolchains
|
./modules/locale.nix
|
||||||
./modules/scripts.nix # Custom system scripts and helpers
|
./modules/nix-settings.nix
|
||||||
|
./modules/security.nix
|
||||||
|
|
||||||
|
# Hardware
|
||||||
|
./modules/hardware.nix
|
||||||
|
./modules/power.nix
|
||||||
|
./modules/audio.nix
|
||||||
|
|
||||||
|
# Desktop & user
|
||||||
|
./modules/desktop.nix
|
||||||
|
./modules/users.nix
|
||||||
|
./modules/apps.nix
|
||||||
|
./modules/default-apps.nix
|
||||||
|
./modules/scripts.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# Do not change this value. Read documentation before updating.
|
# Do not change this value. Read documentation before updating.
|
||||||
system.stateVersion = "26.05";
|
system.stateVersion = "26.05";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,46 @@
|
||||||
{ config, pkgs, ... }:
|
{ 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; [
|
users.users."nexoniarz".packages = with pkgs; [
|
||||||
# Hardware control (Pantheon itself ships Files/Terminal/Screenshot/
|
|
||||||
# notifications/dock/launcher — see services.desktopManager.pantheon
|
tumbler
|
||||||
# in modules/desktop.nix, nothing to list here for those)
|
brightnessctl # Backlight on the internal panel
|
||||||
brightnessctl # Backlight brightness (internal laptop panel)
|
ddcutil # DDC/CI brightness on an external monitor
|
||||||
ddcutil # DDC/CI brightness (external monitors)
|
lm_sensors # sensors-detect also helps ddcutil find its I2C buses
|
||||||
lm_sensors # sensors-detect helps ddcutil find I2C buses; also feeds asusctl
|
networkmanager # nmcli, for the Wi-Fi hotspot script
|
||||||
networkmanager # nmcli, for the Wi-Fi hotspot script
|
xdg-user-dirs
|
||||||
|
|
||||||
# Apps
|
# Apps
|
||||||
blender
|
blender
|
||||||
|
|
@ -22,35 +52,65 @@
|
||||||
vlc
|
vlc
|
||||||
filezilla
|
filezilla
|
||||||
chromium
|
chromium
|
||||||
|
obs-studio
|
||||||
|
sdrppLean
|
||||||
|
rtl433Lean
|
||||||
|
lmms
|
||||||
|
|
||||||
# Games
|
# Games
|
||||||
prismlauncher
|
prismlauncher
|
||||||
pkgs.osu-lazer-bin
|
osu-lazer-bin
|
||||||
|
|
||||||
# Dev: compilers, runtimes, languages
|
# Dev
|
||||||
glibc
|
glibc
|
||||||
musl
|
musl
|
||||||
cmake
|
cmake
|
||||||
gnumake # Provides the 'make' command
|
gnumake
|
||||||
gcc
|
gcc
|
||||||
python3
|
python3
|
||||||
openjdk25
|
openjdk25
|
||||||
claude-code # AI Developer Assistant
|
go
|
||||||
|
claude-code
|
||||||
];
|
];
|
||||||
|
|
||||||
# Global command-line utilities available everywhere
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
git
|
git
|
||||||
gh # GitHub CLI — was only installed ad-hoc before (login didn't survive)
|
gh
|
||||||
vim
|
vim
|
||||||
fastfetch
|
fastfetch
|
||||||
gparted
|
gparted
|
||||||
|
efibootmgr
|
||||||
firejail
|
firejail
|
||||||
gnupg
|
gnupg
|
||||||
lmstudio
|
lmstudio
|
||||||
|
kdePackages.ark
|
||||||
p7zip
|
p7zip
|
||||||
unzip
|
unzip
|
||||||
unrar
|
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
|
||||||
|
qt5.qtwayland
|
||||||
|
qt6.qtwayland
|
||||||
|
qemu
|
||||||
|
file
|
||||||
|
];
|
||||||
|
|
||||||
|
# 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
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
modules/audio.nix
Normal file
12
modules/audio.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
security.rtkit.enable = true;
|
||||||
|
services.pulseaudio.enable = false;
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
alsa.support32Bit = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
47
modules/boot.nix
Normal file
47
modules/boot.nix
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
{ 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
|
||||||
|
# swap partition hardware-configuration.nix still lists, hence the kernel
|
||||||
|
# param. / /home /nix /boot are declared explicitly there, so they don't
|
||||||
|
# depend on gpt-auto.
|
||||||
|
zramSwap.enable = true;
|
||||||
|
swapDevices = lib.mkForce [ ];
|
||||||
|
|
||||||
|
# Unlike the desktop this doesn't carry acpi_enforce_resources=lax: that
|
||||||
|
# only exists there to let lm_sensors poke the Super I/O chip behind ACPI's
|
||||||
|
# back, and on a laptop — where ACPI genuinely owns the EC that asusd talks
|
||||||
|
# to — relaxing it is how you get fan/thermal weirdness. CPU temps come
|
||||||
|
# from k10temp, everything else from asusd.
|
||||||
|
boot.kernelParams = [ "systemd.gpt_auto=0" ];
|
||||||
|
}
|
||||||
80
modules/default-apps.nix
Normal file
80
modules/default-apps.nix
Normal file
|
|
@ -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}
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
@ -1,38 +1,74 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# --- Pantheon: elementary OS's desktop environment (gala compositor, Wayland) ---
|
# Plasma ships a proper Wayland session (KWin) with solid Xwayland
|
||||||
# Pulls in its own session (pantheon-wayland), top panel (Wingpanel), dock,
|
# support; xserver stays on for that Xwayland layer and for the xkb
|
||||||
# app launcher, Files, Terminal, Screenshot, Photos, notifications, and
|
# layout below, not because the session itself needs it.
|
||||||
# GTK/icon theming — no separate compositor config or dotfile symlinking
|
|
||||||
# needed, unlike the previous Hyprland setup.
|
|
||||||
services.xserver.enable = true;
|
services.xserver.enable = true;
|
||||||
services.xserver.displayManager.lightdm.enable = true;
|
services.desktopManager.plasma6.enable = true;
|
||||||
services.desktopManager.pantheon.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 = {
|
services.xserver.xkb = {
|
||||||
layout = "pl";
|
layout = "pl";
|
||||||
variant = "";
|
variant = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
security.polkit.enable = true;
|
services.tumbler.enable = true;
|
||||||
|
services.gvfs.enable = true;
|
||||||
|
|
||||||
# Native Wayland backend for Electron/Chromium-based apps
|
# xserver.nix installs xterm unconditionally; Konsole is the terminal here.
|
||||||
|
services.xserver.excludePackages = [ pkgs.xterm ];
|
||||||
|
|
||||||
|
# Native Wayland backend for the Electron/Chromium apps (vesktop, chromium,
|
||||||
|
# lmstudio) instead of letting them fall back to Xwayland.
|
||||||
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
||||||
|
|
||||||
# Comfortable trackpad defaults for a laptop — tap-to-click and natural
|
# Laptop trackpad. This writes an Xorg/libinput snippet, so it covers
|
||||||
# scrolling aren't on by default, and gala reads touchpad settings from
|
# Xwayland and any X11 session — KWin's own Wayland session keeps touchpad
|
||||||
# GSettings at runtime (not services.libinput, which is X11-only), so
|
# settings per-device in ~/.config/kcminputrc instead (System Settings →
|
||||||
# they're set here as a dconf default instead.
|
# Mouse & Touchpad), and those keys are keyed by the device's VID/PID, so
|
||||||
programs.dconf.profiles.user.databases = [
|
# they can't be pinned down from another machine. Set them once there, or
|
||||||
{
|
# bring in plasma-manager if you want them declarative too.
|
||||||
settings."org/gnome/desktop/peripherals/touchpad" = {
|
services.libinput.enable = true;
|
||||||
tap-to-click = true;
|
services.libinput.touchpad = {
|
||||||
natural-scroll = true;
|
tapping = true;
|
||||||
two-finger-scrolling-enabled = true;
|
naturalScrolling = true;
|
||||||
};
|
disableWhileTyping = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
# Hybrid graphics: KWin normally picks the right GPU on its own, but if a
|
||||||
|
# session ever comes up rendering on the RTX 4050 (hot, loud, worse battery)
|
||||||
|
# pin it to the AMD iGPU — bus 35:00.0 from `lspci`. Verify the path exists
|
||||||
|
# before enabling, an invalid device makes KWin fail to start:
|
||||||
|
# ls /dev/dri/by-path/
|
||||||
|
# environment.sessionVariables.KWIN_DRM_DEVICES =
|
||||||
|
# "/dev/dri/by-path/pci-0000:35:00.0-card";
|
||||||
|
|
||||||
|
# Icon/cursor theme packages. Plasma has no gsettings-style declarative
|
||||||
|
# knob for this the way Pantheon 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
|
||||||
|
];
|
||||||
|
|
||||||
|
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
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 <command>` (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;
|
|
||||||
}
|
|
||||||
110
modules/hardware.nix
Normal file
110
modules/hardware.nix
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
hardware.graphics = {
|
||||||
|
enable = true;
|
||||||
|
enable32Bit = 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
|
||||||
|
# (the PCI: form is decimal, 0x35 = 53).
|
||||||
|
services.xserver.videoDrivers = [ "nvidia" ];
|
||||||
|
|
||||||
|
hardware.nvidia = {
|
||||||
|
modesetting.enable = true;
|
||||||
|
|
||||||
|
# Open GPU kernel modules — fine on Turing or newer, and this Ada
|
||||||
|
# Lovelace RTX 4050 is well within support.
|
||||||
|
open = true;
|
||||||
|
nvidiaSettings = true;
|
||||||
|
package = config.boot.kernelPackages.nvidiaPackages.stable;
|
||||||
|
|
||||||
|
# Preserves video memory across suspend/resume, which is what fixes the
|
||||||
|
# classic NVIDIA-laptop "black screen after lid close" hang.
|
||||||
|
powerManagement.enable = true;
|
||||||
|
|
||||||
|
# Runtime PM, i.e. letting the dGPU drop to D3cold when idle, is left
|
||||||
|
# off on purpose: supergfxd below already power-cycles the dGPU when you
|
||||||
|
# switch to Integrated mode, and driving both power paths at once is the
|
||||||
|
# usual source of resume hangs on TUF laptops. If you want to try it:
|
||||||
|
# powerManagement.finegrained = 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 only spins up on demand for a specific process — run
|
||||||
|
# anything with `nvidia-offload <command>` (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;
|
||||||
|
|
||||||
|
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
|
||||||
|
# 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
|
||||||
|
'';
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# No blueman here: Plasma brings its own Bluetooth stack (bluedevil), and
|
||||||
|
# running the GTK applet alongside it just gives you two tray icons
|
||||||
|
# fighting over the same adapter. The desktop repo still has it enabled,
|
||||||
|
# left over from the Budgie days.
|
||||||
|
|
||||||
|
# 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;
|
||||||
|
|
||||||
|
# I2C bus, for DDC/CI brightness on an external monitor over HDMI/USB-C
|
||||||
|
# via ddcutil. The internal panel goes through the kernel backlight class
|
||||||
|
# instead — brightness-ctl picks whichever applies, see
|
||||||
|
# modules/scripts/brightness-ctl.sh.
|
||||||
|
hardware.i2c.enable = true;
|
||||||
|
|
||||||
|
services.udev.extraRules = ''
|
||||||
|
# ddcutil without root (i2c group, see modules/users.nix)
|
||||||
|
SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660"
|
||||||
|
'';
|
||||||
|
|
||||||
|
# No OpenRGB: that's the desktop's motherboard/RAM lighting. The keyboard
|
||||||
|
# backlight on this machine is asusd's job (`asusctl aura`).
|
||||||
|
|
||||||
|
services.printing.enable = true;
|
||||||
|
}
|
||||||
19
modules/locale.nix
Normal file
19
modules/locale.nix
Normal file
|
|
@ -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";
|
||||||
|
}
|
||||||
52
modules/networking.nix
Normal file
52
modules/networking.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
{ 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 ];
|
||||||
|
|
||||||
|
# modules/scripts/hotspot-start.sh brings up an AP with
|
||||||
|
# `ipv4.method shared`, which has NetworkManager spawn dnsmasq on the
|
||||||
|
# Wi-Fi interface. Without these the hotspot associates but clients never
|
||||||
|
# get a lease, because the global firewall drops their DHCP and DNS
|
||||||
|
# queries. Scoped to the Wi-Fi interface only ("wl+" is the iptables
|
||||||
|
# wildcard, so it covers wlan0/wlp*), and dnsmasq only listens while the
|
||||||
|
# hotspot profile is up — the same NIC can't be AP and client at once.
|
||||||
|
interfaces."wl+" = {
|
||||||
|
allowedUDPPorts = [ 53 67 ];
|
||||||
|
allowedTCPPorts = [ 53 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# 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, which
|
||||||
|
# matters more here than on the desktop — this machine joins other
|
||||||
|
# people's networks.
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
14
modules/nix-settings.nix
Normal file
14
modules/nix-settings.nix
Normal file
|
|
@ -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";
|
||||||
|
};
|
||||||
|
}
|
||||||
48
modules/power.nix
Normal file
48
modules/power.nix
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Suspend-to-RAM support and the powersave plumbing Plasma builds on:
|
||||||
|
# plasma6.nix turns powerdevil and upower on when this is set, and it
|
||||||
|
# defaults to true — spelled out here because on a laptop it matters.
|
||||||
|
powerManagement.enable = true;
|
||||||
|
|
||||||
|
# Backs Plasma's Power Profiles switcher (Performance / Balanced /
|
||||||
|
# Power Saver in the battery applet). Plasma already defaults it on; kept
|
||||||
|
# explicit since it's the one knob that actually changes CPU behaviour.
|
||||||
|
# Mutually exclusive with tlp and auto-cpufreq — don't add either.
|
||||||
|
services.power-profiles-daemon.enable = true;
|
||||||
|
|
||||||
|
# Lid behaviour. Closing the lid suspends on battery, but only locks when
|
||||||
|
# docked or on AC, so an external-monitor setup keeps running with the lid
|
||||||
|
# shut. Renamed options: this is services.logind.settings.Login now, the
|
||||||
|
# old services.logind.lidSwitch spelling is deprecated in 26.05.
|
||||||
|
services.logind.settings.Login = {
|
||||||
|
HandleLidSwitch = "suspend";
|
||||||
|
HandleLidSwitchExternalPower = "lock";
|
||||||
|
HandleLidSwitchDocked = "ignore";
|
||||||
|
HandlePowerKey = "suspend";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Hibernate isn't available and won't be: swap is zram-only (see
|
||||||
|
# modules/boot.nix), and security.protectKernelImage in modules/security.nix
|
||||||
|
# blocks the kexec path hibernation resume needs anyway.
|
||||||
|
|
||||||
|
# Battery longevity is asusd's department rather than a NixOS option —
|
||||||
|
# there's no hardware.asus module in nixpkgs. Set it once and asusd
|
||||||
|
# persists it across reboots:
|
||||||
|
# asusctl -c 80 # stop charging at 80%
|
||||||
|
# asusctl -c 100 # back to full, before a trip
|
||||||
|
# Fan curves and keyboard lighting likewise: `asusctl profile -l`,
|
||||||
|
# `asusctl aura -h`.
|
||||||
|
|
||||||
|
# amd_pstate is left at the kernel's own default. Forcing
|
||||||
|
# "amd_pstate=active" is the usual tweak for Zen 3+ laptops, but 6.18
|
||||||
|
# already picks it when the firmware advertises CPPC, so pinning it here
|
||||||
|
# would only matter if the BIOS regressed:
|
||||||
|
# boot.kernelParams = [ "amd_pstate=active" ];
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
powertop # `powertop --auto-tune` and per-process wakeup accounting
|
||||||
|
acpi # quick battery/thermal readout from a terminal
|
||||||
|
];
|
||||||
|
}
|
||||||
40
modules/security.nix
Normal file
40
modules/security.nix
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
security.polkit.enable = true;
|
||||||
|
|
||||||
|
security.sudo.extraConfig = ''
|
||||||
|
Defaults pwfeedback
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.firejail.enable = true;
|
||||||
|
|
||||||
|
programs.gnupg.agent = {
|
||||||
|
enable = true;
|
||||||
|
enableSSHSupport = true;
|
||||||
|
# Qt pinentry to match Plasma (the desktop still says pinentry-rofi, a
|
||||||
|
# leftover from its Hyprland days — rofi isn't even installed there).
|
||||||
|
pinentryPackage = pkgs.pinentry-qt;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 <pid>` 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;
|
||||||
|
}
|
||||||
|
|
@ -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";
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +1,27 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# Primary user account configuration (Access and settings only)
|
|
||||||
users.users."nexoniarz" = {
|
users.users."nexoniarz" = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
description = "Nexoniarz";
|
description = "Nexoniarz";
|
||||||
extraGroups = [ "networkmanager" "wheel" "fuse" "i2c" "video" ];
|
extraGroups = [ "networkmanager" "wheel" "fuse" "i2c" "video" "plugdev" ];
|
||||||
shell = pkgs.zsh;
|
shell = pkgs.zsh;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Default shell (ZSH)
|
|
||||||
programs.zsh.enable = true;
|
programs.zsh.enable = true;
|
||||||
|
|
||||||
# Web browser configuration
|
|
||||||
programs.firefox.enable = true;
|
programs.firefox.enable = true;
|
||||||
|
|
||||||
# Enable Steam with optimized system configurations
|
|
||||||
programs.steam = {
|
programs.steam = {
|
||||||
enable = true;
|
enable = true;
|
||||||
remotePlay.openFirewall = true;
|
remotePlay.openFirewall = true;
|
||||||
dedicatedServer.openFirewall = true;
|
dedicatedServer.openFirewall = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Enable Flatpak support
|
|
||||||
services.flatpak.enable = true;
|
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"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue