mirror of
https://github.com/Nexoniarz/nexoniarz-config-nixos-laptop.git
synced 2026-11-02 20:14:27 +00:00
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 <noreply@anthropic.com>
This commit is contained in:
parent
6bcd5e15ad
commit
863abb4fd3
21 changed files with 754 additions and 367 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.claude
|
||||
result
|
||||
result-*
|
||||
53
README.md
53
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 <command>`)
|
||||
- **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 <command>`)
|
||||
- **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 |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
80
configs/fastfetch/config.jsonc
Normal file
80
configs/fastfetch/config.jsonc
Normal file
|
|
@ -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 }
|
||||
]
|
||||
}
|
||||
121
configs/firefox/prefs.js
Normal file
121
configs/firefox/prefs.js
Normal file
|
|
@ -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);
|
||||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
];
|
||||
}
|
||||
|
|
|
|||
25
modules/audio.nix
Normal file
25
modules/audio.nix
Normal file
|
|
@ -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" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
39
modules/boot.nix
Normal file
39
modules/boot.nix
Normal file
|
|
@ -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" ];
|
||||
}
|
||||
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,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
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
7
modules/fastfetch.nix
Normal file
7
modules/fastfetch.nix
Normal file
|
|
@ -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;
|
||||
}
|
||||
11
modules/firefox.nix
Normal file
11
modules/firefox.nix
Normal file
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
76
modules/hardware.nix
Normal file
76
modules/hardware.nix
Normal file
|
|
@ -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 <command>`.
|
||||
# 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;
|
||||
}
|
||||
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";
|
||||
}
|
||||
38
modules/networking.nix
Normal file
38
modules/networking.nix
Normal file
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
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";
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
38
modules/security.nix
Normal file
38
modules/security.nix
Normal file
|
|
@ -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 <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,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"
|
||||
];
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue