This commit is contained in:
ashisgreat22 2026-01-31 20:11:19 +01:00
parent 57dafa4d25
commit 7529c0c5c4
15 changed files with 291 additions and 302 deletions

132
flake.lock generated
View file

@ -3,11 +3,11 @@
"cachyos-kernel": {
"flake": false,
"locked": {
"lastModified": 1768669154,
"narHash": "sha256-n9peTL7TAv1FIsboTEE1nWvuY2HYB67Jhh8o4O/JGfY=",
"lastModified": 1769435645,
"narHash": "sha256-xxIqw5x8U+13ya2BUcwmAW6BdpCpMhrMTn6Pd0bzocE=",
"owner": "CachyOS",
"repo": "linux-cachyos",
"rev": "4d7506c820f0d18fc0bbc36ecfec8ed126aee682",
"rev": "e8675eeb9b48a23167b3e43f84e3be76e321935e",
"type": "github"
},
"original": {
@ -19,11 +19,11 @@
"cachyos-kernel-patches": {
"flake": false,
"locked": {
"lastModified": 1768668945,
"narHash": "sha256-XKQ3DHUnaa/00BfIaY6K8xCZgx0Sy2wXQbNYE/AmWSk=",
"lastModified": 1769587384,
"narHash": "sha256-fPOlnH9arzQLmkbaZ6p+otwLuH9YEf/t8Q2o9/Yq/YA=",
"owner": "CachyOS",
"repo": "kernel-patches",
"rev": "cba022ec33a81d60a1e2c9fe4622196e3fef2b54",
"rev": "5f061ab9733ad15eccf6b9995e9d56f572e67266",
"type": "github"
},
"original": {
@ -37,11 +37,11 @@
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1768575137,
"narHash": "sha256-e0SsKnkSnq+UwZNS9ZyPJjTjabzq9TRc1hqeDnvOF1Q=",
"lastModified": 1769432988,
"narHash": "sha256-q4arZjXnLiuMnLzO972lrXIGdzyGb4DGaIt69CcCYdE=",
"owner": "catppuccin",
"repo": "nix",
"rev": "48e67b4ad22072f1ae30b0ed8e1cb020cf06c611",
"rev": "d7a8632c0d8d144478aac1a8c8d5083b770cbb03",
"type": "github"
},
"original": {
@ -53,11 +53,11 @@
"catppuccin-userstyles": {
"flake": false,
"locked": {
"lastModified": 1768598910,
"narHash": "sha256-GlhBDOcaNADurl6NrmNGFk4MTf5wpoilzj74JCb04rA=",
"lastModified": 1769478525,
"narHash": "sha256-V/5/yrwKJQldrzMW/lo42oOsceEcXFfsaFD1fHqeaGY=",
"owner": "catppuccin",
"repo": "userstyles",
"rev": "a705c3166765be722f0d33d34a411b4aa2663169",
"rev": "72d08a0e24318741866741d38148aea50b4083e5",
"type": "github"
},
"original": {
@ -92,11 +92,11 @@
},
"crane": {
"locked": {
"lastModified": 1767744144,
"narHash": "sha256-9/9ntI0D+HbN4G0TrK3KmHbTvwgswz7p8IEJsWyef8Q=",
"lastModified": 1769287525,
"narHash": "sha256-gABuYA6BzoRMLuPaeO5p7SLrpd4qExgkwEmYaYQY4bM=",
"owner": "ipetkov",
"repo": "crane",
"rev": "2fb033290bf6b23f226d4c8b32f7f7a16b043d7e",
"rev": "0314e365877a85c9e5758f9ea77a9972afbb4c21",
"type": "github"
},
"original": {
@ -202,11 +202,11 @@
]
},
"locked": {
"lastModified": 1765835352,
"narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=",
"lastModified": 1768135262,
"narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "a34fae9c08a15ad73f295041fec82323541400a9",
"rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac",
"type": "github"
},
"original": {
@ -283,11 +283,11 @@
]
},
"locked": {
"lastModified": 1768749864,
"narHash": "sha256-EKRMFBLBRCHrFZ5luX85RTnsN3b2q3FjZEi62vXwJBE=",
"lastModified": 1769638001,
"narHash": "sha256-hGwdJ/+oo+IRo2TiWV/V8BWWptQihcdFV/olTONaHqg=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "5148e08046dc8c74c66b8aee4d302a47d6931b56",
"rev": "bd9f031efc634be4b80c5090b9171cc3a9f8e49c",
"type": "github"
},
"original": {
@ -325,11 +325,11 @@
]
},
"locked": {
"lastModified": 1768749749,
"narHash": "sha256-LznsuRIp4RyjOy6EuHYbmgMx9MQ2lUSH3ymfNPE+O9w=",
"lastModified": 1769548169,
"narHash": "sha256-03+JxvzmfwRu+5JafM0DLbxgHttOQZkUtDWBmeUkN8Y=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "7d905a5a23f26b62c5b68129ef3780409088327a",
"rev": "7b1d382faf603b6d264f58627330f9faa5cba149",
"type": "github"
},
"original": {
@ -376,11 +376,11 @@
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1768307256,
"narHash": "sha256-3yDvlAqWa0Vk3B9hFRJJrSs1xc+FwVQFLtu//VrTR4c=",
"lastModified": 1769417433,
"narHash": "sha256-0WZ7I/N9InaBHL96/qdiJxg8mqFW3vRla8Z062JmQFE=",
"owner": "nix-community",
"repo": "lanzaboote",
"rev": "7e031eb535a494582f4fc58735b5aecba7b57058",
"rev": "1902463415745b992dbaf301b2a35a1277be1584",
"type": "github"
},
"original": {
@ -413,11 +413,11 @@
]
},
"locked": {
"lastModified": 1767822362,
"narHash": "sha256-rnpIDY/sy/uV+1dsW+MrFwAFE/RHg5K/6aa5k7Yt1Dc=",
"lastModified": 1769469790,
"narHash": "sha256-VJI4KvK2AWtjPdNqanQ43MUydnU9qwN+HTDXrAtS2bI=",
"owner": "utensils",
"repo": "mcp-nixos",
"rev": "9706014c1530ba12ff36ca8d9d1717b1e61d29db",
"rev": "af7b82497af2229893d0a5e4edaad4165f45eec7",
"type": "github"
},
"original": {
@ -450,11 +450,11 @@
"rust-overlay": "rust-overlay_2"
},
"locked": {
"lastModified": 1768678265,
"narHash": "sha256-Ub8eed4DsfIDWyg30xEe+8bSxL/z5Af/gCjmvJ0V/Hs=",
"lastModified": 1769577126,
"narHash": "sha256-v9vz9Rj4MGwPuhGELdvpRKl2HH+xvkgat6VwL0L86Fg=",
"owner": "YaLTeR",
"repo": "niri",
"rev": "d7184a04b904e07113f4623610775ae78d32394c",
"rev": "f30db163b5748e8cf95c05aba77d0d3736f40543",
"type": "github"
},
"original": {
@ -494,11 +494,11 @@
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1768697537,
"narHash": "sha256-+3arRjix3ZmBM7ijdB95tkmcuOTrLCIZba7up+YXihY=",
"lastModified": 1769623217,
"narHash": "sha256-GHpbWLiez3G54o9czW9zc4uy4h0/nMK3/ahMYmILqkY=",
"owner": "xddxdd",
"repo": "nix-cachyos-kernel",
"rev": "a9f4771d31a7fe8a74711b5a77bb77bfddc2d18b",
"rev": "03f574805ffe01b47e7fa93c7128d678b2037729",
"type": "github"
},
"original": {
@ -515,11 +515,11 @@
]
},
"locked": {
"lastModified": 1768817462,
"narHash": "sha256-F3aGIF05MLaTbzulCxLuhkTPHnia8zYL8GOPrAy5SY4=",
"lastModified": 1769570521,
"narHash": "sha256-o4crX1S+jsfytfy0liMr1NSnnVDdIOGoW3UTZXJG5PI=",
"owner": "kiriwalawren",
"repo": "nixflix",
"rev": "174a08001731d38cad88aa4b690ed047090ebfff",
"rev": "8037889b0be0275d1a96a4cc0a1d4aa878e2c82e",
"type": "github"
},
"original": {
@ -530,11 +530,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1768305791,
"narHash": "sha256-AIdl6WAn9aymeaH/NvBj0H9qM+XuAuYbGMZaP0zcXAQ=",
"lastModified": 1769018530,
"narHash": "sha256-MJ27Cy2NtBEV5tsK+YraYr2g851f3Fl1LpNHDzDX15c=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1412caf7bf9e660f2f962917c14b1ea1c3bc695e",
"rev": "88d3861acdd3d2f0e361767018218e51810df8a1",
"type": "github"
},
"original": {
@ -608,11 +608,11 @@
},
"nixpkgs_4": {
"locked": {
"lastModified": 1768640357,
"narHash": "sha256-NRmPViu76stpOUahRWuR3zMKfY2dKr/qAxRlcqfyps4=",
"lastModified": 1769607364,
"narHash": "sha256-bJIFB86xsMAJb0iEwb9p746T1XoslRAxbqMxBz7tjbo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d157866bc6cc1a986f88f6e78a6884efeeec6187",
"rev": "69459b3b3ea735e9933e1e367db3e68334cce3fe",
"type": "github"
},
"original": {
@ -624,11 +624,11 @@
},
"nixpkgs_5": {
"locked": {
"lastModified": 1768564909,
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
"lastModified": 1769461804,
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
"type": "github"
},
"original": {
@ -646,11 +646,11 @@
"systems": "systems_2"
},
"locked": {
"lastModified": 1768486009,
"narHash": "sha256-I7ymDe6UQooHy9I9wrafKCCDnRbox/EMWAgJgpm7fGs=",
"lastModified": 1769644746,
"narHash": "sha256-1X9o0GjCzku03magX4pM+1OZXA0aUTN7KvEReZ9t3OU=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "03a638205b5cb04ba9c2ed6c604e137b15f07fa1",
"rev": "3c27e1b35ca0fee6a89bfc20840654361ffe888d",
"type": "github"
},
"original": {
@ -666,11 +666,11 @@
]
},
"locked": {
"lastModified": 1768757767,
"narHash": "sha256-/z02Cp48mTQBh77DU2c0QefO048a3LHsXtINI/8Vuyc=",
"lastModified": 1769684048,
"narHash": "sha256-KoMHkgsxan9c6JwTuuKSAQBg947zTs+GdjlH9hquccM=",
"owner": "noctalia-dev",
"repo": "noctalia-shell",
"rev": "e24582770e0b422adeacd2da2254235dc489a691",
"rev": "7bf3dad98949c4895f15cdc4a7412b52e7d689ea",
"type": "github"
},
"original": {
@ -729,11 +729,11 @@
]
},
"locked": {
"lastModified": 1767281941,
"narHash": "sha256-6MkqajPICgugsuZ92OMoQcgSHnD6sJHwk8AxvMcIgTE=",
"lastModified": 1769069492,
"narHash": "sha256-Efs3VUPelRduf3PpfPP2ovEB4CXT7vHf8W+xc49RL/U=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "f0927703b7b1c8d97511c4116eb9b4ec6645a0fa",
"rev": "a1ef738813b15cf8ec759bdff5761b027e3e1d23",
"type": "github"
},
"original": {
@ -750,11 +750,11 @@
]
},
"locked": {
"lastModified": 1768691866,
"narHash": "sha256-MvnxwwfyO4fwozHlMWC4vW8l5GVNuv2ojwWtFOk/fUg=",
"lastModified": 1769582933,
"narHash": "sha256-MUzapTJuDJjfeOMlC9V1aesAX9WjFNUvjkyMCBHIA7E=",
"owner": "PrismLauncher",
"repo": "PrismLauncher",
"rev": "e8b5d491545f181599aaba610e53196e658a8bf2",
"rev": "70cbbf5b07460524a14e661c1242cc51742e0937",
"type": "github"
},
"original": {
@ -793,11 +793,11 @@
]
},
"locked": {
"lastModified": 1768272338,
"narHash": "sha256-Tg/kL8eKMpZtceDvBDQYU8zowgpr7ucFRnpP/AtfuRM=",
"lastModified": 1769309768,
"narHash": "sha256-AbOIlNO+JoqRJkK1VrnDXhxuX6CrdtIu2hSuy4pxi3g=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "03dda130a8701b08b0347fcaf850a190c53a3c1e",
"rev": "140c9dc582cb73ada2d63a2180524fcaa744fad5",
"type": "github"
},
"original": {
@ -834,11 +834,11 @@
]
},
"locked": {
"lastModified": 1768709255,
"narHash": "sha256-aigyBfxI20FRtqajVMYXHtj5gHXENY2gLAXEhfJ8/WM=",
"lastModified": 1769469829,
"narHash": "sha256-wFcr32ZqspCxk4+FvIxIL0AZktRs6DuF8oOsLt59YBU=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "5e8fae80726b66e9fec023d21cd3b3e638597aa9",
"rev": "c5eebd4eb2e3372fe12a8d70a248a6ee9dd02eff",
"type": "github"
},
"original": {

View file

@ -52,11 +52,11 @@
./system/secrets.nix # SOPS secrets
./system/compatibility.nix # Compatibility layers (nix-ld)
./system/game-drive.nix
./system/vpn.nix # System-wide VPN
./system/game-bypass.nix # Game bypass netns
#./system/authelia.nix # SSO/2FA
../../modules/nixos/media.nix # Arr Stack
../../modules/nixos/steam-gamemode.nix # Steam GameMode Session
../../modules/nixos/redlib.nix # Redlib private frontend
];
nixpkgs.config.allowUnfreePredicate =
@ -138,6 +138,7 @@
# Enable performance optimizations
myModules.performance.enable = true;
myModules.redlib.enable = true;
system.stateVersion = "25.05";
}

