fix(searxng): resolve 502 error and apply Catppuccin theme

- Fix Redis connection by using container-to-container networking.
- Apply Catppuccin (Mocha/Latte) theme via custom CSS.
- Enable SearXNG module in host configuration.
- Configure Caddy reverse proxy and DDclient for search.ashisgreat.xyz.
This commit is contained in:
ashisgreat22 2026-01-19 20:43:22 +01:00
parent 2be8de47fa
commit 6ada19e490
55 changed files with 2502 additions and 269 deletions

View file

@ -6,13 +6,25 @@
... ...
}: }:
{ {
# Noctalia shell
# Noctalia shell # Noctalia shell
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default
ydotool
]; ];
environment.etc."glfw".source = "${pkgs.glfw}/lib"; environment.etc."glfw".source = "${pkgs.glfw}/lib";
boot.kernelModules = [
"uinput"
];
users.groups.uinput = { };
users.users.ashie.extraGroups = [ "uinput" ];
services.udev.extraRules = ''
KERNEL=="uinput", GROUP="uinput", MODE="0660", OPTIONS+="static_node=uinput"
'';
# FORCE Root Filesystem to satisfy assertions # FORCE Root Filesystem to satisfy assertions
fileSystems."/" = lib.mkForce { fileSystems."/" = lib.mkForce {
device = "none"; device = "none";
@ -34,12 +46,14 @@
./system/packages.nix # Package list ./system/packages.nix # Package list
./system/users.nix # User accounts ./system/users.nix # User accounts
./system/greetd.nix # Display manager ./system/greetd.nix # Display manager
./modules/system/cosmic.nix # Cosmic Desktop
./system/kernel.nix # CachyOS kernel ./system/kernel.nix # CachyOS kernel
./system/locate.nix # mlocate ./system/locate.nix # mlocate
./system/secrets.nix # SOPS secrets ./system/secrets.nix # SOPS secrets
./system/compatibility.nix # Compatibility layers (nix-ld) ./system/compatibility.nix # Compatibility layers (nix-ld)
./system/game-drive.nix ./system/game-drive.nix
# ./system/vpn.nix # Uncomment to enable WireGuard VPN ./system/vpn-namespace.nix # Isolated VPN Namespace
./modules/system/media.nix # Arr Stack
]; ];
nixpkgs.config.allowUnfreePredicate = nixpkgs.config.allowUnfreePredicate =
@ -102,7 +116,6 @@
# Binary caches for CachyOS kernel # Binary caches for CachyOS kernel
nix.settings.substituters = [ nix.settings.substituters = [
"https://cache.cachyos.org"
"https://hyprland.cachix.org" "https://hyprland.cachix.org"
"https://nix-community.cachix.org" "https://nix-community.cachix.org"
"https://attic.xuyh0120.win/lantian" "https://attic.xuyh0120.win/lantian"
@ -116,6 +129,10 @@
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g=" "cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
]; ];
# Registry pinning for instant shell startups
nix.registry.nixpkgs.flake = inputs.nixpkgs;
nix.channel.enable = false; # We are using flakes
# Enable performance optimizations # Enable performance optimizations
myModules.performance.enable = true; myModules.performance.enable = true;

275
flake.lock generated
View file

@ -3,11 +3,11 @@
"cachyos-kernel": { "cachyos-kernel": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1768206129, "lastModified": 1768669154,
"narHash": "sha256-BpTer/+8ZSHq4hXbfN/DZh1rru3LVCapp6ks1nyuWj0=", "narHash": "sha256-n9peTL7TAv1FIsboTEE1nWvuY2HYB67Jhh8o4O/JGfY=",
"owner": "CachyOS", "owner": "CachyOS",
"repo": "linux-cachyos", "repo": "linux-cachyos",
"rev": "8e4d77a4aeef28c8e93fd9b724d61a84b11b384f", "rev": "4d7506c820f0d18fc0bbc36ecfec8ed126aee682",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -19,11 +19,11 @@
"cachyos-kernel-patches": { "cachyos-kernel-patches": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1768204281, "lastModified": 1768668945,
"narHash": "sha256-4GraDM1qDeLxPWlyN7+SaN/lgsvZxW+hAcxb3192+aE=", "narHash": "sha256-XKQ3DHUnaa/00BfIaY6K8xCZgx0Sy2wXQbNYE/AmWSk=",
"owner": "CachyOS", "owner": "CachyOS",
"repo": "kernel-patches", "repo": "kernel-patches",
"rev": "11908b28acba425e0acfa8a68f6488e665d6e25c", "rev": "cba022ec33a81d60a1e2c9fe4622196e3fef2b54",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -37,11 +37,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1767967164, "lastModified": 1768575137,
"narHash": "sha256-Cx4VETh9dGoQYDtWhre7g66d7SAr+h1h6f+SSHxVrck=", "narHash": "sha256-e0SsKnkSnq+UwZNS9ZyPJjTjabzq9TRc1hqeDnvOF1Q=",
"owner": "catppuccin", "owner": "catppuccin",
"repo": "nix", "repo": "nix",
"rev": "e973584280e3b0e1d5b5a1a5e9948dc222c54af7", "rev": "48e67b4ad22072f1ae30b0ed8e1cb020cf06c611",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -50,6 +50,30 @@
"type": "github" "type": "github"
} }
}, },
"cosmic-manager": {
"inputs": {
"flake-parts": "flake-parts",
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1765831383,
"narHash": "sha256-P5F/VPjjGw7s0AOTPb3z3gxqtH0YkAnd/c9P6QdWrEU=",
"owner": "HeitorAugustoLN",
"repo": "cosmic-manager",
"rev": "819d4d21fb90460dd11416d81d2cff65a53b8a59",
"type": "github"
},
"original": {
"owner": "HeitorAugustoLN",
"repo": "cosmic-manager",
"type": "github"
}
},
"crane": { "crane": {
"locked": { "locked": {
"lastModified": 1767744144, "lastModified": 1767744144,
@ -98,9 +122,48 @@
} }
}, },
"flake-parts": { "flake-parts": {
"inputs": {
"nixpkgs-lib": [
"cosmic-manager",
"nixpkgs"
]
},
"locked": {
"lastModified": 1759362264,
"narHash": "sha256-wfG0S7pltlYyZTM+qqlhJ7GMw2fTF4mLKCIVhLii/4M=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "758cf7296bee11f1706a574c77d072b8a7baa881",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": { "inputs": {
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
"locked": {
"lastModified": 1767609335,
"narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "250481aafeb741edfe23d29195671c19b36b6dca",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_3": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib_2"
},
"locked": { "locked": {
"lastModified": 1768135262, "lastModified": 1768135262,
"narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=",
@ -115,7 +178,28 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts_2": { "flake-parts_4": {
"inputs": {
"nixpkgs-lib": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1765835352,
"narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "a34fae9c08a15ad73f295041fec82323541400a9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_5": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"steam-config-nix", "steam-config-nix",
@ -183,11 +267,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1768271922, "lastModified": 1768749864,
"narHash": "sha256-zmFw7AtcmfMxW3vR7AiGeQQeHhdrd2x7a3hxzd6vJYI=", "narHash": "sha256-EKRMFBLBRCHrFZ5luX85RTnsN3b2q3FjZEi62vXwJBE=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "fbd566923adcfa67be512a14a79467e2ab8a5777", "rev": "5148e08046dc8c74c66b8aee4d302a47d6931b56",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -204,11 +288,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1747978958, "lastModified": 1768598210,
"narHash": "sha256-pQQnbxWpY3IiZqgelXHIe/OAE/Yv4NSQq7fch7M6nXQ=", "narHash": "sha256-kkgA32s/f4jaa4UG+2f8C225Qvclxnqs76mf8zvTVPg=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "7419250703fd5eb50e99bdfb07a86671939103ea", "rev": "c47b2cc64a629f8e075de52e4742de688f930dc6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -225,11 +309,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1767822991, "lastModified": 1768749749,
"narHash": "sha256-iyrn9AcPZCoyxX4OT8eMkBsjG7SRUQXXS/V1JzxS7rA=", "narHash": "sha256-LznsuRIp4RyjOy6EuHYbmgMx9MQ2lUSH3ymfNPE+O9w=",
"owner": "nix-community", "owner": "nix-community",
"repo": "impermanence", "repo": "impermanence",
"rev": "82e5bc4508cab9e8d5a136626276eb5bbce5e9c5", "rev": "7d905a5a23f26b62c5b68129ef3780409088327a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -305,6 +389,27 @@
"type": "github" "type": "github"
} }
}, },
"mcp-nixos": {
"inputs": {
"flake-parts": "flake-parts_2",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1767822362,
"narHash": "sha256-rnpIDY/sy/uV+1dsW+MrFwAFE/RHg5K/6aa5k7Yt1Dc=",
"owner": "utensils",
"repo": "mcp-nixos",
"rev": "9706014c1530ba12ff36ca8d9d1717b1e61d29db",
"type": "github"
},
"original": {
"owner": "utensils",
"repo": "mcp-nixos",
"type": "github"
}
},
"niri": { "niri": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -313,11 +418,11 @@
"rust-overlay": "rust-overlay_2" "rust-overlay": "rust-overlay_2"
}, },
"locked": { "locked": {
"lastModified": 1768196703, "lastModified": 1768678265,
"narHash": "sha256-mttBQdVnVFO3mn+M+oqCsZZOtS2HvXYy+VaHxb8YuMw=", "narHash": "sha256-Ub8eed4DsfIDWyg30xEe+8bSxL/z5Af/gCjmvJ0V/Hs=",
"owner": "YaLTeR", "owner": "YaLTeR",
"repo": "niri", "repo": "niri",
"rev": "3672e79369d72297abda8878245ea4ec327062c6", "rev": "d7184a04b904e07113f4623610775ae78d32394c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -353,15 +458,15 @@
"cachyos-kernel": "cachyos-kernel", "cachyos-kernel": "cachyos-kernel",
"cachyos-kernel-patches": "cachyos-kernel-patches", "cachyos-kernel-patches": "cachyos-kernel-patches",
"flake-compat": "flake-compat_2", "flake-compat": "flake-compat_2",
"flake-parts": "flake-parts", "flake-parts": "flake-parts_3",
"nixpkgs": "nixpkgs_4" "nixpkgs": "nixpkgs_4"
}, },
"locked": { "locked": {
"lastModified": 1768240180, "lastModified": 1768697537,
"narHash": "sha256-7OHZ5iSiiHLteGG9WSQDsGlr731vbNEmraML1Vh8I+s=", "narHash": "sha256-+3arRjix3ZmBM7ijdB95tkmcuOTrLCIZba7up+YXihY=",
"owner": "xddxdd", "owner": "xddxdd",
"repo": "nix-cachyos-kernel", "repo": "nix-cachyos-kernel",
"rev": "b555ec531ba870b0aeecbec46a7c75f9c6e88c09", "rev": "a9f4771d31a7fe8a74711b5a77bb77bfddc2d18b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -370,29 +475,13 @@
"type": "github" "type": "github"
} }
}, },
"nix-flatpak": {
"locked": {
"lastModified": 1767983141,
"narHash": "sha256-7ZCulYUD9RmJIDULTRkGLSW1faMpDlPKcbWJLYHoXcs=",
"owner": "gmodena",
"repo": "nix-flatpak",
"rev": "440818969ac2cbd77bfe025e884d0aa528991374",
"type": "github"
},
"original": {
"owner": "gmodena",
"ref": "latest",
"repo": "nix-flatpak",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1767116409, "lastModified": 1768305791,
"narHash": "sha256-5vKw92l1GyTnjoLzEagJy5V5mDFck72LiQWZSOnSicw=", "narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "cad22e7d996aea55ecab064e84834289143e44a0", "rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -417,6 +506,21 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-lib_2": {
"locked": {
"lastModified": 1765674936,
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1758035966, "lastModified": 1758035966,
@ -451,11 +555,11 @@
}, },
"nixpkgs_4": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1768207485, "lastModified": 1768640357,
"narHash": "sha256-4HuteAAt/c9IXq5u2qRRGxYwL/ohww5J/jml6zJPzpw=", "narHash": "sha256-NRmPViu76stpOUahRWuR3zMKfY2dKr/qAxRlcqfyps4=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "8b162715b04e986c97788e1edf254d319681e4ae", "rev": "d157866bc6cc1a986f88f6e78a6884efeeec6187",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -467,11 +571,11 @@
}, },
"nixpkgs_5": { "nixpkgs_5": {
"locked": { "locked": {
"lastModified": 1768127708, "lastModified": 1768564909,
"narHash": "sha256-1Sm77VfZh3mU0F5OqKABNLWxOuDeHIlcFjsXeeiPazs=", "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "ffbc9f8cbaacfb331b6017d5a5abb21a492c9a38", "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -480,6 +584,28 @@
"type": "indirect" "type": "indirect"
} }
}, },
"nixvim": {
"inputs": {
"flake-parts": "flake-parts_4",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_2"
},
"locked": {
"lastModified": 1768486009,
"narHash": "sha256-I7ymDe6UQooHy9I9wrafKCCDnRbox/EMWAgJgpm7fGs=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "03a638205b5cb04ba9c2ed6c604e137b15f07fa1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixvim",
"type": "github"
}
},
"noctalia": { "noctalia": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -487,11 +613,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1768305888, "lastModified": 1768757767,
"narHash": "sha256-PJ0CbkW/u2M8JBPL1+fR3hljZHl5qJy7BXKKf51EeLE=", "narHash": "sha256-/z02Cp48mTQBh77DU2c0QefO048a3LHsXtINI/8Vuyc=",
"owner": "noctalia-dev", "owner": "noctalia-dev",
"repo": "noctalia-shell", "repo": "noctalia-shell",
"rev": "12090997885d087f86c7bcdf748dd31deece7507", "rev": "e24582770e0b422adeacd2da2254235dc489a691",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -571,11 +697,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1768284897, "lastModified": 1768691866,
"narHash": "sha256-gZS0Pf/fwZGyRmvMQNyE3GWayKdNqVD47u0YRkYZiVQ=", "narHash": "sha256-MvnxwwfyO4fwozHlMWC4vW8l5GVNuv2ojwWtFOk/fUg=",
"owner": "PrismLauncher", "owner": "PrismLauncher",
"repo": "PrismLauncher", "repo": "PrismLauncher",
"rev": "c2fc0a30b789c63667eb1514b113a2bca6704330", "rev": "e8b5d491545f181599aaba610e53196e658a8bf2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -587,14 +713,16 @@
"root": { "root": {
"inputs": { "inputs": {
"catppuccin": "catppuccin", "catppuccin": "catppuccin",
"cosmic-manager": "cosmic-manager",
"home-manager": "home-manager", "home-manager": "home-manager",
"impermanence": "impermanence", "impermanence": "impermanence",
"lanzaboote": "lanzaboote", "lanzaboote": "lanzaboote",
"mcp-nixos": "mcp-nixos",
"niri": "niri", "niri": "niri",
"nix-bwrapper": "nix-bwrapper", "nix-bwrapper": "nix-bwrapper",
"nix-cachyos-kernel": "nix-cachyos-kernel", "nix-cachyos-kernel": "nix-cachyos-kernel",
"nix-flatpak": "nix-flatpak",
"nixpkgs": "nixpkgs_5", "nixpkgs": "nixpkgs_5",
"nixvim": "nixvim",
"noctalia": "noctalia", "noctalia": "noctalia",
"opencode-flake": "opencode-flake", "opencode-flake": "opencode-flake",
"prismlauncher": "prismlauncher", "prismlauncher": "prismlauncher",
@ -651,11 +779,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1768271704, "lastModified": 1768709255,
"narHash": "sha256-jJqlW8A3OZ5tYbXphF7U8P8g/3Cn8PPwPa4YlJ/9agg=", "narHash": "sha256-aigyBfxI20FRtqajVMYXHtj5gHXENY2gLAXEhfJ8/WM=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "691b8b6713855d0fe463993867291c158472fc6f", "rev": "5e8fae80726b66e9fec023d21cd3b3e638597aa9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -666,18 +794,18 @@
}, },
"steam-config-nix": { "steam-config-nix": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_2", "flake-parts": "flake-parts_5",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"systems": "systems_2" "systems": "systems_3"
}, },
"locked": { "locked": {
"lastModified": 1767484813, "lastModified": 1768615900,
"narHash": "sha256-zSpaCHGORhPi5tQufxD1NeYNS85sTZzszDcDYGBayvU=", "narHash": "sha256-5Xfic5IZvg92mcW0sq+kFOh1PWgH7DO5WkxPYsDFDcY=",
"owner": "different-name", "owner": "different-name",
"repo": "steam-config-nix", "repo": "steam-config-nix",
"rev": "c07a36b9f941766c7f1cf06231fe1fb0cc718a7e", "rev": "083054c75cda3d5de25d6fc61aa3e779563c57f8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -716,6 +844,21 @@
"type": "github" "type": "github"
} }
}, },
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": { "treefmt-nix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_3" "nixpkgs": "nixpkgs_3"

View file

@ -8,62 +8,73 @@
url = "github:xddxdd/nix-cachyos-kernel"; url = "github:xddxdd/nix-cachyos-kernel";
}; };
nix-flatpak = {
url = "github:gmodena/nix-flatpak/?ref=latest";
inputs.nixpkgs.follows = "nixpkgs";
};
sops-nix = { sops-nix = {
url = "github:Mic92/sops-nix"; url = "github:Mic92/sops-nix?shallow=1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
noctalia = { noctalia = {
url = "github:noctalia-dev/noctalia-shell"; url = "github:noctalia-dev/noctalia-shell?shallow=1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
steam-config-nix = { steam-config-nix = {
url = "github:different-name/steam-config-nix"; url = "github:different-name/steam-config-nix?shallow=1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
home-manager = { home-manager = {
url = "github:nix-community/home-manager"; url = "github:nix-community/home-manager?shallow=1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
prismlauncher = { prismlauncher = {
url = "github:PrismLauncher/PrismLauncher"; url = "github:PrismLauncher/PrismLauncher?shallow=1";
inputs.nixpkgs.follows = "nixpkgs";
};
opencode-flake = {
url = "github:AodhanHayter/opencode-flake";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nix-bwrapper = { nix-bwrapper = {
url = "github:Naxdy/nix-bwrapper"; url = "github:Naxdy/nix-bwrapper?shallow=1";
inputs.nixpkgs.follows = "nixpkgs";
};
opencode-flake = {
url = "github:AodhanHayter/opencode-flake?shallow=1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
lanzaboote = { lanzaboote = {
url = "github:nix-community/lanzaboote"; url = "github:nix-community/lanzaboote?shallow=1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
niri = { niri = {
url = "github:YaLTeR/niri"; url = "github:YaLTeR/niri?shallow=1";
inputs.nixpkgs.follows = "nixpkgs";
};
mcp-nixos = {
url = "github:utensils/mcp-nixos?shallow=1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
impermanence = { impermanence = {
url = "github:nix-community/impermanence"; url = "github:nix-community/impermanence?shallow=1";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
catppuccin.url = "github:catppuccin/nix"; catppuccin.url = "github:catppuccin/nix";
nixvim = {
url = "github:nix-community/nixvim?shallow=1";
inputs.nixpkgs.follows = "nixpkgs";
};
cosmic-manager = {
url = "github:HeitorAugustoLN/cosmic-manager";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
}; };
outputs = outputs =
@ -72,9 +83,9 @@
nixpkgs, nixpkgs,
home-manager, home-manager,
noctalia, noctalia,
nix-flatpak,
lanzaboote, lanzaboote,
niri, niri,
cosmic-manager,
... ...
}@inputs: }@inputs:
{ {
@ -110,9 +121,11 @@
inputs.sops-nix.nixosModules.sops inputs.sops-nix.nixosModules.sops
home-manager.nixosModules.home-manager home-manager.nixosModules.home-manager
inputs.catppuccin.nixosModules.catppuccin inputs.catppuccin.nixosModules.catppuccin
inputs.nixvim.nixosModules.nixvim
{ {
home-manager = { home-manager = {
extraSpecialArgs = { inherit inputs; }; extraSpecialArgs = { inherit inputs; };
sharedModules = [ inputs.cosmic-manager.homeManagerModules.cosmic-manager ];
useGlobalPkgs = true; useGlobalPkgs = true;
useUserPackages = true; useUserPackages = true;
backupFileExtension = "backup"; backupFileExtension = "backup";
@ -132,9 +145,11 @@
inputs.sops-nix.nixosModules.sops inputs.sops-nix.nixosModules.sops
home-manager.nixosModules.home-manager home-manager.nixosModules.home-manager
inputs.catppuccin.nixosModules.catppuccin inputs.catppuccin.nixosModules.catppuccin
inputs.nixvim.nixosModules.nixvim
{ {
home-manager = { home-manager = {
extraSpecialArgs = { inherit inputs; }; extraSpecialArgs = { inherit inputs; };
sharedModules = [ inputs.cosmic-manager.homeManagerModules.cosmic-manager ];
useGlobalPkgs = true; useGlobalPkgs = true;
useUserPackages = true; useUserPackages = true;
backupFileExtension = "backup"; backupFileExtension = "backup";

271
generate.log Normal file
View file

@ -0,0 +1,271 @@
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/confdata.o
HOSTCC scripts/kconfig/expr.o
LEX scripts/kconfig/lexer.lex.c
YACC scripts/kconfig/parser.tab.[ch]
HOSTCC scripts/kconfig/lexer.lex.o
HOSTCC scripts/kconfig/menu.o
HOSTCC scripts/kconfig/parser.tab.o
HOSTCC scripts/kconfig/preprocess.o
HOSTCC scripts/kconfig/symbol.o
HOSTCC scripts/kconfig/util.o
HOSTLD scripts/kconfig/conf
using config: '.config'
razerkbd config not found!!
razermouse config not found!!
vendor_reset config not found!!
razerkraken config not found!!
*
* Restart config...
*
*
* Scheduler features
*
Enable utilization clamping for RT/FAIR tasks (UCLAMP_TASK) [Y/n/?] y
Number of supported utilization clamp buckets (UCLAMP_BUCKETS_COUNT) [5] 5
Proxy Execution (SCHED_PROXY_EXEC) [N/y/?] (NEW)
*
* Binary Emulations
*
IA32 Emulation (IA32_EMULATION) [Y/n/?] y
IA32 emulation disabled by default (IA32_EMULATION_DEFAULT_DISABLED) [N/y/?] n
x32 ABI for 64-bit mode (X86_X32_ABI) [N/y/?] (NEW)
*
* GCC plugins
*
GCC plugins (GCC_PLUGINS) [Y/n/?] (NEW)
Generate some entropy during boot and runtime (GCC_PLUGIN_LATENT_ENTROPY) [N/y/?] (NEW)
*
* PCI GPIO expanders
*
AMD 8111 GPIO driver (GPIO_AMD8111) [N/m/y/?] n
BT8XX GPIO abuser (GPIO_BT8XX) [N/m/y/?] (NEW)
OKI SEMICONDUCTOR ML7213 IOH GPIO support (GPIO_ML_IOH) [N/m/y/?] n
ACCES PCI-IDIO-16 GPIO support (GPIO_PCI_IDIO_16) [N/m/y/?] n
ACCES PCIe-IDIO-24 GPIO support (GPIO_PCIE_IDIO_24) [N/m/y/?] n
RDC R-321x GPIO support (GPIO_RDC321X) [N/m/y/?] n
Intel Sodaville GPIO support (GPIO_SODAVILLE) [N/y/?] n
*
* Voltage and Current Regulator Support
*
Voltage and Current Regulator Support (REGULATOR) [Y/n/?] y
Regulator debug support (REGULATOR_DEBUG) [N/y/?] n
Fixed voltage regulator support (REGULATOR_FIXED_VOLTAGE) [N/m/y/?] n
Virtual regulator consumer support (REGULATOR_VIRTUAL_CONSUMER) [N/m/y/?] n
Userspace regulator consumer support (REGULATOR_USERSPACE_CONSUMER) [N/m/y/?] n
Enable support for receiving regulator events via netlink (REGULATOR_NETLINK_EVENTS) [Y/n/?] y
Marvell 88PG86X voltage regulators (REGULATOR_88PG86X) [N/m/y/?] n
Marvell 88PM8607 Power regulators (REGULATOR_88PM8607) [N/m/y/?] n
Active-semi act8865 voltage regulator (REGULATOR_ACT8865) [N/m/y/?] n
Analog Devices AD5398/AD5821 regulators (REGULATOR_AD5398) [N/m/y/?] n
Analog Devices ADP5055 Triple Buck Regulator (REGULATOR_ADP5055) [N/m/y/?] n
AnalogicTech AAT2870 Regulators (REGULATOR_AAT2870) [N/m/y/?] n
AS3711 PMIC (REGULATOR_AS3711) [N/m/y/?] n
Awinic AW37503 Dual Output Power regulators (REGULATOR_AW37503) [N/m/y/?] n
Dialog Semiconductor DA9030/DA9034 regulators (REGULATOR_DA903X) [N/m/y/?] (NEW)
Dialog Semiconductor DA9052/DA9053 regulators (REGULATOR_DA9052) [N/m/y/?] n
Dialog Semiconductor DA9055 regulators (REGULATOR_DA9055) [N/m/y/?] n
Dialog Semiconductor DA9121/DA9122/DA9220/DA9217/DA9130/DA9131/DA9132 regulator (REGULATOR_DA9121) [N/m/y/?] n
Dialog Semiconductor DA9210 regulator (REGULATOR_DA9210) [N/m/y/?] n
Dialog Semiconductor DA9211/DA9212/DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 regulator (REGULATOR_DA9211) [N/m/y/?] n
Fairchild FAN53555 Regulator (REGULATOR_FAN53555) [N/m/y/?] n
Fairchild FAN53880 Regulator (REGULATOR_FAN53880) [N/m/y/?] n
GPIO regulator support (REGULATOR_GPIO) [N/m/y/?] n
Intersil ISL9305 regulator (REGULATOR_ISL9305) [N/m/y/?] n
Intersil ISL6271A Power regulator (REGULATOR_ISL6271A) [N/m/y/?] n
National Semiconductors LP3971 PMIC regulator driver (REGULATOR_LP3971) [N/m/y/?] n
National Semiconductors LP3972 PMIC regulator driver (REGULATOR_LP3972) [N/m/y/?] n
TI/National Semiconductor LP8720/LP8725 voltage regulators (REGULATOR_LP872X) [N/m/y/?] n
TI LP8755 High Performance PMU driver (REGULATOR_LP8755) [N/m/y/?] n
TI LP8788 Power Regulators (REGULATOR_LP8788) [N/m/y/?] n
LTC3589 8-output voltage regulator (REGULATOR_LTC3589) [N/m/y/?] n
LTC3676 8-output voltage regulator (REGULATOR_LTC3676) [N/m/y/?] n
Maxim 1586/1587 voltage regulator (REGULATOR_MAX1586) [N/m/y/?] n
Analog Devices MAX77503 Regulator (REGULATOR_MAX77503) [N/m/y/?] n
ADI MAX77857/MAX77831 regulator support (REGULATOR_MAX77857) [N/m/y/?] n
Maxim 8649 voltage regulator (REGULATOR_MAX8649) [N/m/y/?] n
Maxim 8660/8661 voltage regulator (REGULATOR_MAX8660) [N/m/y/?] n
Maxim 8893 voltage regulator (REGULATOR_MAX8893) [N/m/y/?] n
Maxim MAX8925 Power Management IC (REGULATOR_MAX8925) [N/m/y/?] n
Maxim MAX8952 Power Management IC (REGULATOR_MAX8952) [N/m/y/?] n
Maxim MAX8973A voltage regulator (REGULATOR_MAX8973) [N/m/y/?] n
Maxim 8997/8966 regulator (REGULATOR_MAX8997) [N/m/y/?] n
Maxim 8998 voltage regulator (REGULATOR_MAX8998) [N/m/y/?] n
Maxim MAX20086-MAX20089 Camera Power Protectors (REGULATOR_MAX20086) [N/m/y/?] n
Maxim MAX20411 High-Efficiency Single Step-Down Converter (REGULATOR_MAX20411) [N/m/y/?] n
Maxim 77693/77843 regulator (REGULATOR_MAX77693) [N/m/y/?] n
Maxim 77826 regulator (REGULATOR_MAX77826) [N/m/y/?] n
Maxim 77838 regulator (REGULATOR_MAX77838) [N/m/y/?] n
Microchip MCP16502 PMIC (REGULATOR_MCP16502) [N/m/y/?] n
Monolithic MP5416 PMIC (REGULATOR_MP5416) [N/m/y/?] n
MPS MP8859 regulator driver (REGULATOR_MP8859) [N/m/y/?] n
MPS MP8869 regulator driver (REGULATOR_MP886X) [N/m/y/?] n
Monolithic MPQ7920 PMIC (REGULATOR_MPQ7920) [N/m/y/?] n
MediaTek MT6311 PMIC (REGULATOR_MT6311) [N/m/y/?] n
NXP PCA9450A/PCA9450B/PCA9450C regulator driver (REGULATOR_PCA9450) [N/m/y/?] n
NXP PF9453 regulator driver (REGULATOR_PF9453) [N/m/y/?] n
Motorola PCAP2 regulator driver (REGULATOR_PCAP) [N/m/y/?] n
NXP PF0900/PF0901/PF09XX regulator driver (REGULATOR_PF0900) [N/m/y/?] n
NXP PF5300/PF5301/PF5302 regulator driver (REGULATOR_PF530X) [N/m/y/?] n
NXP PF8100/PF8121A/PF8200 regulator driver (REGULATOR_PF8X00) [N/m/y/?] n
Freescale PFUZE100/200/3000/3001 regulator driver (REGULATOR_PFUZE100) [N/m/y/?] n
Powerventure Semiconductor PV88060 regulator (REGULATOR_PV88060) [N/m/y/?] n
Powerventure Semiconductor PV88080 regulator (REGULATOR_PV88080) [N/m/y/?] n
Powerventure Semiconductor PV88090 regulator (REGULATOR_PV88090) [N/m/y/?] n
PWM voltage regulator (REGULATOR_PWM) [N/m/y/?] n
Renesas RAA215300 driver (REGULATOR_RAA215300) [N/m/y/?] n
Raspberry Pi 7-inch touchscreen panel ATTINY regulator (REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY) [N/m/y/?] n
Raspberry Pi 7-inch touchscreen panel V2 regulator (REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2) [N/m/y/?] n
RICOH RC5T583 Power regulators (REGULATOR_RC5T583) [N/m/y/?] n
Richtek RT4801 Regulators (REGULATOR_RT4801) [N/m/y/?] n
Richtek RT4803 boost regulator (REGULATOR_RT4803) [N/m/y/?] n
Richtek RT5133 PMIC Regulators (REGULATOR_RT5133) [N/m/y/?] n
Richtek RT5190A PMIC (REGULATOR_RT5190A) [N/m/y/?] n
Richtek RT5739 Regulator (REGULATOR_RT5739) [N/m/y/?] n
Richtek RT5759 Regulator (REGULATOR_RT5759) [N/m/y/?] n
Richtek RT6160 BuckBoost voltage regulator (REGULATOR_RT6160) [N/m/y/?] n
Richtek RT6190 4-Switch BuckBoost controller (REGULATOR_RT6190) [N/m/y/?] n
Richtek RT6245 voltage regulator (REGULATOR_RT6245) [N/m/y/?] n
Richtek RTQ2134 SubPMIC Regulator (REGULATOR_RTQ2134) [N/m/y/?] n
Richtek RTMV20 Laser Diode Regulator (REGULATOR_RTMV20) [N/m/y/?] n
Richtek RTQ6752 TFT LCD voltage regulator (REGULATOR_RTQ6752) [N/m/y/?] n
Richtek RTQ2208 SubPMIC Regulator (REGULATOR_RTQ2208) [N/m/y/?] n
Dialog Semiconductor SLG51000 regulators (REGULATOR_SLG51000) [N/m/y/?] n
Silergy SY8106A regulator (REGULATOR_SY8106A) [N/m/y/?] n
Silergy SY8824C/SY8824E regulator (REGULATOR_SY8824X) [N/m/y/?] n
Silergy SY8827N regulator (REGULATOR_SY8827N) [N/m/y/?] n
TI TPS51632 Power Regulator (REGULATOR_TPS51632) [N/m/y/?] n
TI TPS6236x Power Regulator (REGULATOR_TPS62360) [N/m/y/?] n
TI TPS6286x Power Regulator (REGULATOR_TPS6286X) [N/m/y/?] n
TI TPS6287x Power Regulator (REGULATOR_TPS6287X) [N/m/y/?] n
TI TPS65023 Power regulators (REGULATOR_TPS65023) [N/m/y/?] n
TI TPS6507X Power regulators (REGULATOR_TPS6507X) [N/m/y/?] n
TI TPS65090 Power regulator (REGULATOR_TPS65090) [N/m/y/?] n
TI TPS65132 Dual Output Power regulators (REGULATOR_TPS65132) [N/m/y/?] n
TI TPS6524X Power regulators (REGULATOR_TPS6524X) [N/m/y/?] n
TI TPS6586X Power regulators (REGULATOR_TPS6586X) [N/m/y/?] n
TI TPS65910/TPS65911 Power Regulators (REGULATOR_TPS65910) [N/m/y/?] n
TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC (REGULATOR_TWL4030) [N/m/y/?] n
Voltage controlled regulators (REGULATOR_VCTRL) [N/m/y/?] n
Wolfson Microelectronics WM831x PMIC regulators (REGULATOR_WM831X) [N/m/y/?] n
Wolfson Microelectronics WM8350 AudioPlus PMIC (REGULATOR_WM8350) [N/m/y/?] n
Wolfson Microelectronics WM8400 AudioPlus PMIC (REGULATOR_WM8400) [N/m/y/?] n
*
* Video encoders
*
Analog Devices ADV7170 video encoder (VIDEO_ADV7170) [N/m/?] n
Analog Devices ADV7175 video encoder (VIDEO_ADV7175) [N/m/?] n
ADV7343 video encoder (VIDEO_ADV7343) [N/m/?] n
ADV7393 video encoder (VIDEO_ADV7393) [N/m/?] n
Analog Devices ADV7511 encoder (VIDEO_ADV7511) [N/m/?] (NEW)
AK8813/AK8814 video encoders (VIDEO_AK881X) [N/m/?] n
Philips SAA7127/9 digital video encoders (VIDEO_SAA7127) [N/m/?] n
Philips SAA7185 video encoder (VIDEO_SAA7185) [N/m/?] n
Texas Instruments THS8200 video encoder (VIDEO_THS8200) [N/m/?] n
*
* PCI sound devices
*
PCI sound devices (SND_PCI) [Y/n/?] y
Analog Devices AD1889 (SND_AD1889) [N/m/?] n
Avance Logic ALS300/ALS300+ (SND_ALS300) [N/m/?] n
Avance Logic ALS4000 (SND_ALS4000) [N/m/?] n
ALi M5451 PCI Audio Controller (SND_ALI5451) [N/m/?] n
AudioScience ASIxxxx (SND_ASIHPI) [N/m/?] n
ATI IXP AC97 Controller (SND_ATIIXP) [N/m/?] n
ATI IXP Modem (SND_ATIIXP_MODEM) [N/m/?] n
Aureal Advantage (SND_AU8810) [N/m/?] n
Aureal Vortex (SND_AU8820) [N/m/?] n
Aureal Vortex 2 (SND_AU8830) [N/m/?] n
Emagic Audiowerk 2 (SND_AW2) [N/m/?] n
Aztech AZF3328 / PCI168 (SND_AZT3328) [N/m/?] n
Bt87x Audio Capture (SND_BT87X) [N/m/?] n
SB Audigy LS / Live 24bit (SND_CA0106) [N/m/?] n
C-Media 8338, 8738, 8768, 8770 (SND_CMIPCI) [N/m/?] n
C-Media 8786, 8787, 8788 (Oxygen) (SND_OXYGEN) [N/m/?] n
Cirrus Logic (Sound Fusion) CS4281 (SND_CS4281) [N/m/?] n
Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x (SND_CS46XX) [N/m/?] n
Creative Sound Blaster X-Fi (SND_CTXFI) [N/m/?] n
(Echoaudio) Darla20 (SND_DARLA20) [N/m/?] n
(Echoaudio) Gina20 (SND_GINA20) [N/m/?] n
(Echoaudio) Layla20 (SND_LAYLA20) [N/m/?] n
(Echoaudio) Darla24 (SND_DARLA24) [N/m/?] n
(Echoaudio) Gina24 (SND_GINA24) [N/m/?] n
(Echoaudio) Layla24 (SND_LAYLA24) [N/m/?] n
(Echoaudio) Mona (SND_MONA) [N/m/?] n
(Echoaudio) Mia (SND_MIA) [N/m/?] n
(Echoaudio) 3G cards (SND_ECHO3G) [N/m/?] n
(Echoaudio) Indigo (SND_INDIGO) [N/m/?] n
(Echoaudio) Indigo IO (SND_INDIGOIO) [N/m/?] n
(Echoaudio) Indigo DJ (SND_INDIGODJ) [N/m/?] n
(Echoaudio) Indigo IOx (SND_INDIGOIOX) [N/m/?] n
(Echoaudio) Indigo DJx (SND_INDIGODJX) [N/m/?] n
Emu10k1 (SB Live!, Audigy, E-MU APS/0404/1010/1212/1616/1820) (SND_EMU10K1) [N/m/?] n
Emu10k1X (Dell OEM Version) (SND_EMU10K1X) [N/m/?] n
(Creative) Ensoniq AudioPCI 1370 (SND_ENS1370) [N/m/?] n
(Creative) Ensoniq AudioPCI 1371/1373 (SND_ENS1371) [N/m/?] n
ESS ES1938/1946/1969 (Solo-1) (SND_ES1938) [N/m/?] n
ESS ES1968/1978 (Maestro-1/2/2E) (SND_ES1968) [N/m/?] n
ForteMedia FM801 (SND_FM801) [N/m/?] n
RME Hammerfall DSP Audio (SND_HDSP) [N/m/?] n
RME Hammerfall DSP MADI/RayDAT/AIO (SND_HDSPM) [N/m/?] n
ICEnsemble ICE1712 (Envy24) (SND_ICE1712) [N/m/?] n
ICE/VT1724/1720 (Envy24HT/PT) (SND_ICE1724) [N/m/?] n
Intel/SiS/nVidia/AMD/ALi AC97 Controller (SND_INTEL8X0) [N/m/?] n
Intel/SiS/nVidia/AMD MC97 Modem (SND_INTEL8X0M) [N/m/?] n
Korg 1212 IO (SND_KORG1212) [N/m/?] n
Digigram Lola (SND_LOLA) [N/m/?] n
Digigram LX6464ES (SND_LX6464ES) [N/m/?] n
ESS Allegro/Maestro3 (SND_MAESTRO3) [N/m/?] n
Digigram miXart (SND_MIXART) [N/m/?] n
NeoMagic NM256AV/ZX (SND_NM256) [N/m/?] n
Digigram PCXHR (SND_PCXHR) [N/m/?] n
Conexant Riptide (SND_RIPTIDE) [N/m/?] n
RME Digi32, 32/8, 32 PRO (SND_RME32) [N/m/?] n
RME Digi96, 96/8, 96/8 PRO (SND_RME96) [N/m/?] n
RME Digi9652 (Hammerfall) (SND_RME9652) [N/m/?] n
Studio Evolution SE6X (SND_SE6X) [N/m/?] (NEW)
S3 SonicVibes (SND_SONICVIBES) [N/m/?] n
Trident 4D-Wave DX/NX; SiS 7018 (SND_TRIDENT) [N/m/?] n
VIA 82C686A/B, 8233/8235 AC97 Controller (SND_VIA82XX) [N/m/?] n
VIA 82C686A/B, 8233 based Modems (SND_VIA82XX_MODEM) [N/m/?] n
Asus Virtuoso 66/100/200 (Xonar) (SND_VIRTUOSO) [N/m/?] n
Digigram VX222 (SND_VX222) [N/m/?] n
Yamaha YMF724/740/744/754 (SND_YMFPCI) [N/m/?] n
*
* Kernel hardening options
*
Randomize layout of sensitive kernel structures
> 1. Disable structure layout randomization (RANDSTRUCT_NONE)
2. Fully randomize structure layout (RANDSTRUCT_FULL)
3. Limit randomization of structure layout to cache-lines (RANDSTRUCT_PERFORMANCE) (NEW)
choice[1-3?]:
*
* Compile-time checks and compiler options
*
Debug information
1. Disable debug information (DEBUG_INFO_NONE)
> 2. Rely on the toolchain's implicit default DWARF version (DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT)
3. Generate DWARF Version 4 debuginfo (DEBUG_INFO_DWARF4)
4. Generate DWARF Version 5 debuginfo (DEBUG_INFO_DWARF5)
choice[1-4?]: 2
Reduce debugging information (DEBUG_INFO_REDUCED) [N/y/?] n
Compressed Debug information
> 1. Don't compress debug information (DEBUG_INFO_COMPRESSED_NONE)
2. Compress debugging information with zlib (DEBUG_INFO_COMPRESSED_ZLIB)
choice[1-2?]: 1
Produce split debuginfo in .dwo files (DEBUG_INFO_SPLIT) [N/y/?] n
Provide GDB scripts for kernel debugging (GDB_SCRIPTS) [Y/n/?] y
Warn for stack frames larger than (FRAME_WARN) [2048] 2048
Strip assembler-generated symbols during link (STRIP_ASM_SYMS) [Y/n/?] y
Generate readable assembler code (READABLE_ASM) [N/y/?] (NEW)
Install uapi headers to usr/include (HEADERS_INSTALL) [N/y/?] n
Enable full Section mismatch analysis (DEBUG_SECTION_MISMATCH) [N/y/?] (NEW)
Make section mismatch errors non-fatal (SECTION_MISMATCH_WARN_ONLY) [Y/n/?] y
Force all function address 64B aligned (DEBUG_FORCE_FUNCTION_ALIGN_64B) [N/y/?] n
Upgrade objtool warnings to errors (OBJTOOL_WERROR) [N/y/?] n
Generate vmlinux.map file when linking (VMLINUX_MAP) [N/y/?] n
Force weak per-cpu definitions (DEBUG_FORCE_WEAK_PER_CPU) [N/y/?] n
#
# configuration written to .config
#

View file

@ -24,13 +24,10 @@
boot.kernelModules = [ "kvm-amd" ]; boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
# Unlock the encrypted root early in initrd (stable: UUID of the LUKS container)
boot.initrd.luks.devices.cryptroot = { boot.initrd.luks.devices.cryptroot = {
device = "/dev/disk/by-uuid/362284b1-a1ab-4ad0-b87b-eba30eaa258d"; device = "/dev/disk/by-uuid/362284b1-a1ab-4ad0-b87b-eba30eaa258d";
# allowDiscards = true; # uncomment if you use SSD discard/TRIM through LUKS
}; };
# EFI System Partition
fileSystems."/boot" = { fileSystems."/boot" = {
device = "/dev/disk/by-uuid/042E-DA9E"; device = "/dev/disk/by-uuid/042E-DA9E";
fsType = "vfat"; fsType = "vfat";
@ -50,6 +47,26 @@
]; ];
}; };
fileSystems."/data" = {
device = "/dev/mapper/cryptdata";
fsType = "btrfs";
options = [
"subvol=@media"
"compress-force=zstd"
"noatime"
];
};
fileSystems."/games/steam" = {
device = "/dev/mapper/cryptdata";
fsType = "btrfs";
options = [
"subvol=@steam"
"compress-force=zstd"
"noatime"
];
};
# Impermanence layout: persistent subvolumes that must be mounted in initrd # Impermanence layout: persistent subvolumes that must be mounted in initrd
fileSystems."/nix" = { fileSystems."/nix" = {
device = lib.mkForce "/dev/mapper/cryptroot"; device = lib.mkForce "/dev/mapper/cryptroot";
@ -75,11 +92,6 @@
neededForBoot = true; neededForBoot = true;
}; };
# NOTE:
# We intentionally do NOT define fileSystems."/" here because your setup appears to
# use impermanence (root is typically tmpfs). If you *do* have a persistent root
# subvolume, define it in your main config instead.
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
@ -87,6 +99,6 @@
boot.swraid = { boot.swraid = {
enable = true; enable = true;
mdadmConf = "PROGRAM ${pkgs.coreutils}/bin/true"; # Silences mdmon warning mdadmConf = "PROGRAM ${pkgs.coreutils}/bin/true";
}; };
} }

View file

@ -6,9 +6,12 @@
}: }:
{ {
imports = [ imports = [
./modules/home/gluetun-user.nix
./modules/home/cosmic.nix
inputs.sops-nix.homeManagerModules.sops inputs.sops-nix.homeManagerModules.sops
inputs.steam-config-nix.homeModules.default inputs.steam-config-nix.homeModules.default
inputs.catppuccin.homeManagerModules.catppuccin inputs.catppuccin.homeManagerModules.catppuccin
inputs.nixvim.homeManagerModules.nixvim
# inputs.unified-router-mcp.homeManagerModules.default # inputs.unified-router-mcp.homeManagerModules.default
./modules/home # Import all Home Manager modules ./modules/home # Import all Home Manager modules
./hosts/nixos/home-modules.nix # Host-specific module configuration ./hosts/nixos/home-modules.nix # Host-specific module configuration
@ -22,6 +25,9 @@
home.packages = [ home.packages = [
pkgs.mimalloc pkgs.mimalloc
pkgs.jellyfin-media-player
pkgs.bemoji
pkgs.wtype
(pkgs.writeShellScriptBin "opencode" '' (pkgs.writeShellScriptBin "opencode" ''
export OPENAI_BASE_URL="https://api.ashisgreat.xyz/v1" export OPENAI_BASE_URL="https://api.ashisgreat.xyz/v1"
export OPENAI_API_KEY="$(cat ${config.sops.secrets.master_api_key.path})" export OPENAI_API_KEY="$(cat ${config.sops.secrets.master_api_key.path})"
@ -170,6 +176,19 @@
}; };
}; };
xdg.desktopEntries.youtube = {
name = "YouTube";
genericName = "Video Player";
exec = "brave --app=https://youtube.com";
terminal = false;
categories = [
"Network"
"Video"
"AudioVideo"
];
icon = "youtube";
};
xdg.mimeApps = { xdg.mimeApps = {
enable = true; enable = true;
defaultApplications = { defaultApplications = {
@ -191,4 +210,17 @@
"application/pdf" = [ "nix.bwrapper.firefox.desktop" ]; "application/pdf" = [ "nix.bwrapper.firefox.desktop" ];
}; };
}; };
systemd.user.services.ydotoold = {
Unit = {
Description = "ydotool daemon";
};
Service = {
ExecStart = "${pkgs.ydotool}/bin/ydotoold --socket-path %t/ydotoold.sock";
Restart = "on-failure";
};
Install = {
WantedBy = [ "default.target" ];
};
};
} }

View file

@ -1,4 +1,9 @@
{ config, pkgs, ... }: {
config,
pkgs,
inputs,
...
}:
let let
# Wrap Antigravity in an FHS environment to support dynamically linked binaries # Wrap Antigravity in an FHS environment to support dynamically linked binaries
@ -195,6 +200,9 @@ in
DEFAULT_PORT = "9090"; DEFAULT_PORT = "9090";
}; };
}; };
# "nixos" = {
# command = "${inputs.mcp-nixos.packages.${pkgs.system}.default}/bin/mcp-nixos";
# };
}; };
}; };
}; };
@ -224,6 +232,9 @@ in
DEFAULT_PORT = "9090"; DEFAULT_PORT = "9090";
}; };
}; };
# nixos = {
# command = "${inputs.mcp-nixos.packages.${pkgs.system}.default}/bin/mcp-nixos";
# };
}; };
}; };
}; };

View file

@ -29,6 +29,11 @@
zramAlgorithm = "zstd"; zramAlgorithm = "zstd";
}; };
# Hardened Malloc (Scudo)
hardenedMalloc = {
enable = false;
};
# Secure Boot (Lanzaboote) # Secure Boot (Lanzaboote)
# 1. sudo sbctl create-keys # 1. sudo sbctl create-keys
# 2. sudo sbctl enroll-keys -m # 2. sudo sbctl enroll-keys -m
@ -47,8 +52,9 @@
# Cloudflare-only firewall rules # Cloudflare-only firewall rules
cloudflareFirewall = { cloudflareFirewall = {
enable = false; enable = true;
enablePodmanWorkaround = false; allowLocalTraffic = true;
enablePodmanWorkaround = true;
restrictedPorts = [ restrictedPorts = [
80 80
443 443
@ -80,5 +86,12 @@
openWebUI = { openWebUI = {
enable = true; enable = true;
}; };
# SearXNG (Meta-Search Engine)
searxng = {
enable = true;
port = 8888;
domain = "search.ashisgreat.xyz";
};
}; };
} }

View file

@ -38,15 +38,15 @@
# Gluetun VPN user service # Gluetun VPN user service
gluetunUser = { gluetunUser = {
enable = true; enable = false;
environmentFile = "/run/secrets/rendered/gluetun.env"; environmentFile = "/run/secrets/rendered/gluetun.env";
}; };
# qBittorrent through VPN # qBittorrent through VPN
qbittorrentVpn = { qbittorrentVpn = {
enable = true; enable = false;
configDir = "/home/ashie/qbittorrent/config"; configDir = "/home/ashie/qbittorrent/config";
downloadsDir = "/home/ashie/qbittorrent/downloads"; downloadsDir = "/home/ashie/Media/Torrents";
}; };
# Auto-update browser containers # Auto-update browser containers
@ -60,6 +60,11 @@
arch = "x86_64_v3"; arch = "x86_64_v3";
}; };
# PrismLauncher Sandboxed
prismlauncher = {
enable = true;
};
# Unified API Router # Unified API Router
# unifiedRouter = { # unifiedRouter = {
# enable = true; # enable = true;
@ -68,7 +73,7 @@
# SillyTavern Frontend # SillyTavern Frontend
sillytavern = { sillytavern = {
enable = true; enable = false;
}; };
# Noctalia Shell # Noctalia Shell

View file

@ -41,7 +41,9 @@ in
Service = { Service = {
ExecStartPre = pkgs.writeShellScript "antigravity2api-init" '' ExecStartPre = pkgs.writeShellScript "antigravity2api-init" ''
cat > ${workDir}/.env <<EOF export PATH="${pkgs.coreutils}/bin:$PATH"
mkdir -p "${workDir}"
cat > "${workDir}/.env" <<EOF
API_KEY=${cfg.credentials.apiKey} API_KEY=${cfg.credentials.apiKey}
ADMIN_USERNAME=${cfg.credentials.username} ADMIN_USERNAME=${cfg.credentials.username}
ADMIN_PASSWORD=${cfg.credentials.password} ADMIN_PASSWORD=${cfg.credentials.password}

12
modules/home/cosmic.nix Normal file
View file

@ -0,0 +1,12 @@
{
# programs.cosmic-manager.enable = true; # Deprecated
# Add cosmic-manager configurations here
# Example:
# programs.cosmic-edit.enable = true;
xdg.configFile."cosmic/com.system76.CosmicComp/v1/input_default".text = ''
(
acceleration_profile: Flat,
)
'';
}

View file

@ -15,6 +15,7 @@
./browser-container-update.nix ./browser-container-update.nix
./proton-cachyos-updater.nix ./proton-cachyos-updater.nix
./cli-tools.nix ./cli-tools.nix
./nixvim.nix
# ./unified-router.nix # ./unified-router.nix
./sillytavern.nix ./sillytavern.nix
@ -24,5 +25,6 @@
./polling-rate.nix ./polling-rate.nix
./antigravity2api.nix ./antigravity2api.nix
./theme.nix ./theme.nix
./prismlauncher.nix
]; ];
} }

View file

@ -232,7 +232,8 @@ in
Mod+Minus { set-column-width "-10%"; } Mod+Minus { set-column-width "-10%"; }
Mod+Equal { set-column-width "+10%"; } Mod+Equal { set-column-width "+10%"; }
Mod+Shift+E { quit; } Mod+Shift+E { spawn "bemoji" "-t"; }
Print { spawn "sh" "-c" "grim -g \"$(slurp)\" - | wl-copy"; } Print { spawn "sh" "-c" "grim -g \"$(slurp)\" - | wl-copy"; }
// Browsers // Browsers

149
modules/home/nixvim.nix Normal file
View file

@ -0,0 +1,149 @@
{ pkgs, ... }:
{
programs.nixvim = {
enable = true;
defaultEditor = true;
colorschemes.catppuccin = {
enable = true;
settings = {
flavour = "mocha";
term_colors = true;
};
};
globals = {
mapleader = " ";
maplocalleader = "\\";
};
opts = {
number = true;
relativenumber = true;
# Tabs
tabstop = 2;
softtabstop = 2;
shiftwidth = 2;
expandtab = true;
smartindent = true;
# Search
ignorecase = true;
smartcase = true;
# UI
cursorline = true;
termguicolors = true;
scrolloff = 8;
# System
mouse = "a";
clipboard = "unnamedplus";
undofile = true;
};
plugins = {
lualine.enable = true;
bufferline.enable = true;
web-devicons.enable = true;
which-key.enable = true;
# Treesitter
treesitter = {
enable = true;
settings = {
highlight.enable = true;
indent.enable = true;
};
};
# File Explorer
neo-tree = {
enable = true;
closeIfLastWindow = true;
};
# Fuzzy Finder
telescope = {
enable = true;
keymaps = {
"<leader>ff" = "find_files";
"<leader>fg" = "live_grep";
"<leader>fb" = "buffers";
"<leader>fh" = "help_tags";
};
};
# LSP & Completion
lsp = {
enable = true;
servers = {
nixd.enable = true; # Nix
lua_ls.enable = true; # Lua
pyright.enable = true; # Python
bashls.enable = true; # Bash
html.enable = true; # HTML
cssls.enable = true; # CSS
ts_ls.enable = true; # TS/JS
};
};
cmp = {
enable = true;
autoEnableSources = true;
settings = {
sources = [
{ name = "nvim_lsp"; }
{ name = "path"; }
{ name = "buffer"; }
];
mapping = {
"<C-Space>" = "cmp.mapping.complete()";
"<CR>" = "cmp.mapping.confirm({ select = true })";
"<Tab>" = "cmp.mapping.select_next_item()";
"<S-Tab>" = "cmp.mapping.select_prev_item()";
};
};
};
cmp-nvim-lsp.enable = true;
cmp-path.enable = true;
cmp-buffer.enable = true;
# UI Improvements
notify = {
enable = true;
settings.background_colour = "#000000";
};
noice = {
enable = true;
settings = {
notify.enabled = true;
presets = {
bottom_search = true;
command_palette = true;
long_message_to_split = true;
inc_rename = false;
lsp_doc_border = false;
};
};
};
};
keymaps = [
{
mode = "n";
key = "<leader>e";
action = "<cmd>Neotree toggle<cr>";
options.desc = "Toggle Explorer";
}
{
mode = "n";
key = "<C-s>";
action = "<cmd>w<cr>";
options.desc = "Save File";
}
];
};
}

View file