View file

@ -19,22 +19,4 @@
};
};
# Override Steam desktop entry to use bypass
xdg.desktopEntries.steam = {
name = "Steam";
genericName = "Application Store";
exec = "game-bypass steam %U";
terminal = false;
icon = "steam";
categories = [
"Network"
"FileTransfer"
"Game"
];
mimeType = [
"x-scheme-handler/steam"
"x-scheme-handler/steamlink"
];
prefetchIface = "steam";
};
}

View file

@ -89,6 +89,20 @@ let
antigravityFHSLauncher = pkgs.writeShellScriptBin "antigravity-fhs" ''
exec ${antigravityWrapped}/bin/antigravity "$@"
'';
# Helper to adapt VS Code extensions for Antigravity
# Home Manager expects extensions to be in share/antigravity/extensions based on the package name,
# but standard extensions are in share/vscode/extensions.
adaptToAntigravity = ext: pkgs.symlinkJoin {
name = "${ext.name}-antigravity";
paths = [ ext ];
# Ensure passthru attributes are preserved (though symlinkJoin usually handles this, specific ones might help)
inherit (ext) meta;
postBuild = ''
mkdir -p $out/share/antigravity
ln -sf ${ext}/share/vscode/extensions $out/share/antigravity/extensions
'';
};
in
{
home.packages = [
@ -118,7 +132,7 @@ in
enableExtensionUpdateCheck = false;
# Extensions from nixpkgs
extensions = with pkgs.vscode-extensions; [
extensions = map adaptToAntigravity (with pkgs.vscode-extensions; [
# Theme & Icons
catppuccin.catppuccin-vsc
catppuccin.catppuccin-vsc-icons
@ -160,7 +174,7 @@ in
# Formatters
esbenp.prettier-vscode
];
]);
# User settings (settings.json equivalent)
userSettings = {

View file

@ -1,108 +0,0 @@
{
config,
lib,
pkgs,
...
}:
{
# Namespace setup for Game Bypass
systemd.services.game-bypass-netns = {
description = "Game Bypass Network Namespace (Direct Internet)";
wants = [ "network.target" ];
after = [ "network.target" ];
requiredBy = [ "multi-user.target" ];
path = [
pkgs.iproute2
pkgs.kmod
pkgs.util-linux # for nsenter
pkgs.dhcpcd
];
script = ''
NAME="physical"
VETH_HOST="veth-game"
VETH_NS="eth0"
BRIDGE="br0"
# 1. Create Namespace if not exists
if ! ip netns list | grep -q "$NAME"; then
ip netns add "$NAME"
fi
# 2. Setup Veth Pair
# Cleanup previous
ip link delete "$VETH_HOST" 2>/dev/null || true
# Create pair
ip link add "$VETH_HOST" type veth peer name "$VETH_NS-tmp"
# Host side: Attach to Bridge
ip link set "$VETH_HOST" master "$BRIDGE"
ip link set "$VETH_HOST" up
# Client side: Move to NS
ip link set "$VETH_NS-tmp" netns "$NAME"
# 3. Configure Inside Namespace
# Rename to eth0
ip netns exec "$NAME" ip link set "$VETH_NS-tmp" name "$VETH_NS"
ip netns exec "$NAME" ip link set "$VETH_NS" up
ip netns exec "$NAME" ip link set lo up
# 4. DHCP
# Run dhcpcd inside the namespace
# We use -4 for IPv4 only if desired, or just standard
ip netns exec "$NAME" dhcpcd --nobackground "$VETH_NS" &
# 5. DNS (Use Google/Cloudflare directly)
mkdir -p /etc/netns/"$NAME"
echo "nameserver 1.1.1.1" > /etc/netns/"$NAME"/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/netns/"$NAME"/resolv.conf
'';
# We use oneshot to just launch dhcpcd
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
User = "root";
};
};
# Wrapper script to launch apps in the bypass
environment.systemPackages = [
(pkgs.writeShellScriptBin "game-bypass" ''
exec doas ip netns exec physical sudo -u ${config.users.users.ashie.name} -E -- "$@"
'')
];
# Security wrapper permissions
security.doas.extraRules = [
{
users = [ "ashie" ];
cmd = "/run/current-system/sw/bin/ip";
args = [
"netns"
"exec"
"physical"
"sudo"
"-u"
"ashie"
"-E"
"--"
];
noPass = true;
keepEnv = true;
}
];
# Also need sudo rules?
# "sudo -u ashie" inside the namespace might prompt for password if not configured.
# Usually user running sudo to switch to themselves needs no password if standard setup,
# OR we can just use setpriv/su if we are already root (which ip netns exec is).
# Wait, `ip netns exec` runs as root.
# So we are root inside the NS. We then drop privileges to 'ashie'.
# `sudo -u ashie` works fine if we are root.
}

View file

@ -90,6 +90,10 @@
locations."/" = {
proxyPass = "http://127.0.0.1:8888";
proxyWebsockets = true;
extraConfig = ''
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
'';
};
};
@ -229,6 +233,26 @@
forceSSL = true;
globalRedirect = "jellyseer.ashisgreat.xyz";
};
"reddit.ashisgreat.xyz" = {
useACMEHost = "ashisgreat.xyz";
forceSSL = true;
extraConfig = ''
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
'';
locations."/" = {
proxyPass = "http://127.0.0.1:8082";
proxyWebsockets = true;
extraConfig = ''
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
'';
};
};
};
# Hardening for Chrony