@ -9,66 +9,83 @@ let
cfg = config.services.polling-rate-switcher; cfg = config.services.polling-rate-switcher;
switcherScript = pkgs.writeShellScriptBin "polling-rate-switcher" '' switcherScript = pkgs.writeShellScriptBin "polling-rate-switcher" ''
# Find Razer Viper V3 Pro sysfs path export PATH="${
# Look for a device that supports poll_rate lib.makeBinPath [
MOUSE_PATH="" pkgs.coreutils
pkgs.gnugrep
pkgs.jq
pkgs.systemd
pkgs.niri
pkgs.gawk
]
}:$PATH"
find_mouse() { # Find the Razer device object path via D-Bus
for dev in /sys/bus/hid/drivers/razermouse/*; do # We look for an object path that looks like /org/razer/device/...
if [ -f "$dev/device_type" ] && [ -f "$dev/poll_rate" ]; then # AND supports setPollRate
TYPE=$(cat "$dev/device_type") echo "Searching for OpenRazer device on D-Bus..."
# Check if it looks like a mouse "Razer Viper V3 Pro" usually has unique ID/Type
# For now, we take the first Razer device that supports polling rate RAZER_OBJ=""
# Or specifically filter if we knew exact string.
# The user said "Active window... polling rate of my razer viper v3 pro" # Simple retry loop in case the service starts before the device is ready
# We'll assume it's the main device found. for i in {1..10}; do
MOUSE_PATH="$dev" # Find matches, then check introspection for setPollRate method
echo "Found Razer device at $MOUSE_PATH ($TYPE)" CANDIDATES=$(busctl --user tree --list org.razer | grep '^/org/razer/device/') || true
break
for obj in $CANDIDATES; do
if busctl --user introspect org.razer "$obj" 2>/dev/null | grep -q "setPollRate"; then
RAZER_OBJ="$obj"
break
fi
done
if [ -n "$RAZER_OBJ" ]; then
break
fi fi
done sleep 2
} done
find_mouse if [ -z "$RAZER_OBJ" ]; then
echo "No Razer device found on D-Bus org.razer that supports setPollRate after retries."
if [ -z "$MOUSE_PATH" ]; then
echo "No Razer mouse found with poll_rate capability."
exit 1 exit 1
fi fi
echo "Starting Polling Rate Switcher for $MOUSE_PATH" echo "Found Razer device at $RAZER_OBJ"
CURRENT_MODE="unknown" # Function to set polling rate via D-Bus
set_rate() {
update_rate() { local rate="$1"
TARGET=$1 # Call OpenRazer method: setPollRate(int)
# Read current to avoid redundant writes busctl --user call org.razer "$RAZER_OBJ" razer.device.misc setPollRate i "$rate"
CURRENT=$(cat "$MOUSE_PATH/poll_rate")
if [ "$CURRENT" != "$TARGET" ]; then
echo "Switching polling rate to $TARGET Hz"
echo "$TARGET" > "$MOUSE_PATH/poll_rate"
fi
} }
while true; do current_rate=""
# Get active window info from Niri
# Niri msg active-window returns JSON # Listen to Niri event stream
WINDOW_INFO=$(${pkgs.niri}/bin/niri msg -j focused-window 2>/dev/null) # We filter for WindowFocusChanged events, then query the state.
# This avoids parsing the complex event stream directly for state.
niri msg --json event-stream | jq --unbuffered -c 'select(.WindowFocusChanged) | .WindowFocusChanged.id' | while read -r _; do
# Query current focused window
# The focused-window output is wrapped in Ok.FocusedWindow
fw=$(niri msg --json focused-window 2>/dev/null || true)
if [ -n "$WINDOW_INFO" ]; then # If no window is focused or command fails, these will be empty
APP_ID=$(echo "$WINDOW_INFO" | ${pkgs.jq}/bin/jq -r '.app_id // ""' | tr '[:upper:]' '[:lower:]') app_id=$(echo "$fw" | jq -r '.Ok.FocusedWindow.app_id // ""' | tr '[:upper:]' '[:lower:]')
TITLE=$(echo "$WINDOW_INFO" | ${pkgs.jq}/bin/jq -r '.title // ""' | tr '[:upper:]' '[:lower:]') title=$(echo "$fw" | jq -r '.Ok.FocusedWindow.title // ""' | tr '[:upper:]' '[:lower:]')
# Check for Overwatch # Default rate
if [[ "$APP_ID" == *"overwatch"* ]] || [[ "$TITLE" == *"overwatch"* ]]; then target_rate=1000
update_rate 8000
else # High polling rate for specific games
update_rate 1000 if [[ "$app_id" == *"overwatch"* || "$title" == *"overwatch"* ]]; then
fi target_rate=8000
fi
if [ "$target_rate" != "$current_rate" ]; then
echo "Switching rate to $target_rate Hz (App: $app_id, Title: $title)"
set_rate "$target_rate"
current_rate="$target_rate"
fi fi
sleep 2
done done
''; '';
in in

View file

@ -0,0 +1,287 @@
{
config,
lib,
pkgs,
inputs,
...
}:
let
cfg = config.myModules.prismlauncher;
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
# Libraries required by Minecraft natives (LWJGL), various mods,
# and the Microsoft authentication flow (NSS/NSPR).
runtimeLibs = with pkgs; [
glib
libgbm
libglvnd
nspr
nss
alsa-lib
libpulseaudio
udev
cups
mesa
expat
libdrm
libxkbcommon
dbus
xorg.libXcomposite
xorg.libXdamage
xorg.libXext
xorg.libXfixes
xorg.libXrandr
xorg.libxcb
libxml2
xorg.libXScrnSaver
glfw
];
defaultJvmArgs = "-XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+UseNUMA -XX:NmethodSweepActivity=1 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:-DontCompileHugeMethods -XX:MaxNodeLimit=240000 -XX:NodeLimitFudgeFactor=8000 -XX:+UseVectorCmov -XX:+PerfDisableSharedMem -XX:+UseFastUnorderedTimeStamps -XX:+UseCriticalJavaThreadPriority -XX:ThreadPriorityPolicy=1 -XX:AllocatePrefetchStyle=3 -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000 -XX:AllocatePrefetchStyle=1 -XX:ConcGCThreads=4";
in
{
options.myModules.prismlauncher = {
enable = lib.mkEnableOption "PrismLauncher Sandboxed";
jvmArgs = lib.mkOption {
type = lib.types.str;
default = defaultJvmArgs;
description = "JVM arguments to enforce in prismlauncher.cfg";
};
uid = lib.mkOption {
type = lib.types.int;
default = 1000;
description = "User ID for /run/user bind mount";
};
glfwPackage = lib.mkOption {
type = lib.types.package;
default = pkgs.glfw;
description = "The GLFW package to use for the custom GLFW path.";
};
};
config = lib.mkIf cfg.enable {
home.packages = [
(bwrapperPkgs.mkBwrapper {
app = {
id = "org.prismlauncher.PrismLauncher";
package = pkgs.prismlauncher.overrideAttrs (old: {
pname = "prismlauncher";
version = old.version or "9.1"; # Fallback or keep current if valid
buildInputs = (old.buildInputs or [ ]);
# Keep runtimeLibs in closure without injecting them into environment
postInstall = (old.postInstall or "") + ''
mkdir -p $out/share/prismlauncher-sandboxed
echo "${lib.makeLibraryPath runtimeLibs}" > $out/share/prismlauncher-sandboxed/libs
'';
qtWrapperArgs = (old.qtWrapperArgs or [ ]);
});
env = {
# Propagate XDG_DATA_DIRS so themes/icons can be found
BROWSER = "firefox";
QT_QPA_PLATFORM = "xcb";
GDK_BACKEND = "x11";
NO_AT_BRIDGE = "1";
QT_QPA_PLATFORMTHEME = "";
QT_STYLE_OVERRIDE = "fusion";
# Sanitize Desktop Environment to prevent loading conflicting platform themes
XDG_CURRENT_DESKTOP = "X-Generic";
XDG_SESSION_TYPE = "x11";
GTK_USE_PORTAL = "0";
GTK_THEME = "Adwaita"; # Force a safe theme or empty?
# Unset potential conflict variables
GTK_MODULES = "";
GTK3_MODULES = "";
};
};
sockets.x11 = true;
sockets.wayland = true;
flatpak.enable = false;
fhsenv.opts = {
unshareUser = true;
unshareUts = false;
unshareCgroup = false;
unsharePid = false;
unshareNet = false;
unshareIpc = false;
};
fhsenv.bwrap.baseArgs = lib.mkForce [
"--new-session"
"--proc /proc"
"--dev /dev"
"--dev-bind /dev/dri /dev/dri"
"--tmpfs /home"
"--tmpfs /tmp"
"--tmpfs /run"
"--dir /run/user"
"--dir /run/user/${toString cfg.uid}"
# Bind ro system paths commonly needed
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
"--dir /run/systemd/resolve"
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
"--ro-bind /run/dbus /run/dbus"
];
mounts = {
read = [
"$HOME/.config/fontconfig"
"$HOME/.local/share/fonts"
"$HOME/.icons"
"$HOME/.themes"
"$HOME/.local/share/themes"
"$HOME/.config/qt6ct"
"$HOME/.config/Kvantum"
"$HOME/.config/MangoHud"
"$HOME/Downloads"
];
readWrite = [
"$HOME/.local/share/PrismLauncher"
"$HOME/.cache/PrismLauncher"
];
};
dbus.enable = false;
script.preCmds.stage2 =
let
glfwPath = "${cfg.glfwPackage}/lib/libglfw.so.3";
# We need to access the sandbox-utils.nix. Since it's in system modules,
# we can't easily import it relative to here if it's not exported.
# But the content was small, let's inline what we need or check if we can source it.
# For now, I'll assume the dbus-proxy logic is needed.
# Reimplementing mkDbusProxyScript from sandbox-utils.nix inline to avoid path dependency
mkDbusProxyScript =
{ appId, proxyArgs }:
let
proxyArgsStr = lib.escapeShellArgs proxyArgs;
appDir = "$XDG_RUNTIME_DIR/app/${appId}";
proxySocket = "${appDir}/bus";
in
''
mkdir -p "${appDir}"
# Start xdg-dbus-proxy
${pkgs.xdg-dbus-proxy}/bin/xdg-dbus-proxy \
"$DBUS_SESSION_BUS_ADDRESS" "${proxySocket}" \
${proxyArgsStr} &
DBUS_PROXY_PID=$!
# Kill proxy on exit
trap "kill $DBUS_PROXY_PID" EXIT
# Wait for socket to be created
for i in {1..50}; do
if [ -S "${proxySocket}" ]; then
break
fi
if ! kill -0 $DBUS_PROXY_PID 2>/dev/null; then
echo "xdg-dbus-proxy died unexpectedly"
exit 1
fi
sleep 0.1
done
'';
dbusScript = mkDbusProxyScript {
appId = "org.prismlauncher.PrismLauncher";
proxyArgs = [
"--filter"
"--talk=org.freedesktop.portal.*"
"--call=org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"
"--talk=org.freedesktop.Notifications"
"--own=org.prismlauncher.PrismLauncher"
"--own=org.prismlauncher.PrismLauncher.*"
];
};
in
''
${dbusScript}
# Sanitize Environment
unset QT_QPA_PLATFORMTHEME
unset GTK_THEME
unset XDG_CURRENT_DESKTOP
export QT_QPA_PLATFORM=xcb
export GDK_BACKEND=x11
export NO_AT_BRIDGE=1
# Force Configs (JVM Args + GLFW)
cfg="$HOME/.local/share/PrismLauncher/prismlauncher.cfg"
if [ -f "$cfg" ]; then
# JVM Args
if ${pkgs.gnugrep}/bin/grep -q "^JvmArgs=" "$cfg"; then
${pkgs.gnused}/bin/sed -i "s|^JvmArgs=.*|JvmArgs=${cfg.jvmArgs}|" "$cfg"
else
if ${pkgs.gnugrep}/bin/grep -q "^\\[General\\]" "$cfg"; then
${pkgs.gnused}/bin/sed -i "/^\\[General\\]/a JvmArgs=${cfg.jvmArgs}" "$cfg"
else
echo "JvmArgs=${cfg.jvmArgs}" >> "$cfg"
fi
fi
# GLFW Settings
# 1. CustomGLFWPath
if ${pkgs.gnugrep}/bin/grep -q "^CustomGLFWPath=" "$cfg"; then
${pkgs.gnused}/bin/sed -i "s|^CustomGLFWPath=.*|CustomGLFWPath=${glfwPath}|" "$cfg"
else
echo "CustomGLFWPath=${glfwPath}" >> "$cfg"
fi
# 2. UseNativeGLFW
if ${pkgs.gnugrep}/bin/grep -q "^UseNativeGLFW=" "$cfg"; then
${pkgs.gnused}/bin/sed -i "s|^UseNativeGLFW=.*|UseNativeGLFW=true|" "$cfg"
else
echo "UseNativeGLFW=true" >> "$cfg"
fi
fi
'';
fhsenv.bwrap.additionalArgs = [
# D-Bus proxy
''--bind "$XDG_RUNTIME_DIR/bus" "$XDG_RUNTIME_DIR/bus"''
# Note: The original code bound a specific path TO ./bus.
# "''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''"
# But mkDbusProxyScript (if standard) creates a socket.
# The logic in prismlauncher-sandboxed.nix imported sandbox-utils.nix.
# I'll try to match the original bind logic if possible.
# The original code had:
# ''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''
# But my inline mkDbusProxyScript sets up "$XDG_RUNTIME_DIR/bus" as the listen socket *inside* the script execution?
# Wait, xdg-dbus-proxy runs inside the outer unshared namespace or outside?
# In mkBwrapper, preCmds run *inside* the bwrap?
# No, typically preCmds run before the final exec?
# Actually, looking at nix-bwrapper, `preCmds.stage2` runs *inside* the sandbox?
# Let's start with the binds exactly as they were, assuming `sandbox-utils` logic.
# If I can't import sandbox-utils, I have to rely on what I can see.
# The original `sandbox-utils.nix` likely set up the proxy.
# I will copy the binds from the original file.
''--bind "$XDG_RUNTIME_DIR/app/org.prismlauncher.PrismLauncher/bus" "$XDG_RUNTIME_DIR/bus"''
# Wayland socket
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
# PipeWire + Pulse
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
];
})
];
};
}

View file

@ -40,7 +40,7 @@ in
azahar-sandboxed = bwrapperPkgs.mkBwrapper { azahar-sandboxed = bwrapperPkgs.mkBwrapper {
app = { app = {
package = azahar; package = azahar;
id = "org.azahar_emu.azahar"; id = "org.azahar_emu.Azahar";
env = { env = {
QT_QPA_PLATFORM = "wayland;xcb"; QT_QPA_PLATFORM = "wayland;xcb";
XDG_CURRENT_DESKTOP = "KDE"; XDG_CURRENT_DESKTOP = "KDE";
@ -51,10 +51,7 @@ in
fhsenv.bwrap.additionalArgs = [ fhsenv.bwrap.additionalArgs = [
"--dir /run/systemd/resolve" "--dir /run/systemd/resolve"
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve" "--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
''--bind "$XDG_RUNTIME_DIR/app/org.azahar_emu.azahar/bus" "$XDG_RUNTIME_DIR/bus"'' ''--bind "$XDG_RUNTIME_DIR/app/org.azahar_emu.Azahar/bus" "$XDG_RUNTIME_DIR/bus"''
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
]; ];
mounts = { mounts = {
@ -74,7 +71,7 @@ in
dbus.enable = false; dbus.enable = false;
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript { script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
appId = "org.azahar_emu.azahar"; appId = "org.azahar_emu.Azahar";
enableSystemBus = false; enableSystemBus = false;
proxyArgs = [ proxyArgs = [
"--filter" "--filter"

View file

@ -1,4 +1,3 @@
# Brave Sandboxed with nix-bwrapper
{ {
config, config,
lib, lib,
@ -150,4 +149,26 @@ in
}; };
}) })
]; ];
environment.systemPackages =
let
vpnLauncher = pkgs.writeShellScriptBin "brave-vpn" ''
exec /home/ashie/nixos/scripts/launch-vpn-app.sh ${pkgs.brave-sandboxed}/bin/brave "$@"
'';
desktopItem = pkgs.makeDesktopItem {
name = "brave-vpn";
desktopName = "Brave (VPN)";
exec = "${vpnLauncher}/bin/brave-vpn";
icon = "brave-browser";
categories = [
"Network"
"WebBrowser"
];
};
in
[
vpnLauncher
desktopItem
];
} }

View file

@ -1,16 +1,3 @@
# Caddy with Cloudflare DNS-01 ACME Module
# Provides: Caddy reverse proxy with automatic SSL via Cloudflare DNS
#
# Usage:
# myModules.caddyCloudflare = {
# enable = true;
# email = "you@example.com";
# cloudflareApiTokenFile = config.sops.secrets.cloudflare_api_key.path;
# virtualHosts = {
# "api.example.com" = { reverseProxy = "127.0.0.1:8080"; };
# };
# };
{ {
config, config,
lib, lib,

View file

@ -143,7 +143,9 @@ in
# Create directories that bwrap will bind # Create directories that bwrap will bind
mkdir -p "$HOME/.cache/citron-tmp" mkdir -p "$HOME/.cache/citron-tmp"
mkdir -p "$HOME/.config/citron" mkdir -p "$HOME/.config/citron"
mkdir -p "$HOME/.config/Citron"
mkdir -p "$HOME/.local/share/citron" mkdir -p "$HOME/.local/share/citron"
mkdir -p "$HOME/.local/share/Citron"
mkdir -p "$HOME/Games/Switch" mkdir -p "$HOME/Games/Switch"
'' ''
+ (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript { + (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
@ -170,13 +172,6 @@ in
# D-Bus session proxy only # D-Bus session proxy only
''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"'' ''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"''
# Wayland socket
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
# PipeWire + Pulse
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
# Manual mounts for data persistence # Manual mounts for data persistence
"--ro-bind-try $HOME/.config/kdedefaults $HOME/.config/kdedefaults" "--ro-bind-try $HOME/.config/kdedefaults $HOME/.config/kdedefaults"
"--ro-bind-try $HOME/.local/share/color-schemes $HOME/.local/share/color-schemes" "--ro-bind-try $HOME/.local/share/color-schemes $HOME/.local/share/color-schemes"
@ -190,7 +185,9 @@ in
# Read-write mounts # Read-write mounts
"--bind $HOME/Games/Switch $HOME/Games/Switch" "--bind $HOME/Games/Switch $HOME/Games/Switch"
"--bind $HOME/.config/citron $HOME/.config/citron" "--bind $HOME/.config/citron $HOME/.config/citron"
"--bind $HOME/.config/Citron $HOME/.config/Citron"
"--bind $HOME/.local/share/citron $HOME/.local/share/citron" "--bind $HOME/.local/share/citron $HOME/.local/share/citron"
"--bind $HOME/.local/share/Citron $HOME/.local/share/Citron"
"--bind $HOME/.cache/citron-tmp $HOME/.cache/citron-tmp" "--bind $HOME/.cache/citron-tmp $HOME/.cache/citron-tmp"
]; ];
}; };

14
modules/system/cosmic.nix Normal file
View file

@ -0,0 +1,14 @@
{
pkgs,
...
}:
{
services.desktopManager.cosmic.enable = true;
services.displayManager.cosmic-greeter.enable = false;
# Optimization
services.system76-scheduler.enable = true;
# Clipboard support (unstable protocol)
environment.sessionVariables.COSMIC_DATA_CONTROL_ENABLED = "1";
}

View file

@ -9,6 +9,8 @@
imports = [ imports = [
./common.nix ./common.nix
./security.nix ./security.nix
./mac-randomization.nix
./usbguard.nix
./kernel-hardening.nix ./kernel-hardening.nix
./secure-boot.nix ./secure-boot.nix
./dns-over-tls.nix ./dns-over-tls.nix
@ -31,5 +33,8 @@
./spotify-sandboxed.nix ./spotify-sandboxed.nix
./performance.nix ./performance.nix
./vesktop-sandboxed.nix ./vesktop-sandboxed.nix
./tutanota-sandboxed.nix
./hardened-malloc.nix
./searxng.nix
]; ];
} }

View file

@ -138,13 +138,6 @@ in
# D-Bus session proxy only # D-Bus session proxy only
''--bind "$XDG_RUNTIME_DIR/app/io.github.faugus.Launcher/bus" "$XDG_RUNTIME_DIR/bus"'' ''--bind "$XDG_RUNTIME_DIR/app/io.github.faugus.Launcher/bus" "$XDG_RUNTIME_DIR/bus"''
# Wayland socket
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
# PipeWire + Pulse
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
# dconf for GTK settings # dconf for GTK settings
"--bind-try /run/user/${toString config.users.users.ashie.uid}/dconf /run/user/${toString config.users.users.ashie.uid}/dconf" "--bind-try /run/user/${toString config.users.users.ashie.uid}/dconf /run/user/${toString config.users.users.ashie.uid}/dconf"
]; ];

View file

@ -1,4 +1,3 @@
# Firefox Sandboxed with nix-bwrapper
{ {
config, config,
lib, lib,

View file

@ -0,0 +1,32 @@
# Hardened Malloc Module (Scudo)
# Provides: Userspace memory corruption mitigations via LLVM Scudo
#
# Usage:
# myModules.hardenedMalloc = {
# enable = true;
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.hardenedMalloc;
in
{
options.myModules.hardenedMalloc = {
enable = lib.mkEnableOption "hardened memory allocator (Scudo)";
};
config = lib.mkIf cfg.enable {
environment.memoryAllocator.provider = "scudo";
# Scudo options:
# ZeroContents=1: Zero chunks on allocation/deallocation (mitigates use-after-free info leaks)
# PatternFillContents=1: (Alternative to Zero) Fill with pattern to catch bugs
environment.variables.SCUDO_OPTIONS = "ZeroContents=1";
};
}

View file

@ -34,6 +34,12 @@
"/var/lib/bluetooth" # Bluetooth pairings "/var/lib/bluetooth" # Bluetooth pairings
"/var/lib/sbctl" # Secure Boot Keys "/var/lib/sbctl" # Secure Boot Keys
"/etc/NetworkManager/system-connections" # Wifi/Ethernet profiles "/etc/NetworkManager/system-connections" # Wifi/Ethernet profiles
"/var/lib/sonarr"
"/var/lib/radarr"
"/var/lib/prowlarr"
"/var/lib/qbittorrent"
"/var/lib/jellyfin"
"/var/lib/jellyseerr"
]; ];
files = [ files = [
@ -47,6 +53,7 @@
"Music" "Music"
"Pictures" "Pictures"
"Videos" "Videos"
"Torrents"
"nixos" # Config repo "nixos" # Config repo
".local/share/PrismLauncher" # Minecraft ".local/share/PrismLauncher" # Minecraft
".local/share/containers" # Rootless podman ".local/share/containers" # Rootless podman
@ -58,10 +65,12 @@
"git" # Git Repositories "git" # Git Repositories
".local/state" # Application State ".local/state" # Application State
".config/Antigravity" # Antigravity Config ".config/Antigravity" # Antigravity Config
".config/modprobed-db" # Local modconfig database
".config/VSCodium" # Codium Config ".config/VSCodium" # Codium Config
".config/sops" # Sops Keys ".config/sops" # Sops Keys
".config/gh" # Github CLI Auth ".config/gh" # Github CLI Auth
".local/share/keyrings" # Gnome Keyrings (Passwords) ".local/share/keyrings" # Gnome Keyrings (Passwords)
".local/share/nvim" # NeoVim data (LazyVim, Mason, etc.)
".local/share/flatpak" # Flatpak Apps ".local/share/flatpak" # Flatpak Apps
".vscode" # VSCode Extensions ".vscode" # VSCode Extensions
".vscode-oss" # VSCodium Extensions ".vscode-oss" # VSCodium Extensions
@ -71,6 +80,10 @@
".config/citron" ".config/citron"
".local/share/citron" ".local/share/citron"
".cache/lutris" ".cache/lutris"
".config/azahar"
".local/share/azahar"
".config/Citron"
".local/share/Citron"
".local/share/umu" ".local/share/umu"
".cache/mesa_shader_cache" ".cache/mesa_shader_cache"
# ".local/share/Steam" # Symlinked to /games/Steam (Already Persistent) # ".local/share/Steam" # Symlinked to /games/Steam (Already Persistent)
@ -78,6 +91,8 @@
".config/steamtinkerlaunch" # Example of extra tools ".config/steamtinkerlaunch" # Example of extra tools
".local/share/applications" # Desktop entries ".local/share/applications" # Desktop entries
".local/share/icons" # Application icons ".local/share/icons" # Application icons
".local/bin" # User scripts
".local/share/qBittorrent"
]; ];
}; };
}; };

View file

@ -66,6 +66,9 @@ in
"randomize_kstack_offset=on" "randomize_kstack_offset=on"
"vsyscall=none" "vsyscall=none"
"oops=panic" "oops=panic"
"debugfs=off"
"module.sig_enforce=1"
"lockdown=confidentiality"
]; ];
# Kernel sysctl hardening # Kernel sysctl hardening
@ -104,6 +107,13 @@ in
"net.ipv4.tcp_rmem" = "4096 87380 2500000"; "net.ipv4.tcp_rmem" = "4096 87380 2500000";
"net.ipv4.tcp_wmem" = "4096 65536 2500000"; "net.ipv4.tcp_wmem" = "4096 65536 2500000";
"net.core.netdev_max_backlog" = 5000; "net.core.netdev_max_backlog" = 5000;
# Advanced Security
"net.core.bpf_jit_harden" = 2;
"fs.suid_dumpable" = 0;
"kernel.sysrq" = 0;
"net.ipv4.conf.all.accept_source_route" = 0;
"net.ipv6.conf.all.accept_source_route" = 0;
}; };
# Set IO Scheduler to kyber for NVMe and bfq for SATA # Set IO Scheduler to kyber for NVMe and bfq for SATA

View file

@ -76,7 +76,7 @@ in
]; ];
readWrite = [ readWrite = [
"$HOME/Games" "$HOME/Games/windows"
"$HOME/.local/share/icons" "$HOME/.local/share/icons"
"$HOME/.config/lutris" "$HOME/.config/lutris"
"$HOME/.local/share/lutris" "$HOME/.local/share/lutris"

View file

@ -0,0 +1,42 @@
# MAC Address Randomization Module
# Provides: MAC address randomization for Wi-Fi and Ethernet
#
# Usage:
# myModules.macRandomization = {
# enable = true;
# mode = "stable-ssid"; # "random", "stable", "stable-ssid" (default)
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.macRandomization;
in
{
options.myModules.macRandomization = {
enable = lib.mkEnableOption "MAC address randomization";
mode = lib.mkOption {
type = lib.types.enum [ "random" "stable" "stable-ssid" ];
default = "stable-ssid";
description = ''
MAC randomization mode:
- random: Randomize for every connection (highest privacy, might break captive portals).
- stable: Generate a stable random MAC per connection profile.
- stable-ssid: Generate a stable random MAC per SSID (default).
'';
};
};
config = lib.mkIf cfg.enable {
networking.networkmanager.wifi.macAddress = cfg.mode;
# Optional: Ethernet randomization (can cause issues on some LANs)
# networking.networkmanager.ethernet.macAddress = cfg.mode;
};
}

167
modules/system/media.nix Normal file
View file

@ -0,0 +1,167 @@
{
config,
lib,
pkgs,
...
}:
{
# 1. Create the 'media' group (optional now if running as user)
users.groups.media = { };
# 2. OCI Container Configuration
virtualisation.oci-containers.containers = {
# Prowlarr
prowlarr = {
image = "lscr.io/linuxserver/prowlarr:latest";
ports = [ "9696:9696" ];
environment = {
PUID = "1000";
PGID = "100"; # users group
TZ = "Europe/Berlin";
};
volumes = [
"/var/lib/prowlarr:/config"
];
};
# Sonarr
sonarr = {
image = "lscr.io/linuxserver/sonarr:latest";
ports = [ "8989:8989" ];
environment = {
PUID = "1000";
PGID = "100";
TZ = "Europe/Berlin";
};
volumes = [
"/var/lib/sonarr:/config"
"/data:/data"
];
};
# Radarr
radarr = {
image = "lscr.io/linuxserver/radarr:latest";
ports = [ "7878:7878" ];
environment = {
PUID = "1000";
PGID = "100";
TZ = "Europe/Berlin";
};
volumes = [
"/var/lib/radarr:/config"
"/data:/data"
];
};
# FlareSolverr (Cloudflare Bypass)
flaresolverr = {
image = "ghcr.io/flaresolverr/flaresolverr:latest";
ports = [ "8191:8191" ];
environment = {
TZ = "Europe/Berlin";
LOG_LEVEL = "info";
};
};
# Jellyfin (Media Server)
jellyfin = {
image = "lscr.io/linuxserver/jellyfin:latest";
ports = [ "8096:8096" ];
environment = {
PUID = "1000";
PGID = "100";
TZ = "Europe/Berlin";
};
volumes = [
"/var/lib/jellyfin:/config"
"/data:/data"
];
};
# VPN (Gluetun)
# WARNING: You must configure your VPN provider details in 'environmentFiles' or 'environment'
vpn = {
image = "qmcgaw/gluetun";
ports = [
"8080:8080" # qBittorrent WebUI
"6881:6881" # Torrent Port TCP
"6881:6881/udp" # Torrent Port UDP
];
environmentFiles = [ config.sops.templates."gluetun.env".path ];
environment = {
TZ = "Europe/Berlin";
DOT = "off";
DNS_ADDRESS = "1.1.1.1";
WIREGUARD_MTU = "1420";
};
extraOptions = [
"--cap-add=NET_ADMIN"
"--cap-add=NET_RAW"
"--device=/dev/net/tun:/dev/net/tun"
];
};
# qBittorrent (Networked via VPN)
torrent = {
image = "lscr.io/linuxserver/qbittorrent:latest";
# Ports are exposed via vpn container, not here
extraOptions = [ "--network=container:vpn" ];
dependsOn = [ "vpn" ];
environment = {
PUID = "1000";
PGID = "100";
TZ = "Europe/Berlin";
WEBUI_PORT = "8080";
};
volumes = [
"/var/lib/qbittorrent:/config"
"/data:/data"
];
};
# Jellyseerr (Request Management)
jellyseerr = {
image = "docker.io/fallenbagel/jellyseerr:latest";
ports = [ "5055:5055" ];
environment = {
LOG_LEVEL = "debug";
TZ = "Europe/Berlin";
};
volumes = [
"/var/lib/jellyseerr:/app/config"
];
};
};
# Ensure config directories exist and are owned by the user (1000)
systemd.tmpfiles.rules = [
"d /data 0755 ashie users - -"
"d /var/lib/prowlarr 0755 ashie users - -"
"d /var/lib/sonarr 0755 ashie users - -"
"d /var/lib/radarr 0755 ashie users - -"
"d /var/lib/qbittorrent 0755 ashie users - -"
"d /var/lib/jellyfin 0755 ashie users - -"
"d /var/lib/jellyseerr 0755 ashie users - -"
# Recursively fix permissions on restart to ensure 1000 owns the config
"Z /var/lib/prowlarr - ashie users - -"
"Z /var/lib/sonarr - ashie users - -"
"Z /var/lib/radarr - ashie users - -"
"Z /var/lib/qbittorrent - ashie users - -"
"Z /var/lib/jellyfin - ashie users - -"
"Z /var/lib/jellyseerr - ashie users - -"
];
# Firewall rules
networking.firewall.allowedTCPPorts = [
9696
8989
7878
8191
8080
8096
5055
6881
];
networking.firewall.allowedUDPPorts = [ 6881 ];
}

View file

@ -14,7 +14,7 @@
config = lib.mkIf config.myModules.performance.enable { config = lib.mkIf config.myModules.performance.enable {
services.scx = { services.scx = {
enable = true; enable = true;
scheduler = "scx_rustland"; scheduler = "scx_lavd";
package = pkgs.scx.full; package = pkgs.scx.full;
}; };
@ -46,6 +46,8 @@
"net.ipv4.tcp_wmem" = lib.mkForce "4096 65536 16777216"; "net.ipv4.tcp_wmem" = lib.mkForce "4096 65536 16777216";
}; };
powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
# faster boot # faster boot
systemd.services.NetworkManager-wait-online.enable = lib.mkForce false; systemd.services.NetworkManager-wait-online.enable = lib.mkForce false;
systemd.services.systemd-networkd-wait-online.enable = lib.mkForce false; systemd.services.systemd-networkd-wait-online.enable = lib.mkForce false;

View file

@ -53,28 +53,29 @@ in
prismlauncher-sandboxed = bwrapperPkgs.mkBwrapper { prismlauncher-sandboxed = bwrapperPkgs.mkBwrapper {
app = { app = {
id = "org.prismlauncher.PrismLauncher"; id = "org.prismlauncher.PrismLauncher";
package = package = pkgs.prismlauncher.overrideAttrs (old: {
inputs.prismlauncher.packages.${pkgs.stdenv.hostPlatform.system}.prismlauncher.overrideAttrs pname = "prismlauncher";
(old: { version = old.version or "9.1";
pname = "prismlauncher"; buildInputs = (old.buildInputs or [ ]) ++ [ pkgs.mimalloc ];
version = old.version or "9.1";
buildInputs = (old.buildInputs or [ ]) ++ runtimeLibs ++ [ pkgs.mimalloc ];
qtWrapperArgs = (old.qtWrapperArgs or [ ]) ++ [ # Keep runtimeLibs in closure without injecting them into environment
"--set MIMALLOC_PATH ${pkgs.mimalloc}/lib/libmimalloc.so" postInstall = (old.postInstall or "") + ''
"--prefix LD_PRELOAD : ${pkgs.mimalloc}/lib/libmimalloc.so" mkdir -p $out/share/prismlauncher-sandboxed
"--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath runtimeLibs}" echo "${lib.makeLibraryPath runtimeLibs}" > $out/share/prismlauncher-sandboxed/libs
"--prefix QT_PLUGIN_PATH : ${pkgs.kdePackages.qtstyleplugin-kvantum}/lib/qt6/plugins" '';
];
}); qtWrapperArgs = (old.qtWrapperArgs or [ ]) ++ [
"--set MIMALLOC_PATH ${pkgs.mimalloc}/lib/libmimalloc.so"
"--prefix LD_PRELOAD : ${pkgs.mimalloc}/lib/libmimalloc.so"
];
});
env = { env = {
# Propagate XDG_DATA_DIRS so themes/icons can be found # Propagate XDG_DATA_DIRS so themes/icons can be found
XDG_DATA_DIRS = "$XDG_DATA_DIRS"; # XDG_DATA_DIRS = "$XDG_DATA_DIRS";
GTK_THEME = "catppuccin-mocha-mauve-standard";
QT_QPA_PLATFORMTHEME = "gtk3";
QT_STYLE_OVERRIDE = "kvantum";
BROWSER = "firefox"; BROWSER = "firefox";
QT_QPA_PLATFORMTHEME = "";
QT_STYLE_OVERRIDE = "fusion";
}; };
}; };
@ -103,7 +104,7 @@ in
"--dir /run/user" "--dir /run/user"
"--dir /run/user/${toString config.users.users.ashie.uid}" "--dir /run/user/${toString config.users.users.ashie.uid}"
# Bind ro system paths commonly needed # Bind ro system paths commonly needed
"--ro-bind-try /run/current-system /run/current-system" # "--ro-bind-try /run/current-system /run/current-system"
"--ro-bind-try /run/opengl-driver /run/opengl-driver" "--ro-bind-try /run/opengl-driver /run/opengl-driver"
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32" "--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
"--dir /run/systemd/resolve" "--dir /run/systemd/resolve"

View file

@ -109,13 +109,6 @@ in
# D-Bus session proxy only # D-Bus session proxy only
''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"'' ''--bind "$XDG_RUNTIME_DIR/app/${appId}/bus" "$XDG_RUNTIME_DIR/bus"''
# Wayland socket
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
# PipeWire + Pulse
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
# Manual mounts for data persistence # Manual mounts for data persistence
"--ro-bind-try $HOME/.config/kdedefaults $HOME/.config/kdedefaults" "--ro-bind-try $HOME/.config/kdedefaults $HOME/.config/kdedefaults"
"--ro-bind-try $HOME/.local/share/color-schemes $HOME/.local/share/color-schemes" "--ro-bind-try $HOME/.local/share/color-schemes $HOME/.local/share/color-schemes"

View file

@ -13,7 +13,7 @@ in
enable = lib.mkEnableOption "sched-ext (scx) schedulers"; enable = lib.mkEnableOption "sched-ext (scx) schedulers";
scheduler = lib.mkOption { scheduler = lib.mkOption {
type = lib.types.enum [ "scx_rustland" "scx_lavd" "scx_rusty" "scx_bpfland" ]; type = lib.types.enum [ "scx_lavd" "scx_rusty" "scx_bpfland" ];
default = "scx_lavd"; default = "scx_lavd";
description = "The scx scheduler to run."; description = "The scx scheduler to run.";
}; };

303
modules/system/searxng.nix Normal file
View file

@ -0,0 +1,303 @@
# SearXNG Module (Rootless Podman)
# Provides: Private meta-search engine running in a rootless container
#
# Usage:
# myModules.searxng = {
# enable = true;
# port = 8888;
# domain = "search.ashisgreat.xyz";
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.searxng;
catppuccinCss = pkgs.writeText "searxng-catppuccin.css" ''
:root {
/* Mocha (Dark) */
--cat-rosewater: #f5e0dc;
--cat-flamingo: #f2cdcd;
--cat-pink: #f5c2e7;
--cat-mauve: #cba6f7;
--cat-red: #f38ba8;
--cat-maroon: #eba0ac;
--cat-peach: #fab387;
--cat-yellow: #f9e2af;
--cat-green: #a6e3a1;
--cat-teal: #94e2d5;
--cat-sky: #89dceb;
--cat-sapphire: #74c7ec;
--cat-blue: #89b4fa;
--cat-lavender: #b4befe;
--cat-text: #cdd6f4;
--cat-subtext1: #bac2de;
--cat-subtext0: #a6adc8;
--cat-overlay2: #9399b2;
--cat-overlay1: #7f849c;
--cat-overlay0: #6c7086;
--cat-surface2: #585b70;
--cat-surface1: #45475a;
--cat-surface0: #313244;
--cat-base: #1e1e2e;
--cat-mantle: #181825;
--cat-crust: #11111b;
}
@media (prefers-color-scheme: light) {
:root {
/* Latte (Light) */
--cat-rosewater: #dc8a78;
--cat-flamingo: #dd7878;
--cat-pink: #ea76cb;
--cat-mauve: #8839ef;
--cat-red: #d20f39;
--cat-maroon: #e64553;
--cat-peach: #fe640b;
--cat-yellow: #df8e1d;
--cat-green: #40a02b;
--cat-teal: #179287;
--cat-sky: #04a5e5;
--cat-sapphire: #209fb5;
--cat-blue: #1e66f5;
--cat-lavender: #7287fd;
--cat-text: #4c4f69;
--cat-subtext1: #5c5f77;
--cat-subtext0: #6c6f85;
--cat-overlay2: #7c7f93;
--cat-overlay1: #8c8fa1;
--cat-overlay0: #9ca0b0;
--cat-surface2: #acb0be;
--cat-surface1: #bcc0cc;
--cat-surface0: #ccd0da;
--cat-base: #eff1f5;
--cat-mantle: #e6e9ef;
--cat-crust: #dce0e8;
}
}
/* Apply variables */
:root {
--color-base-font: var(--cat-text);
--color-base-background: var(--cat-base);
--color-base-background-mobile: var(--cat-base);
--color-url-font: var(--cat-mauve);
--color-url-visited-font: var(--cat-mauve);
--color-header-background: var(--cat-mantle);
--color-header-border: var(--cat-mantle);
--color-footer-background: var(--cat-mantle);
--color-footer-border: var(--cat-mantle);
--color-sidebar-border: var(--cat-base);
--color-sidebar-font: var(--cat-text);
--color-sidebar-background: var(--cat-base);
--color-backtotop-font: var(--cat-subtext1);
--color-backtotop-border: var(--cat-surface0);
--color-backtotop-background: var(--cat-surface0);
--color-btn-background: var(--cat-mauve);
--color-btn-font: var(--cat-base);
--color-show-btn-background: var(--cat-mauve);
--color-show-btn-font: var(--cat-base);
--color-search-border: var(--cat-surface0);
--color-search-shadow: 0 2px 8px var(--cat-crust);
--color-search-background: var(--cat-surface0);
--color-search-font: var(--cat-text);
--color-search-background-hover: var(--cat-mauve);
--color-error: var(--cat-red);
--color-error-background: var(--cat-surface0);
--color-warning: var(--cat-yellow);
--color-warning-background: var(--cat-surface0);
--color-success: var(--cat-green);
--color-success-background: var(--cat-surface0);
--color-categories-item-selected-font: var(--cat-text);
--color-categories-item-border-selected: var(--cat-mauve);
--color-autocomplete-font: var(--cat-subtext1);
--color-autocomplete-border: var(--cat-surface0);
--color-autocomplete-shadow: 0 2px 8px var(--cat-crust);
--color-autocomplete-background: var(--cat-surface0);
--color-autocomplete-background-hover: var(--cat-surface1);
--color-answer-font: var(--cat-text);
--color-answer-background: var(--cat-mantle);
--color-result-background: var(--cat-mantle);
--color-result-border: var(--cat-base);
--color-result-url-font: var(--cat-subtext1);
--color-result-vim-selected: var(--cat-surface0);
--color-result-vim-arrow: var(--cat-mauve);
--color-result-description-highlight-font: var(--cat-text);
--color-result-link-font: var(--cat-mauve);
--color-result-link-font-highlight: var(--cat-mauve);
--color-result-link-visited-font: var(--cat-mauve);
--color-result-publishdate-font: var(--cat-surface2);
--color-result-engines-font: var(--cat-surface2);
--color-result-search-url-border: var(--cat-surface2);
--color-result-search-url-font: var(--cat-text);
--color-result-detail-font: var(--cat-text);
--color-result-detail-label-font: var(--cat-subtext0);
--color-result-detail-background: var(--cat-base);
--color-result-detail-hr: var(--cat-base);
--color-result-detail-link: var(--cat-mauve);
--color-result-detail-loader-border: rgba(255, 255, 255, 0.2);
--color-result-detail-loader-borderleft: var(--cat-crust);
--color-result-image-span-font: var(--cat-text);
--color-result-image-span-font-selected: var(--cat-base);
--color-result-image-background: var(--cat-mantle);
--color-settings-tr-hover: var(--cat-surface0);
--color-settings-engine-description-font: var(--cat-text);
--color-settings-engine-group-background: var(--cat-surface0);
--color-toolkit-badge-font: var(--cat-text);
--color-toolkit-badge-background: var(--cat-surface0);
--color-toolkit-kbd-font: var(--cat-text);
--color-toolkit-kbd-background: var(--cat-mantle);
--color-toolkit-dialog-border: var(--cat-mantle);
--color-toolkit-dialog-background: var(--cat-mantle);
--color-toolkit-tabs-label-border: var(--cat-base);
--color-toolkit-tabs-section-border: var(--cat-base);
--color-toolkit-select-background: var(--cat-surface0);
--color-toolkit-select-border: var(--cat-surface0);
--color-toolkit-select-background-hover: var(--cat-surface1);
--color-toolkit-input-text-font: var(--cat-text);
--color-toolkit-checkbox-onoff-off-background: var(--cat-surface0);
--color-toolkit-checkbox-onoff-on-background: var(--cat-surface0);
--color-toolkit-checkbox-onoff-on-mark-background: var(--cat-green);
--color-toolkit-checkbox-onoff-on-mark-color: var(--cat-mantle);
--color-toolkit-checkbox-onoff-off-mark-background: var(--cat-red);
--color-toolkit-checkbox-onoff-off-mark-color: var(--cat-mantle);
--color-toolkit-checkbox-label-background: var(--cat-base);
--color-toolkit-checkbox-label-border: var(--cat-mantle);
--color-toolkit-checkbox-input-border: var(--cat-mauve);
--color-toolkit-engine-tooltip-border: var(--cat-surface0);
--color-toolkit-engine-tooltip-background: var(--cat-surface0);
--color-toolkit-loader-border: rgba(255, 255, 255, 0.2);
--color-toolkit-loader-borderleft: var(--cat-crust);
--color-doc-code: var(--cat-rosewater);
--color-doc-code-background: var(--cat-mantle);
}
#search_logo svg :not([fill="none"]) {
fill: var(--cat-mauve) !important;
}
#search_logo svg :not([stroke="none"]) {
stroke: var(--cat-mauve) !important;
}
/* Additional cute tweaks */
article.result {
background-color: var(--color-result-background);
border-radius: 0.75em;
padding: 0.75em;
margin: 0.5em;
border: 1px solid var(--cat-surface0);
}
article.category-images {
padding-bottom: 4em;
}
input[type="text"] {
border-radius: 2em !important;
}
'';
in
{
options.myModules.searxng = {
enable = lib.mkEnableOption "SearXNG meta-search engine";
port = lib.mkOption {
type = lib.types.port;
default = 8888;
description = "Port to expose SearXNG on localhost";
};
domain = lib.mkOption {
type = lib.types.str;
default = "search.ashisgreat.xyz";
description = "Public domain name for SearXNG";
};
};
config = lib.mkIf cfg.enable {
# Ensure Podman is enabled
myModules.podman.enable = true;
# 1. Redis Container (Cache/Limiter)
virtualisation.oci-containers.containers."searxng-redis" = {
image = "docker.io/library/redis:alpine";
cmd = [ "redis-server" "--save" "" "--appendonly" "no" ]; # Ephemeral cache, no persistence needed
ports = [ "127.0.0.1:6379:6379" ];
};
# 2. SearXNG Container
virtualisation.oci-containers.containers."searxng" = {
image = "docker.io/searxng/searxng:latest";
ports = [ "127.0.0.1:${toString cfg.port}:8080" ];
environment = {
"SEARXNG_BASE_URL" = "https://${cfg.domain}";
"SEARXNG_REDIS_URL" = "redis://searxng-redis:6379"; # Talk to Redis directly via container DNS
"SEARXNG_URL_BASE" = "https://${cfg.domain}";
};
environmentFiles = [
# Contains SEARXNG_SECRET_KEY
config.sops.templates."searxng.env".path
];
extraOptions = [
"--cap-drop=ALL"
"--cap-add=CHOWN"
"--cap-add=SETGID"
"--cap-add=SETUID"
"--cap-add=DAC_OVERRIDE"
"--add-host=host.containers.internal:host-gateway"
];
volumes = [
"${config.sops.templates."searxng_settings.yml".path}:/etc/searxng/settings.yml:ro"
"${catppuccinCss}:/etc/searxng/custom.css:ro"
];
};
# 3. Secrets Configuration
# We generate the settings.yml dynamically using sops templates to inject secrets if needed,
# or just to manage the config declaratively.
sops.templates."searxng.env".content = ''
SEARXNG_SECRET_KEY=${config.sops.placeholder.searxng_secret_key}
'';
sops.templates."searxng_settings.yml".content = ''
use_default_settings: true
general:
debug: false
instance_name: "Ashie Search"
donations:
patreon: false
buymeacoffee: false
search:
safe_search: 0
autocomplete: "google"
default_lang: "en-US"
formats:
- html
- json
server:
port: 8080
bind_address: "0.0.0.0"
secret_key: "${config.sops.placeholder.searxng_secret_key}"
limiter: true
image_proxy: true
ui:
static_use_hash: true
custom_css: custom.css
theme_args:
simple_style: "auto"
redis:
url: redis://searxng-redis:6379/0
'';
# Placeholder secret definition (User must add this to secrets.yaml!)
sops.secrets.searxng_secret_key = { };
};
}

View file

@ -1,14 +1,3 @@
# Security Hardening Module
# Provides: doas (sudo replacement), audit logging, AppArmor, core dump prevention
#
# Usage:
# myModules.security = {
# enable = true;
# enableAudit = true; # default: true
# enableAppArmor = true; # default: true
# useDoas = true; # default: true (replaces sudo)
# };
{ {
config, config,
lib, lib,
@ -66,6 +55,14 @@ in
} }
]; ];
# Proc hardening (Hide other users' processes)
boot.specialFileSystems."/proc".options = [
"nosuid"
"nodev"
"noexec"
"hidepid=2"
];
# Security audit logging # Security audit logging
security.auditd.enable = cfg.enableAudit; security.auditd.enable = cfg.enableAudit;
security.audit = lib.mkIf cfg.enableAudit { security.audit = lib.mkIf cfg.enableAudit {

View file

@ -95,7 +95,6 @@ in
"$HOME/.local/share/color-schemes" "$HOME/.local/share/color-schemes"
]; ];
readWrite = [ readWrite = [
"$HOME/Games"
"$HOME/.steam" "$HOME/.steam"
"$HOME/.local/share/Steam" "$HOME/.local/share/Steam"
"$HOME/.local/share/umu" "$HOME/.local/share/umu"
@ -104,6 +103,7 @@ in
"$HOME/.local/share/icons" "$HOME/.local/share/icons"
"$HOME/.local/share/Larian Studios" "$HOME/.local/share/Larian Studios"
"$HOME/Desktop" "$HOME/Desktop"
"/games/steam"
]; ];
}; };

View file

@ -0,0 +1,119 @@
{
config,
lib,
pkgs,
inputs,
...
}:
let
bwrapperPkgs = pkgs.extend inputs.nix-bwrapper.overlays.default;
pname = "tutanota-desktop";
version = "319.260107.1";
src = pkgs.fetchurl {
url = "https://github.com/tutao/tutanota/releases/download/tutanota-desktop-release-${version}/tutanota-desktop-linux.AppImage";
sha256 = "0gjvh3f70mmr85kx3kz4yd8gfxpk4kj8wkh697a4gy34mgxpqnka";
};
appimageContents = pkgs.appimageTools.extractType2 {
inherit pname version src;
};
tutanota = pkgs.appimageTools.wrapType2 {
inherit pname version src;
extraInstallCommands = ''
install -m 444 -D ${appimageContents}/tutanota-desktop.desktop $out/share/applications/tutanota-desktop.desktop
install -m 444 -D ${appimageContents}/tutanota-desktop.png \
$out/share/icons/hicolor/512x512/apps/tutanota-desktop.png
substituteInPlace $out/share/applications/tutanota-desktop.desktop \
--replace 'Exec=AppRun' 'Exec=tutanota-desktop'
'';
};
in
{
nixpkgs.overlays = [
(final: prev: {
tutanota-sandboxed = bwrapperPkgs.mkBwrapper {
app = {
package = tutanota;
id = "com.tutanota.Tutanota";
env = {
XDG_DATA_DIRS = "$XDG_DATA_DIRS";
};
};
flatpak.enable = false;
# Basic sandboxing
fhsenv.opts = {
unshareUser = true;
unshareUts = true;
unshareCgroup = true;
unsharePid = true;
unshareNet = false; # Needs network
unshareIpc = true;
};
fhsenv.bwrap.baseArgs = lib.mkForce [
"--new-session"
"--proc /proc"
"--dev /dev"
"--dev-bind /dev/dri /dev/dri" # GPU acceleration
"--tmpfs /home"
"--tmpfs /tmp"
"--tmpfs /run"
"--dir /run/user"
"--dir /run/user/${toString config.users.users.ashie.uid}"
# System paths
"--ro-bind /sys /sys"
"--ro-bind-try /run/current-system /run/current-system"
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
"--dir /run/systemd/resolve"
"--ro-bind-try /run/systemd/resolve /run/systemd/resolve"
];
mounts = {
read = [
"$HOME/.config/fontconfig"
"$HOME/.local/share/fonts"
"$HOME/.icons"
"$HOME/.themes"
"$HOME/.local/share/themes"
"$HOME/.config/kdedefaults"
"$HOME/.local/share/color-schemes"
];
readWrite = [
"$HOME/.config/tutanota-desktop"
"$HOME/Downloads"
];
};
dbus.enable = false;
script.preCmds.stage2 = (import ./sandbox-utils.nix { inherit pkgs lib; }).mkDbusProxyScript {
appId = "com.tutanota.Tutanota";
enableSystemBus = false;
proxyArgs = [
"--filter"
''--talk="org.freedesktop.portal.*"''
''--talk="org.freedesktop.Notifications"''
''--talk="org.freedesktop.secrets"''
''--talk="org.gnome.keyring.SystemPrompter"'' # Often needed for secrets
''--call="org.freedesktop.portal.*=*@/org/freedesktop/portal/desktop"''
''--own="com.tutanota.Tutanota"''
];
};
fhsenv.bwrap.additionalArgs = [
# D-Bus session proxy only
''--bind "$XDG_RUNTIME_DIR/app/com.tutanota.Tutanota/bus" "$XDG_RUNTIME_DIR/bus"''
# Wayland
''--bind "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"''
];
};
})
];
}