View file

@ -1,95 +0,0 @@
{
config,
lib,
pkgs,
...
}:
{
networking.wg-quick.interfaces = {
wg0 = {
address = [ "10.66.219.165/32" ]; # Fallback, should ideally come from secret but wg-quick needs it here or in config
# We will rely on the config file generation to include the address if possible,
# but nixos module usually requires 'address' or 'configFile'.
# Since we are using secrets for everything, we might need a script or careful usage of configFile.
# Better approach with sops: use the declarative config but read secrets from file for keys.
# However, 'address' usually isn't secret.
# In vpn-namespace.nix: ADDRESS=$(cat ${config.sops.secrets.wireguard_addresses.path})
# Valid approach for secrets in wg-quick:
# Use configFile pointing to a secret file, OR use normal config with privateKeyFile.
autostart = true;
dns = [ "1.1.1.1" ]; # Force DNS through VPN (or public DNS)
privateKeyFile = config.sops.secrets.wireguard_private_key.path;
peers = [
{
publicKey = "KPj/q9j/..."; # We need the public key here.
# PROB: The user's vpn-namespace.nix was reading PEER_KEY from a secret.
# NixOS wg-quick module expects publicKey as a string literal in the nix config, usually.
# If the peer public key is secret, we can't easily put it in nix store (it ends up world readable).
# BUT: Public keys are generally safe to be public.
# However, since the user has it in sops, they might want to keep it secret.
# ALTERNATIVE: Use `configFile` option and generate the whole config from secrets at runtime.
# But `networking.wg-quick.interfaces.<name>.configFile` expects a path.
# Let's write a script to generate the config file from secrets and start it.
# actually, the `networking.wg-quick` module is just a wrapper around systemd services.
# Let's try to stick to the module if possible.
# If we can't, we can write a systemd service just like vpn-namespace.nix but for the main netns.
}
];
};
};
# RE-EVALUATION:
# Since all WireGuard parameters (Addresses, Endpoint, Keys) are in sops secrets,
# trying to use `networking.wg-quick.interfaces` is clumsy because it expects static values for non-secrets.
# We should create a systemd service that constructs the config and runs wg-quick.
systemd.services.wg-quick-wg0 = {
description = "WireGuard Tunnel wg0";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
path = [
pkgs.wireguard-tools
pkgs.bash
];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = pkgs.writeShellScript "wg0-up" ''
# Generate Config
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})
cat > /run/wg0.conf <<EOF
[Interface]
Address = $ADDRESS
PrivateKey = $PRIVATE_KEY
DNS = 1.1.1.1
[Peer]
PublicKey = $PEER_KEY
PresharedKey = $PRESHARED_KEY
Endpoint = $ENDPOINT_IP:$ENDPOINT_PORT
AllowedIPs = 0.0.0.0/0
EOF
chmod 600 /run/wg0.conf
${pkgs.wireguard-tools}/bin/wg-quick up /run/wg0.conf
'';
ExecStop = "${pkgs.wireguard-tools}/bin/wg-quick down /run/wg0.conf";
};
};
}

View file

@ -58,6 +58,8 @@ in
};
# Runtime kernel hardening
boot.kernelModules = lib.mkIf cfg.enableZram [ "zram" ];
boot.kernelParams = [
"slab_nomerge"
"init_on_alloc=1"

View file

@ -99,9 +99,18 @@ in
# PipeWire + Pulse
''--bind "$XDG_RUNTIME_DIR/pipewire-0" "$XDG_RUNTIME_DIR/pipewire-0"''
''--bind "$XDG_RUNTIME_DIR/pulse" "$XDG_RUNTIME_DIR/pulse"''
# Hardware access
"--dev-bind /dev/dri /dev/dri"
"--dev-bind /dev/shm /dev/shm"
"--ro-bind /sys /sys"
# Bind system themes to /usr/share
"--ro-bind /run/current-system/sw/share/themes /usr/share/themes"
"--ro-bind /run/current-system/sw/share/icons /usr/share/icons"
# OpenGL/Vulkan drivers
"--ro-bind-try /run/opengl-driver /run/opengl-driver"
"--ro-bind-try /run/opengl-driver-32 /run/opengl-driver-32"
];
# Disable built-in DBus module (invokes bwrap without --unshare-user)

View file

@ -48,6 +48,7 @@ in
TZ = "Europe/Berlin";
DOT = "off"; # DNS over TLS off (optional)
FIREWALL_OUTBOUND_SUBNETS = "10.89.0.0/24"; # Allow access to local docker network
FIREWALL_VPN_INPUT_PORTS = "36630"; # Allow incoming torrent traffic
};
extraOptions = [
"--cap-add=NET_ADMIN"

63
modules/nixos/redlib.nix Normal file
View file

@ -0,0 +1,63 @@
# Redlib Module (Rootless Podman)
# Provides: Private Reddit frontend running in a rootless container
#
# Usage:
# myModules.redlib = {
# enable = true;
# port = 8082;
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.redlib;
in
{
options.myModules.redlib = {
enable = lib.mkEnableOption "Redlib private Reddit frontend";
port = lib.mkOption {
type = lib.types.port;
default = 8082;
description = "Port to expose Redlib on localhost";
};
};
config = lib.mkIf cfg.enable {
myModules.podman.enable = true;
# Redlib Container
virtualisation.oci-containers.containers."redlib" = {
image = "quay.io/redlib/redlib:latest";
# ports = [ "127.0.0.1:${toString cfg.port}:8080" ]; # Port exposed via VPN
extraOptions = [
"--pull=always"
"--cap-drop=ALL"
"--network=container:vpn"
];
dependsOn = [ "vpn" ];
};
# Rootless Overrides
systemd.services."podman-redlib".serviceConfig.User = lib.mkForce "ashie";
systemd.services."podman-redlib".environment = {
HOME = "/home/ashie";
XDG_RUNTIME_DIR = "/run/user/1000";
};
systemd.services."podman-redlib".serviceConfig.Type = lib.mkForce "simple";
systemd.services."podman-redlib".serviceConfig.Delegate = true;
systemd.services."podman-redlib".after = [
"user-runtime-dir@1000.service"
"podman-vpn.service"
];
systemd.services."podman-redlib".requires = [
"user-runtime-dir@1000.service"
"podman-vpn.service"
];
};
}

View file

@ -199,6 +199,25 @@ let
border-radius: 2em !important;
}
'';
anubisPolicy = pkgs.writeText "anubis-policy.yml" ''
bots:
- name: "Allow OpenSearch"
action: ALLOW
path_regex: ".*opensearch\\.xml.*"
- name: "Catch-All"
user_agent_regex: ".*"
action: CHALLENGE
'';
faviconsConfig = pkgs.writeText "favicons.toml" ''
[favicons]
cfg_schema = 1
[favicons.cache]
db_url = "/var/cache/searxng/faviconcache.db"
LIMIT_TOTAL_BYTES = 2147483648
'';
in
{
options.myModules.searxng = {
@ -236,11 +255,15 @@ in
serviceConfig.RemainAfterExit = true;
after = [ "user-runtime-dir@1000.service" ];
requires = [ "user-runtime-dir@1000.service" ];
path = [ pkgs.podman ];
path = [
pkgs.podman
pkgs.shadow
];
script = ''
export PATH=/run/wrappers/bin:$PATH
export XDG_RUNTIME_DIR="/run/user/1000"
export HOME="/home/ashie"
podman network create searxng-net --ignore
podman network create searxng-net --subnet 10.89.2.0/24 --ignore
'';
};
@ -263,8 +286,8 @@ in
# 3. SearXNG Container
virtualisation.oci-containers.containers."searxng" = {
image = "ghcr.io/searxng/searxng:latest";
ports = [ "127.0.0.1:${toString cfg.port}:8080" ];
image = "ghcr.io/privau/searxng:latest";
# ports = [ "127.0.0.1:${toString cfg.port}:8080" ]; # Port moved to Anubis
environment = {
"SEARXNG_BASE_URL" = "https://${cfg.domain}";
"SEARXNG_REDIS_URL" = "valkey://valkey:6379"; # Talk to Valkey via alias
@ -276,6 +299,7 @@ in
];
extraOptions = [
"--network=searxng-net"
"--network-alias=searxng"
"--cap-drop=ALL"
"--cap-add=CHOWN"
"--cap-add=SETGID"
@ -285,10 +309,41 @@ in
volumes = [
"${config.sops.templates."searxng_settings.yml".path}:/etc/searxng/settings.yml:ro"
"${catppuccinCss}:/etc/searxng/custom.css:ro"
"${faviconsConfig}:/etc/searxng/favicons.toml:ro"
"searxng-cache:/var/cache/searxng"
];
dependsOn = [ "searxng-valkey" ];
};
# 4. Anubis Container (AI Firewall)
virtualisation.oci-containers.containers."searxng-anubis" = {
image = "ghcr.io/techarohq/anubis:latest";
ports = [ "127.0.0.1:${toString cfg.port}:8080" ];
environment = {
"TARGET" = "http://searxng:8080";
"BIND" = ":8080";
"POLICY_FNAME" = "/etc/anubis/policy.yml";
};
extraOptions = [
"--network=searxng-net"
];
volumes = [
"${anubisPolicy}:/etc/anubis/policy.yml:ro"
];
dependsOn = [ "searxng" ];
};
# 5. Permanent NAT Fix for SearXNG Network
networking.nftables.tables.searxng-nat = {
family = "inet";
content = ''
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.89.2.0/24 masquerade
}
'';
};
sops.templates."searxng.env" = {
owner = "ashie";
content = ''
@ -310,9 +365,16 @@ in
lib.mapAttrsToList (name: url: "${name}: \"${url}\"") cfg.donations
)}
engines:
- name: brave
engine: brave
api_key: "${config.sops.placeholder.searxng_brave_api_key}"
tokens: ["${config.sops.placeholder.searxng_private_token}"]
search:
safe_search: 0
favicon_resolver: "duckduckgo"
autocomplete: "google"
default_lang: "en-US"
formats:
@ -327,18 +389,25 @@ in
image_proxy: true
ui:
default_theme: simple
default_theme_style: kagi
static_use_hash: true
custom_css: custom.css
theme_args:
simple_style: "auto"
# custom_css: custom.css
# theme_args:
# simple_style: kagi
hostname_replace:
'(^|.*\.)reddit\.com$': 'reddit.ashisgreat.xyz'
redis:
url: valkey://valkey:6379/0
'';
};
# Placeholder secret definition (User must add this to secrets.yaml!)
# Secret definitions
sops.secrets.searxng_secret_key = { };
sops.secrets.searxng_brave_api_key = { };
sops.secrets.searxng_private_token = { };
# Rootless Overrides
systemd.services."podman-searxng".serviceConfig.User = lib.mkForce "ashie";
@ -351,10 +420,12 @@ in
systemd.services."podman-searxng".after = [
"create-searxng-network.service"
"user-runtime-dir@1000.service"
"network-online.target"
];
systemd.services."podman-searxng".requires = [
"create-searxng-network.service"
"user-runtime-dir@1000.service"
"network-online.target"
];
systemd.services."podman-searxng-valkey".serviceConfig.User = lib.mkForce "ashie";
@ -367,10 +438,30 @@ in
systemd.services."podman-searxng-valkey".after = [
"create-searxng-network.service"
"user-runtime-dir@1000.service"
"network-online.target"
];
systemd.services."podman-searxng-valkey".requires = [
"create-searxng-network.service"
"user-runtime-dir@1000.service"
"network-online.target"
];
systemd.services."podman-searxng-anubis".serviceConfig.User = lib.mkForce "ashie";
systemd.services."podman-searxng-anubis".environment = {
HOME = "/home/ashie";
XDG_RUNTIME_DIR = "/run/user/1000";
};
systemd.services."podman-searxng-anubis".serviceConfig.Type = lib.mkForce "simple";
systemd.services."podman-searxng-anubis".serviceConfig.Delegate = true;
systemd.services."podman-searxng-anubis".after = [
"create-searxng-network.service"
"user-runtime-dir@1000.service"
"network-online.target"
];
systemd.services."podman-searxng-anubis".requires = [
"create-searxng-network.service"
"user-runtime-dir@1000.service"
"network-online.target"
];
};
}