View file

@ -0,0 +1,52 @@
# USBGuard Module
# Provides: Policy enforcement for USB devices
#
# Usage:
# myModules.usbguard = {
# enable = true;
# generatePolicy = true; # Auto-generate policy from currently connected devices
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.usbguard;
in
{
options.myModules.usbguard = {
enable = lib.mkEnableOption "USBGuard for USB device control";
generatePolicy = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Generate an initial policy from currently connected devices on activation (requires reboot/service restart)";
};
};
config = lib.mkIf cfg.enable {
services.usbguard = {
enable = true;
dbus.enable = true;
# Block new devices by default
implicitPolicyTarget = "block";
# Treat present devices as allowed (until policy is generated)
presentDevicePolicy = "apply-policy"; # or "keep" or "allow"
};
# Helper script to generate policy
environment.systemPackages = lib.mkIf cfg.generatePolicy [
(pkgs.writeShellScriptBin "generate-usbguard-policy" ''
sudo usbguard generate-policy > /etc/usbguard/rules.conf
sudo systemctl restart usbguard
echo "USBGuard policy generated from connected devices."
'')
];
};
}

1
result Symbolic link
View file

@ -0,0 +1 @@
/nix/store/5a7l4w0z3m0fn0cy45rbd3ahms1ncpx1-nixos-system-nixos-26.05.20260111.ffbc9f8

View file

@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -e
# Only run if /games/steam is a mountpoint to verify we aren't deleting the only copy
if ! mountpoint -q /games/steam; then
echo "CRITICAL ERROR: /games/steam is NOT a mountpoint."
echo "This implies the migration didn't apply correctly or the subvolume isn't mounted."
echo "Aborting cleanup to prevent data loss."
exit 1
fi
if [ "$EUID" -ne 0 ]; then
echo "Please run this script with doas: doas $0"
exit 1
fi
cd /games || exit 1
echo "Starting cleanup of old Steam files in /games..."
echo "Preserving: 3DS, Switch, battlenet, and the 'steam' mountpoint."
# Iterate over all files/dirs, including hidden ones
for item in * .[^.]*; do
# Skip . and ..
if [[ "$item" == "." || "$item" == ".." ]]; then continue; fi
case "$item" in
"3DS"|"Switch"|"battlenet"|"steam")
echo " [KEEP] $item"
;;
*)
echo " [DELETE] $item"
rm -rf "$item"
;;
esac
done
echo "Cleanup complete. /games now contains only non-Steam games and the 'steam' directory."

View file