View file

@ -36,7 +36,7 @@
fi
echo "Launching gamescope..."
exec ${pkgs.gamescope}/bin/gamescope -f -e -- game-bypass steam -gamepadui
exec ${pkgs.gamescope}/bin/gamescope -f -e -- steam -gamepadui
''}
Type=Application
'';

View file

@ -104,6 +104,9 @@ in
"$HOME/.local/share/Larian Studios"
"$HOME/Desktop"
"/games/steam"
"/games/windows/Modlist"
"/games/windows/Modlist_Downloads"
"$HOME/Games/windows/Modlist/Nordic"
];
};

View file

@ -21,6 +21,8 @@ prowlarr_api_key: ENC[AES256_GCM,data:jONkYK9GNrN9+R/0SSNGAP8VrUi3QU1XwUakkrmLbh
authelia_jwt_secret: ENC[AES256_GCM,data:3hNXsaKu+gk4YjPTQsvR43fhRgpwgsR8GsyalGnkOjPfBJ7KuuykYg/6xvvF1KM8pnlHgJNXznpeS1Jokjndbg==,iv:w+V2O6Kjq29D5h51Toj0Fgmq/GA0LgYWqESRAFOajq8=,tag:dCIZG1X8pVPJvZYkK5frBQ==,type:str]
authelia_session_secret: ENC[AES256_GCM,data:jNB1QBocUNZSljjgIrtgTtmDQKthuGY8Gv8/9jzY9c5s6HvUVNCACYBtfCgA7wN6XHinpO5Vlr5D6BFaTKLMiw==,iv:exBc+tfk2OC5c5HPSo1Qh95vzJqkYiErFokVPoPbErc=,tag:nxmUb+jThN58zuq8ebTqzw==,type:str]
authelia_storage_encryption_key: ENC[AES256_GCM,data:2ELisYBEh7rY+Jcfy5c2mBOvFUi6uYnTHtkMviOffqkIkSUmgc+43Kt2tQA7P97y6Tn8/1w/3jJjx/1voz3ojQ==,iv:85k4x8bMoaJEGz4JgyrpmcTJktGypQjK/2GUxIFymOc=,tag:cJTW6YwZTtoUQDSXnYS32A==,type:str]
searxng_brave_api_key: ENC[AES256_GCM,data:LgBCXW1jISajMWiZ7Miygv9TGjGImGP9TY7QLH4j1Q==,iv:r8E4dSjPofv+XFAsJFx3Z+y592tOOxWr0a/gGkJjPJw=,tag:1FHVfjvyvw7F5IOjQefySA==,type:str]
searxng_private_token: ENC[AES256_GCM,data:Jw2yKNEkCZM7XHSrmz9wynSacT2XszjzDULo61Aodw==,iv:+0SA5IxRA7e/fd5Umw5wlWZj3YaTVEvYX7Jc1WZmPxk=,tag:rsg4N6GEl4yPmRsYzFAjOA==,type:str]
sops:
age:
- recipient: age1g76q4cec3qykmkzrd6f4fxxpafj5fsut4jk7pklweuff97scpuusnwdknu
@ -41,7 +43,7 @@ sops:
cVlpL1pxTFN3d1llbEhiNzlCcDV6NzAK6RlVB106woOkrmlINKB5hjoQs8CBfMAI
nAjTYfHW0h4PznY0JpWfeNaVRD4EbDwbE2m8X6OzQEWJJB1WESw4Zg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-01-20T22:18:47Z"
mac: ENC[AES256_GCM,data:RJENwpgbopALD5EBsObfBF3gUijneA5aiqkUwQ8PRB8u2bvwTM/GoOGHYjr41f7kENQHJ8Q6gLkbBxBdLVrve1sYj2isOs1/A5sQxSFffkrdOtsHo18Mr18rmRC5sdJW6gOs9xUrsoUsxUs+mDbKowp8WfQxM/ALvOQatMYitWI=,iv:eEH4pmIA5JWHQy84l6B4Jyq1Cs8m/nX12tgNB52yNXc=,tag:piwqpJInnhH0VUvvO6iRhQ==,type:str]
lastmodified: "2026-01-29T18:21:33Z"
mac: ENC[AES256_GCM,data:k7C/t0INfl4bfUdrj81S2jbKjHGCP/W4+NeYXgzXrQ3mKD6myWNJW9j5Yh6WucFleV5uvk0IsH8zdUv/6F12fsCGRJ153Le8+LUZ400Co6toaLLIubLvC+mcUxqiXzSnGBUhjNH2jYNscBXtSSD+o2xUsyvs/vc5kqIv2tZzqHY=,iv:ef4nRzAaux9NEap87iphzOj3p1zPrvansBhq2v0w47o=,tag:HN0J/FlzWKg/ZoNvxYtRrg==,type:str]
unencrypted_suffix: _unencrypted
version: 3.11.0