@ -0,0 +1,84 @@
#!/usr/bin/env bash
# Convert COMPLETE kernel config to Nix structuredExtraConfig format
# Reads the generated kernel-config and outputs ALL options
CONFIG_FILE="/home/ashie/nixos/hosts/nixos/kernel-config"
OUTPUT_FILE="/home/ashie/nixos/hosts/nixos/kernel-config.nix"
echo "Converting $CONFIG_FILE to structuredExtraConfig format (FULL)..."
# Start the Nix attribute set
cat > "$OUTPUT_FILE" << 'EOF'
# Auto-generated from kernel-config (FULL)
# Run scripts/convert-kernel-config.sh to regenerate
{ lib }:
with lib.kernel;
{
EOF
# Process line by line
declare -A seen_keys
while read -r line; do
# Skip empty lines and comments that are not "is not set"
if [[ -z "$line" ]]; then continue; fi
if [[ "$line" =~ ^#\ .*is\ not\ set$ ]]; then
# Handle "is not set"
key=$(echo "$line" | sed 's/^# CONFIG_\(.*\) is not set$/\1/')
val="no"
elif [[ "$line" =~ ^CONFIG_ ]]; then
# Handle "CONFIG_KEY=VALUE"
# Extract key and value. Value is everything after first =
key=$(echo "$line" | cut -d= -f1 | sed 's/^CONFIG_//')
val=$(echo "$line" | cut -d= -f2-)
else
# Skip other lines (comments etc)
continue
fi
# Formatting logic
# 1. Quote key if it starts with digit
if [[ "$key" =~ ^[0-9] ]]; then
nix_key="\"$key\""
else
nix_key="$key"
fi
# 2. Convert value to Nix format
if [[ "$val" == "no" ]]; then
nix_val="no"
elif [[ "$val" == "y" ]]; then
nix_val="yes"
elif [[ "$val" == "m" ]]; then
nix_val="module"
elif [[ "$val" == "\"\"" ]]; then
nix_val="(freeform \"\")"
elif [[ "$val" =~ ^\" ]]; then
# It's a string literal "foo".
# NixOS kernel config usually likes freeform for arbitrary strings to avoid type issues.
# Let's wrap it in freeform just like we do for numbers/bare words.
# But wait, val already has quotes. So val is "\"foo\"".
# freeform expects a string. so (freeform "\"foo\"") is correct?
# Actually (freeform "foo") is probably what we want if we strip quotes?
# No, freeform value is written AS IS to .config.
# So if .config has CONFIG_FOO="bar", we want freeform "\"bar\"".
# So we keep the quotes in val.
nix_val="(freeform $val)"
else
# It's a number, hex, or bare word. Wrap in freeform.
nix_val="(freeform \"$val\")"
fi
# Output with mkForce
if [[ -z "${seen_keys[$nix_key]}" ]]; then
echo " $nix_key = lib.mkForce $nix_val;" >> "$OUTPUT_FILE"
seen_keys["$nix_key"]=1
fi
done < "$CONFIG_FILE"
# Close the attribute set
echo "}" >> "$OUTPUT_FILE"
echo "Generated $OUTPUT_FILE"
echo "Total options: $(grep -c '=' "$OUTPUT_FILE")"

View file

@ -0,0 +1,36 @@
#!/usr/bin/env bash
# Convert kernel config to Nix structuredExtraConfig format
# Reads the generated kernel-config and outputs disabled options
CONFIG_FILE="/home/ashie/nixos/hosts/nixos/kernel-config"
OUTPUT_FILE="/home/ashie/nixos/hosts/nixos/kernel-config.nix"
echo "Converting $CONFIG_FILE to structuredExtraConfig format..."
# Start the Nix attribute set
cat > "$OUTPUT_FILE" << 'EOF'
# Auto-generated from kernel-config
# Run scripts/convert-kernel-config.sh to regenerate
{ lib }:
with lib.kernel;
{
EOF
# Extract disabled options (lines that say "# CONFIG_XXX is not set")
grep "^# CONFIG_.*is not set" "$CONFIG_FILE" | while read -r line; do
# Extract config name from "# CONFIG_XXX is not set"
config_name=$(echo "$line" | sed 's/^# CONFIG_\(.*\) is not set$/\1/')
# Quote names that start with a number (invalid Nix syntax otherwise)
# Use mkForce to override NixOS defaults
if [[ "$config_name" =~ ^[0-9] ]]; then
echo " \"$config_name\" = lib.mkForce no;" >> "$OUTPUT_FILE"
else
echo " $config_name = lib.mkForce no;" >> "$OUTPUT_FILE"
fi
done
# Close the attribute set
echo "}" >> "$OUTPUT_FILE"
echo "Generated $OUTPUT_FILE"
echo "Total disabled options: $(grep -c '= no;' "$OUTPUT_FILE")"

38
scripts/launch-vpn-app.sh Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env bash
# Check if running as root
if [ "$EUID" -ne 0 ]; then
# Re-run as root, preserving environment
# doas automatically preserves some env, allowing specific ones if configured,
# but for simplicity we rely on the internal command to handle env variables.
exec doas "$0" "$@"
fi
NAMESPACE="vpn"
USER="ashie" # Hardcoded for now, could be dynamic
# Check if namespace exists
if ! ip netns list | grep -q "$NAMESPACE"; then
echo "Error: Network namespace '$NAMESPACE' does not exist."
echo "Ensure vpn-netns.service is running."
exit 1
fi
COMMAND="$@"
if [ -z "$COMMAND" ]; then
echo "Usage: $0 <command> [args...]"
exit 1
fi
# Execute in namespace as the user
# We use `doas -u $USER` INSIDE the namespace to drop back to user privileges
# We MUST explicitly pass environment variables because doas cleans them.
# The bwrapper needs HOME, XDG_RUNTIME_DIR, etc. to function correctly.
exec ip netns exec "$NAMESPACE" doas -u "$USER" env \
HOME="/home/$USER" \
USER="$USER" \
XDG_RUNTIME_DIR="/run/user/$(id -u $USER)" \
WAYLAND_DISPLAY="$WAYLAND_DISPLAY" \
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u $USER)/bus" \
$COMMAND

71
scripts/migrate_steam.sh Executable file
View file

@ -0,0 +1,71 @@
#!/usr/bin/env bash
set -e
# Configuration
SOURCE_DIR="/games"
TARGET_MOUNT="/mnt/new_steam"
BTRFS_ROOT_MOUNT="/mnt/btrfs_root"
DEVICE="/dev/mapper/cryptdata"
SUBVOL_NAME="@steam"
USER_OWNER="ashie"
GROUP_OWNER="users"
# Ensure we are running with doas or root
if [ "$EUID" -ne 0 ]; then
echo "Please run this script with doas: doas $0"
exit 1
fi
echo "Starting Steam migration..."
# 1. Mount Btrfs root
mkdir -p "$BTRFS_ROOT_MOUNT"
echo "Mounting btrfs root..."
mount -o subvolid=5 "$DEVICE" "$BTRFS_ROOT_MOUNT"
# 2. Create subvolume
if [ -d "$BTRFS_ROOT_MOUNT/$SUBVOL_NAME" ]; then
echo "Subvolume $SUBVOL_NAME already exists."
else
echo "Creating subvolume $SUBVOL_NAME..."
btrfs subvolume create "$BTRFS_ROOT_MOUNT/$SUBVOL_NAME"
fi
# 3. Mount new subvolume
mkdir -p "$TARGET_MOUNT"
echo "Mounting new subvolume to $TARGET_MOUNT..."
mount -o subvol="$SUBVOL_NAME" "$DEVICE" "$TARGET_MOUNT"
# 4. Copy files with reflink (instant copy)
echo "Copying files from $SOURCE_DIR to $TARGET_MOUNT..."
shopt -s dotglob
for item in "$SOURCE_DIR"/*; do
name=$(basename "$item")
case "$name" in
"3DS"|"Switch"|"battlenet")
echo "Skipping $name"
;;
*)
echo "Moving $name..."
cp --reflink=always -r "$item" "$TARGET_MOUNT/"
;;
esac
done
# 5. Set permissions
echo "Setting permissions..."
chown -R "$USER_OWNER":"$GROUP_OWNER" "$TARGET_MOUNT"
# 6. Unmount
echo "Unmounting..."
umount "$TARGET_MOUNT"
umount "$BTRFS_ROOT_MOUNT"
rmdir "$TARGET_MOUNT" "$BTRFS_ROOT_MOUNT"
echo "Migration data copy complete."
echo "Please verify the contents if possible."
echo ""
echo "NEXT STEPS:"
echo "1. Run 'nixos-rebuild switch' to apply the new hardware-configuration.nix changes."
echo "2. Once verified, you can manually delete the old files in /games to free up space (the space is currently shared via reflink, so deleting won't free space until the old refs are gone, but it cleans up the folder view)."
echo " Example: doas rm -rf /games/steamfiles..."

View file

@ -13,6 +13,11 @@ hashed_password: ENC[AES256_GCM,data:s8ADA68VHHZwGEuYsCw0J0/fNlaZ+7W2PSKckGM/cAc
pstream_tmdb_api_key: ENC[AES256_GCM,data:bh+jCUiAAyFOpP0EOe/6vDnUQvC9HURG/2oIU2mIbQNo0lNXP5pFy2hE/9ys2DMnnTvopkMLNu4wGyjXuxLMiJtIrq0Wv7kmH0dVmIXeAwQoa8j8QbU2OWuaHambq0sIxY6+UQJo9lhz88uEtys9zDvKDi3sn4JQREvHnCnVljeGQJnXCAALSgFdzhyU2Zy9fX9kyGPkUu7WA1ZBw0JjGjvxSoYcFJZmG5t2J1rRv6gxVcDvOxddkugoZ4Q4d0Fkac+ybAvqGaqy6m/C5FJ5zYUth88wqppB9SUm6XigliRWrUtTT+WrNoRPXusc,iv:uueZ41EkhJOVuC+xfGFORlWKrandTAM3KN/4PxRDwz0=,tag:DbywbqDgWCvsuo21XwDtmQ==,type:str] pstream_tmdb_api_key: ENC[AES256_GCM,data:bh+jCUiAAyFOpP0EOe/6vDnUQvC9HURG/2oIU2mIbQNo0lNXP5pFy2hE/9ys2DMnnTvopkMLNu4wGyjXuxLMiJtIrq0Wv7kmH0dVmIXeAwQoa8j8QbU2OWuaHambq0sIxY6+UQJo9lhz88uEtys9zDvKDi3sn4JQREvHnCnVljeGQJnXCAALSgFdzhyU2Zy9fX9kyGPkUu7WA1ZBw0JjGjvxSoYcFJZmG5t2J1rRv6gxVcDvOxddkugoZ4Q4d0Fkac+ybAvqGaqy6m/C5FJ5zYUth88wqppB9SUm6XigliRWrUtTT+WrNoRPXusc,iv:uueZ41EkhJOVuC+xfGFORlWKrandTAM3KN/4PxRDwz0=,tag:DbywbqDgWCvsuo21XwDtmQ==,type:str]
pstream_jwt_secret: ENC[AES256_GCM,data:jW81qa96mTaCrGvZOZ3t5eVrUk6H78db5Q1kCd1/u9C0oi8MYFzTY7nH4GaYpkhIbfd65ozDOx78y9G71IbFbg==,iv:tPKT4GlttwtVn43ZpDoNMdSFP4AsqAYdL+hRnN88vLY=,tag:wANFe22Vliabmbb9NKsmDA==,type:str] pstream_jwt_secret: ENC[AES256_GCM,data:jW81qa96mTaCrGvZOZ3t5eVrUk6H78db5Q1kCd1/u9C0oi8MYFzTY7nH4GaYpkhIbfd65ozDOx78y9G71IbFbg==,iv:tPKT4GlttwtVn43ZpDoNMdSFP4AsqAYdL+hRnN88vLY=,tag:wANFe22Vliabmbb9NKsmDA==,type:str]
pstream_postgres_password: ENC[AES256_GCM,data:X00fVgOG+1o6NomujERC30ifp3cRrSIQ5LttgIaFXwPHJb0oXRTE//gHnS46hlKSoZYc9Vz1RQ0ecDOW9bmvWQ==,iv:JHfjowWFUS5CVZ0MgFtAjWuZJxmgQFpYYhUBOWb2ob0=,tag:Raj+yNEkojAnHKTN1Ti3uQ==,type:str] pstream_postgres_password: ENC[AES256_GCM,data:X00fVgOG+1o6NomujERC30ifp3cRrSIQ5LttgIaFXwPHJb0oXRTE//gHnS46hlKSoZYc9Vz1RQ0ecDOW9bmvWQ==,iv:JHfjowWFUS5CVZ0MgFtAjWuZJxmgQFpYYhUBOWb2ob0=,tag:Raj+yNEkojAnHKTN1Ti3uQ==,type:str]
searxng_secret_key: ENC[AES256_GCM,data:eFsJko9dEva9IlBCF+YCCj7j6HYi1dUqkOrDBTxiixNfGgu0FakujOyiyDGOdzrTE7j6Q6RVZ2pGG7/Xl21YtQ==,iv:k7hEaTdDvdFzQMWmFVbUrSIm1fLIc0qq3vdasJZlIlk=,tag:dhi4JP8FQLcdTuUR6mhZMw==,type:str]
nixflix_password: ENC[AES256_GCM,data:oBAbEFJnDhOPkAAZ5TR/hQjBH0YTmfmHbZ78mLRjUs+RcFD0Uw3k80LNrmB3qpnq8NJwazPRg39ukTh5HDU7Gz9D1/DlypOfk0qjKrfVY5IYhyBs+v8B3tsZX0StcGK/74BzMxtT8ahI8dU/glaetcRQKz90PUnHHkUeAJZIkg==,iv:Y7sATA/v3q0Z4AH5BN/xbEzxA4jIa81ooJx7LVWg3e0=,tag:jtwgs5pY25vek7XTVSzRvQ==,type:str]
sonarr_api_key: ENC[AES256_GCM,data:bANmRK6E65/YoxBdCAWrZRLlHNcUweNIv502PPXGRdk=,iv:7xTfpNBwCMJTbIP+cAqN1XsLGtl/evulq79tLSMRYkQ=,tag:sq/2kWMNkrtheYEOsKSYPA==,type:str]
radarr_api_key: ENC[AES256_GCM,data:bGaBbRm9SKXPkMvDS2/3JzCoMfhRQPdXMN6V3ILL2nU=,iv:tWT8Bf/Ae4NKdsKEzN1iEMdj+nGMO6XScs2LoGl9Drs=,tag:JgbILcdC7KmNuzw1Kr1P3A==,type:str]
prowlarr_api_key: ENC[AES256_GCM,data:jONkYK9GNrN9+R/0SSNGAP8VrUi3QU1XwUakkrmLbhk=,iv:qSswJCOejpXiHbdW+2on7duP8eaUB6ToRjeAO0FusuQ=,tag:726JkJmCP0AsFc+Cm9luIg==,type:str]
sops: sops:
age: age:
- recipient: age1g76q4cec3qykmkzrd6f4fxxpafj5fsut4jk7pklweuff97scpuusnwdknu - recipient: age1g76q4cec3qykmkzrd6f4fxxpafj5fsut4jk7pklweuff97scpuusnwdknu
@ -33,7 +38,7 @@ sops:
cVlpL1pxTFN3d1llbEhiNzlCcDV6NzAK6RlVB106woOkrmlINKB5hjoQs8CBfMAI cVlpL1pxTFN3d1llbEhiNzlCcDV6NzAK6RlVB106woOkrmlINKB5hjoQs8CBfMAI
nAjTYfHW0h4PznY0JpWfeNaVRD4EbDwbE2m8X6OzQEWJJB1WESw4Zg== nAjTYfHW0h4PznY0JpWfeNaVRD4EbDwbE2m8X6OzQEWJJB1WESw4Zg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2026-01-12T13:21:54Z" lastmodified: "2026-01-19T19:08:13Z"
mac: ENC[AES256_GCM,data:oYMO342I9EWOIeFxGxCKYVxKrfACdm9/8z8dnmaC2E97mMNhbuoxid7W6g7GgE5Iz6Xlo0paARim43wrmFAnT6U0YlEKdDkducZtVaxc3mCGwbVaGL1E9ErhZBBWFQoF+GGgeB8Co0TbB1Ox5VeRdPzz4diJkPiwsXVGlSCofU8=,iv:UpCOtVwvYrk5kXChUo/g34ZvjxHkTK9r0LTv9Dag6iM=,tag:XBlvehU8xKWkV2zcMNFPpw==,type:str] mac: ENC[AES256_GCM,data:7k41gGei0vW/Hh7RnB4drkXDBlVQmbZULrZnEevLhNQMkeE3f01EGcknzDdLDcmcV5AbZka75aJKE68wypfDRBv7JiT9yG/5PH5he7NONZ47Im40f0zwwT5A2SGOvwS8A37t0DxrGGxmF2IGK6o3PDSnPtsog05juXXKd3TzOwo=,iv:gwW3z9SDF9Cj0XAn+E/7+GMvaAWcNiTB+NZffPpWcK4=,tag:LpNRT5Cown0u8+ngbrN/Lg==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.11.0 version: 3.11.0

View file

@ -10,6 +10,7 @@
device = "nodev"; device = "nodev";
useOSProber = false; useOSProber = false;
configurationLimit = 10; configurationLimit = 10;
gfxmodeEfi = "auto";
}; };
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
boot.loader.timeout = 5; boot.loader.timeout = 5;

View file

@ -22,7 +22,7 @@
fsType = "none"; fsType = "none";
options = [ options = [
"bind" "bind"
"X-systemd.after=games.mount" "x-systemd.after=games.mount"
]; ];
}; };
} }

View file

@ -1,6 +1,7 @@
{ {
config, config,
pkgs, pkgs,
lib,
inputs, inputs,
... ...
}: }:
@ -11,7 +12,7 @@
# Use CachyOS Kernel # Use CachyOS Kernel
boot.kernelPackages = boot.kernelPackages =
pkgs.linuxPackagesFor pkgs.linuxPackagesFor
inputs.nix-cachyos-kernel.packages.${pkgs.system}.linux-cachyos-latest; inputs.nix-cachyos-kernel.packages.${pkgs.system}.linux-cachyos-bore-lto;
# ============================================================================= # =============================================================================
# DEFAULT BOOT: Linux Desktop Mode (GPU for Host) # DEFAULT BOOT: Linux Desktop Mode (GPU for Host)
@ -30,6 +31,9 @@
"tcp_bbr" "tcp_bbr"
"vendor-reset" "vendor-reset"
"ntsync" "ntsync"
"wireguard"
"af_packet"
"bridge"
]; ];
# ============================================================================= # =============================================================================

View file

@ -20,6 +20,11 @@
Name = "br0"; Name = "br0";
}; };
links."10-eth" = {
matchConfig.Name = "enp4s0";
linkConfig.MACAddressPolicy = "random";
};
networks."10-eth" = { networks."10-eth" = {
matchConfig.Name = "enp4s0"; matchConfig.Name = "enp4s0";
networkConfig.Bridge = "br0"; networkConfig.Bridge = "br0";
@ -45,7 +50,8 @@
}; };
# Basic firewall settings (Cloudflare rules are in the module) # Basic firewall settings (Cloudflare rules are in the module)
networking.firewall.enable = false; # networking.firewall.enable = true; # Handled by modules/system/cloudflare-firewall.nix
networking.nftables.enable = true;
# Dynamic DNS for Cloudflare # Dynamic DNS for Cloudflare
services.ddclient = { services.ddclient = {
@ -59,6 +65,14 @@
"chat.ashisgreat.xyz" "chat.ashisgreat.xyz"
"stream.ashisgreat.xyz" "stream.ashisgreat.xyz"
"stream-api.ashisgreat.xyz" "stream-api.ashisgreat.xyz"
"sonarr.ashisgreat.xyz"
"radarr.ashisgreat.xyz"
"prowlarr.ashisgreat.xyz"
"torrent.ashisgreat.xyz"
"jellyfin.ashisgreat.xyz"
"jellyseer.ashisgreat.xyz"
"jellyseerr.ashisgreat.xyz"
"search.ashisgreat.xyz"
]; ];
interval = "10min"; interval = "10min";
usev6 = "disabled"; usev6 = "disabled";

View file

@ -34,7 +34,7 @@
git git
sbctl sbctl
fuzzel fuzzel
prismlauncher-sandboxed # prismlauncher-sandboxed # Managed by Home Manager
polychromatic polychromatic
vscodium vscodium
kdePackages.dolphin kdePackages.dolphin
@ -107,6 +107,7 @@
openssl openssl
nspr nspr
firefox-sandboxed firefox-sandboxed
tutanota-sandboxed
brave-sandboxed brave-sandboxed
eddie eddie
appimage-run appimage-run

View file

@ -10,7 +10,7 @@
sops.defaultSopsFormat = "yaml"; sops.defaultSopsFormat = "yaml";
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.age.keyFile = "/home/ashie/.config/sops/age/keys.txt"; # sops.age.keyFile = "/home/ashie/.config/sops/age/keys.txt";
# WireGuard / Gluetun secrets # WireGuard / Gluetun secrets
sops.secrets.wireguard_private_key = { sops.secrets.wireguard_private_key = {
owner = "ashie"; owner = "ashie";
@ -41,6 +41,12 @@
WIREGUARD_PUBLIC_KEY=${config.sops.placeholder.wireguard_public_key} WIREGUARD_PUBLIC_KEY=${config.sops.placeholder.wireguard_public_key}
WIREGUARD_ENDPOINT_IP=${config.sops.placeholder.wireguard_endpoint_ip} WIREGUARD_ENDPOINT_IP=${config.sops.placeholder.wireguard_endpoint_ip}
WIREGUARD_ENDPOINT_PORT=${config.sops.placeholder.wireguard_endpoint_port} WIREGUARD_ENDPOINT_PORT=${config.sops.placeholder.wireguard_endpoint_port}
WIREGUARD_PRIVATE_KEY=${config.sops.placeholder.wireguard_private_key}
WIREGUARD_ADDRESSES=${config.sops.placeholder.wireguard_addresses}
WIREGUARD_PRESHARED_KEY=${config.sops.placeholder.wireguard_preshared_key}
WIREGUARD_MTU=1320
VPN_SERVICE_PROVIDER=custom
VPN_TYPE=wireguard
''; '';
}; };

View file

@ -5,7 +5,12 @@
... ...
}: }:
{ {
services.flatpak.enable = true; services.flatpak.enable = false;
services.snowflake-proxy = {
enable = true;
capacity = 10;
};
services.timesyncd.enable = false; services.timesyncd.enable = false;
services.chrony = { services.chrony = {
@ -46,6 +51,9 @@
settings = { settings = {
PasswordAuthentication = false; PasswordAuthentication = false;
PermitRootLogin = "no"; PermitRootLogin = "no";
X11Forwarding = false;
AllowAgentForwarding = false;
UseDns = false;
}; };
}; };
@ -70,35 +78,47 @@
globalConfig = '' globalConfig = ''
acme_dns cloudflare {env.CF_API_TOKEN} acme_dns cloudflare {env.CF_API_TOKEN}
servers { servers {
protocols h1 h2 protocols h1 h2 h3
} }
''; '';
virtualHosts."api.ashisgreat.xyz" = { extraConfig = ''
extraConfig = '' (security_headers) {
# Security headers
header { header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff" X-Content-Type-Options "nosniff"
X-Frame-Options "DENY" X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin" Referrer-Policy "strict-origin-when-cross-origin"
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:;" X-XSS-Protection "1; mode=block"
Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
-Server -Server
} }
}
'';
virtualHosts."search.ashisgreat.xyz" = {
extraConfig = ''
import security_headers
reverse_proxy 127.0.0.1:8888
'';
};
virtualHosts."api.ashisgreat.xyz" = {
extraConfig = ''
import security_headers
header {
X-Frame-Options "DENY"
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:;"
}
reverse_proxy 127.0.0.1:8045 reverse_proxy 127.0.0.1:8045
''; '';
}; };
virtualHosts."chat.ashisgreat.xyz" = { virtualHosts."chat.ashisgreat.xyz" = {
extraConfig = '' extraConfig = ''
# Security headers import security_headers
header { header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: blob:; font-src 'self' data:; connect-src 'self' wss: https:; worker-src 'self' blob:;" Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: blob:; font-src 'self' data:; connect-src 'self' wss: https:; worker-src 'self' blob:;"
-Server
} }
reverse_proxy 127.0.0.1:3000 reverse_proxy 127.0.0.1:3000
''; '';
@ -106,37 +126,72 @@
virtualHosts."stream.ashisgreat.xyz" = { virtualHosts."stream.ashisgreat.xyz" = {
extraConfig = '' extraConfig = ''
# Basic Auth import security_headers
basic_auth { basic_auth {
admin $2a$14$2kaAS6oLx6SdyuM2lksnYOZidfRWb7AGPXT5hhg/s5nseL7bjHsx2 admin $2a$14$2kaAS6oLx6SdyuM2lksnYOZidfRWb7AGPXT5hhg/s5nseL7bjHsx2
} }
# Security headers
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
reverse_proxy 127.0.0.1:3333 reverse_proxy 127.0.0.1:3333
''; '';
}; };
virtualHosts."stream-api.ashisgreat.xyz" = { virtualHosts."stream-api.ashisgreat.xyz" = {
extraConfig = '' extraConfig = ''
# Security headers import security_headers
header { header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
# Backend API needs to be accessible by frontend
Access-Control-Allow-Origin "https://stream.ashisgreat.xyz" Access-Control-Allow-Origin "https://stream.ashisgreat.xyz"
-Server
} }
reverse_proxy 127.0.0.1:3334 reverse_proxy 127.0.0.1:3334
''; '';
}; };
virtualHosts."sonarr.ashisgreat.xyz" = {
extraConfig = ''
import security_headers
reverse_proxy 127.0.0.1:8989
'';
};
virtualHosts."radarr.ashisgreat.xyz" = {
extraConfig = ''
import security_headers
reverse_proxy 127.0.0.1:7878
'';
};
virtualHosts."prowlarr.ashisgreat.xyz" = {
extraConfig = ''
import security_headers
reverse_proxy 127.0.0.1:9696
'';
};
virtualHosts."torrent.ashisgreat.xyz" = {
extraConfig = ''
import security_headers
reverse_proxy 127.0.0.1:8080
'';
};
virtualHosts."jellyfin.ashisgreat.xyz" = {
extraConfig = ''
import security_headers
reverse_proxy 127.0.0.1:8096
'';
};
virtualHosts."jellyseer.ashisgreat.xyz" = {
extraConfig = ''
import security_headers
reverse_proxy 127.0.0.1:5055
'';
};
virtualHosts."jellyseerr.ashisgreat.xyz" = {
extraConfig = ''
redir https://jellyseer.ashisgreat.xyz{uri}
'';
};
}; };
# Hardening for Chrony # Hardening for Chrony
@ -179,4 +234,33 @@
}; };
systemd.services.caddy.serviceConfig.EnvironmentFile = config.sops.templates."caddy.env".path; systemd.services.caddy.serviceConfig.EnvironmentFile = config.sops.templates."caddy.env".path;
# Hardening for Snowflake Proxy
systemd.services.snowflake-proxy.serviceConfig = {
DynamicUser = true;
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectKernelTunables = true;
ProtectControlGroups = true;
ProtectKernelModules = true;
MemoryDenyWriteExecute = true;
LockPersonality = true;
RestrictRealtime = true;
SystemCallFilter = [ "@system-service" "~@privileged" ];
};
# Hardening for DDClient
systemd.services.ddclient.serviceConfig = {
ProtectSystem = "full";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectKernelTunables = true;
ProtectControlGroups = true;
ProtectKernelModules = true;
ReadWritePaths = [ "/run/ddclient" ];
NoNewPrivileges = true;
};
} }

View file

@ -18,6 +18,7 @@
"podman" "podman"
"render" "render"
"video" "video"
"media"
]; ];
packages = with pkgs; [ packages = with pkgs; [
tree tree
@ -45,13 +46,13 @@
subUidRanges = [ subUidRanges = [
{ {
startUid = 100000; startUid = 100000;
count = 100000000; count = 65536;
} }
]; ];
subGidRanges = [ subGidRanges = [
{ {
startGid = 100000; startGid = 100000;
count = 100000000; count = 65536;
} }
]; ];
}; };
@ -71,13 +72,13 @@
subUidRanges = [ subUidRanges = [
{ {
startUid = 200000; startUid = 200000;
count = 100000000; count = 65536;
} }
]; ];
subGidRanges = [ subGidRanges = [
{ {
startGid = 200000; startGid = 200000;
count = 100000000; count = 65536;
} }
]; ];
}; };

114
system/vpn-namespace.nix Normal file
View file

@ -0,0 +1,114 @@
{
config,
lib,
pkgs,
...
}:
{
# Ensure iproute2 is available
environment.systemPackages = [ pkgs.iproute2 ];
systemd.services.vpn-netns = {
description = "VPN Network Namespace Setup";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
requiredBy = [ "multi-user.target" ];
path = [
pkgs.iproute2
pkgs.wireguard-tools
pkgs.kmod
];
script = ''
# 1. Create Namespace if not exists
if ! ip netns list | grep -q "vpn"; then
ip netns add vpn
fi
# 2. Cleanup & Create WireGuard Interface
# Delete if exists INSIDE namespace (from previous run)
ip netns exec vpn ip link delete wg0 2>/dev/null || true
# Delete if exists in default namespace
ip link delete wg0 2>/dev/null || true
ip link add wg0 type wireguard
ip link set mtu 1320 dev wg0
# 3. Move to Namespace
ip link set wg0 netns vpn
# 4. Configure WireGuard (INSIDE NAMESPACE)
# We read secrets from the sops-rendered files
PRIVATE_KEY=$(cat ${config.sops.secrets.wireguard_private_key.path})
PEER_KEY=$(cat ${config.sops.secrets.wireguard_public_key.path})
ENDPOINT_IP=$(cat ${config.sops.secrets.wireguard_endpoint_ip.path})
ENDPOINT_PORT=$(cat ${config.sops.secrets.wireguard_endpoint_port.path})
ADDRESS=$(cat ${config.sops.secrets.wireguard_addresses.path})
PRESHARED_KEY=$(cat ${config.sops.secrets.wireguard_preshared_key.path})
# Pass private key via stdin to file
echo "$PRIVATE_KEY" > /run/wg0.key
chmod 600 /run/wg0.key
# Setup interface inside netns
ip netns exec vpn wg set wg0 \
private-key /run/wg0.key \
peer "$PEER_KEY" \
preshared-key <(echo "$PRESHARED_KEY") \
endpoint "$ENDPOINT_IP:$ENDPOINT_PORT" \
allowed-ips 0.0.0.0/0
rm /run/wg0.key
# Assign IP Address
ip netns exec vpn ip addr add "$ADDRESS" dev wg0
# Set MTU (Optimized for VPN to avoid fragmentation)
ip netns exec vpn ip link set mtu 1320 dev wg0
# Bring Up
ip netns exec vpn ip link set wg0 up
ip netns exec vpn ip link set lo up
# Set Default Route
ip netns exec vpn ip route add default dev wg0
# 5. DNS (Optional - force Google/Cloudflare inside namespace)
mkdir -p /etc/netns/vpn
echo "nameserver 1.1.1.1" > /etc/netns/vpn/resolv.conf
'';
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
User = "root";
};
};
# Allow user 'ashie' to run the namespace launcher without password
security.doas.extraRules = [
{
users = [ "ashie" ];
cmd = "/run/current-system/sw/bin/ip";
args = [
"netns"
"exec"
"vpn"
"doas"
"-u"
"ashie"
"--"
]; # Permit the specific chain
noPass = true;
}
# Allow running the script itself
{
users = [ "ashie" ];
cmd = "/home/ashie/nixos/scripts/launch-vpn-app.sh";
noPass = true;
keepEnv = true;
}
];
}