Compare commits
4 commits
0de07cd804
...
6447486643
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6447486643 | ||
|
|
0f1a81c2aa | ||
|
|
5f70e8be94 | ||
|
|
749bfdf50d |
23 changed files with 1025 additions and 310 deletions
|
|
@ -1,7 +1,12 @@
|
||||||
keys:
|
keys:
|
||||||
- &root age1y0tj3kt67pfnj38t9c8g2ghry3a0mhcq8rrqv5xr4jekwepxaelqzu3dkf
|
- &root age1y0tj3kt67pfnj38t9c8g2ghry3a0mhcq8rrqv5xr4jekwepxaelqzu3dkf
|
||||||
- &user age16v8w7q4wmn22hhakq2uzaus2508rhldm7lcwh0kukshzjzyhuqesqz44ze
|
- &user age16v8w7q4wmn22hhakq2uzaus2508rhldm7lcwh0kukshzjzyhuqesqz44ze
|
||||||
|
- &sandbox age1mr42xh9llvrggrvuawr5253qk7gygf4gcg9clqdvjecw3d6tj59qsqxswd
|
||||||
creation_rules:
|
creation_rules:
|
||||||
|
- path_regex: microvm/secrets/sandbox\.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *sandbox
|
||||||
- path_regex: secrets/[^/]+\.yaml$
|
- path_regex: secrets/[^/]+\.yaml$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,6 @@
|
||||||
path = "/root/.ssh/desktop";
|
path = "/root/.ssh/desktop";
|
||||||
mode = "0600";
|
mode = "0600";
|
||||||
};
|
};
|
||||||
sops.secrets."deepseek_api_key" = {
|
|
||||||
owner = "agent";
|
|
||||||
};
|
|
||||||
nix.settings.experimental-features = [
|
nix.settings.experimental-features = [
|
||||||
"nix-command"
|
"nix-command"
|
||||||
"flakes"
|
"flakes"
|
||||||
|
|
@ -96,14 +93,16 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
ports = [ 22 ];
|
ports = [ 22 ];
|
||||||
settings = {
|
settings = {
|
||||||
PasswordAuthentication = false;
|
PasswordAuthentication = true;
|
||||||
KbdInteractiveAuthentication = false;
|
KbdInteractiveAuthentication = true;
|
||||||
PermitRootLogin = "no";
|
PermitRootLogin = "no";
|
||||||
AllowUsers = [
|
AllowUsers = [
|
||||||
"user"
|
"user"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ratbagd.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
hardware = {
|
hardware = {
|
||||||
|
|
@ -171,10 +170,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /home/public 2775 root public - -"
|
"d /home/user/dev 0770 user users -"
|
||||||
"d /home/public/pictures 2775 root public - -"
|
"d /home/user/pictures 0750 user users -"
|
||||||
|
|
||||||
"a+ /home/public - - - - d:g:public:rwX,d:m::rwX"
|
"a+ /home/user/dev - - - - d:g:users:rwX,d:m::rwX"
|
||||||
"a+ /home/public/pictures - - - - d:g:public:rwX,d:m::rwX"
|
"a+ /home/user/pictures - - - - d:g:users:rwX,d:m::rwX"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
executables/opencode.sh
Normal file
12
executables/opencode.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SSH_TARGET="sandbox@vsock%3"
|
||||||
|
|
||||||
|
if [[ "$PWD" == /home/user* ]]; then
|
||||||
|
project="${PWD/\/home\/user/\/home\/sandbox}"
|
||||||
|
else
|
||||||
|
project="$(ssh "$SSH_TARGET" 'mktemp -d -p /tmp opencode-XXXXXX')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec ssh -t "$SSH_TARGET" opencode "$project" "$@"
|
||||||
101
firejail.nix
Normal file
101
firejail.nix
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
agentProfile = pkgs.writeText "agent.profile" ''
|
||||||
|
whitelist /nix/store
|
||||||
|
whitelist /nix/var
|
||||||
|
read-only /nix/store
|
||||||
|
whitelist ''${HOME}/.cache/nix
|
||||||
|
whitelist ''${HOME}/.local/state/nix
|
||||||
|
whitelist /etc/nix
|
||||||
|
whitelist /etc/nixos
|
||||||
|
whitelist /nix/var/nix/daemon-socket
|
||||||
|
whitelist ''${HOME}/dev
|
||||||
|
whitelist ''${HOME}/work
|
||||||
|
whitelist ''${HOME}/.config
|
||||||
|
|
||||||
|
blacklist ''${HOME}
|
||||||
|
blacklist /etc/nixos/secrets
|
||||||
|
blacklist /etc/shadow
|
||||||
|
blacklist /etc/sudoers
|
||||||
|
blacklist /etc/sudoers.d
|
||||||
|
blacklist /root
|
||||||
|
|
||||||
|
caps.drop all
|
||||||
|
nonewprivs
|
||||||
|
noroot
|
||||||
|
seccomp
|
||||||
|
|
||||||
|
no3d
|
||||||
|
nodvd
|
||||||
|
notv
|
||||||
|
nou2f
|
||||||
|
novideo
|
||||||
|
|
||||||
|
|
||||||
|
ignore net none
|
||||||
|
|
||||||
|
machine-id
|
||||||
|
disable-mnt
|
||||||
|
private-dev
|
||||||
|
private-tmp
|
||||||
|
private-cache
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.firejail = {
|
||||||
|
enable = true;
|
||||||
|
wrappedBinaries = {
|
||||||
|
claude = {
|
||||||
|
executable = "${pkgs.claude-code}/bin/claude";
|
||||||
|
profile = agentProfile;
|
||||||
|
extraArgs = [
|
||||||
|
"--private=~/.local/state/claude-home"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
chromium-sandbox = {
|
||||||
|
executable = "${pkgs.chromium}/bin/chromium";
|
||||||
|
profile = "${pkgs.firejail}/etc/firejail/chromium-browser.profile";
|
||||||
|
extraArgs = [
|
||||||
|
"--netns=wg0ns"
|
||||||
|
"--whitelist=~/downloads"
|
||||||
|
"--env=TGK_THEME=Adwaita:dark"
|
||||||
|
"--dns=10.2.0.1"
|
||||||
|
"--private=/home/user/.local/state/chromium-home"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
google-chrome-stable = {
|
||||||
|
# executable = "${chrome-argumented}/bin/google-chrome-stable";
|
||||||
|
executable = "${pkgs.google-chrome}/bin/google-chrome-stable";
|
||||||
|
profile = "${pkgs.firejail}/etc/firejail/google-chrome-stable.profile";
|
||||||
|
extraArgs = [
|
||||||
|
"--env=GTK_THEME=Adwaita:dark"
|
||||||
|
"--netns=wg-br0ns"
|
||||||
|
"--dns=10.2.0.1"
|
||||||
|
"--whitelist=/home/user/downloads"
|
||||||
|
"--whitelist=/home/user/pictures"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
tor-browser = {
|
||||||
|
executable = "${pkgs.tor-browser}/bin/tor-browser";
|
||||||
|
profile = "${pkgs.firejail}/etc/firejail/tor-browser-en-us.profile";
|
||||||
|
extraArgs = [
|
||||||
|
"--netns=wg0ns"
|
||||||
|
"--dns=1.1.1.1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
freetube = {
|
||||||
|
executable = "${pkgs.freetube}/bin/freetube";
|
||||||
|
profile = "${pkgs.firejail}/etc/firejail/freetube.profile";
|
||||||
|
extraArgs = [
|
||||||
|
"--netns=wg0ns"
|
||||||
|
"--dns=1.1.1.1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
269
flake.lock
generated
269
flake.lock
generated
|
|
@ -24,15 +24,14 @@
|
||||||
"dms": {
|
"dms": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs"
|
||||||
"quickshell": "quickshell"
|
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1777675128,
|
"lastModified": 1781822553,
|
||||||
"narHash": "sha256-2zuDs9Lju99dg8MsSPf1frKPPgCRakDn+CEGX71cHJ0=",
|
"narHash": "sha256-lINO2V/B5MxB6RXGahrPlaL07WvFiJur1WDF6rTYuyk=",
|
||||||
"owner": "AvengeMedia",
|
"owner": "AvengeMedia",
|
||||||
"repo": "DankMaterialShell",
|
"repo": "DankMaterialShell",
|
||||||
"rev": "c1cbd0994f5a3585dded85069f2c9103c54f5285",
|
"rev": "4203148cabb74abfb17e5c02f3b76c28b52601e7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -41,6 +40,71 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fenix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"ferrosonic",
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"rust-analyzer-src": "rust-analyzer-src"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1782550137,
|
||||||
|
"narHash": "sha256-XvgBjuAmdT7fvltu56lvZULtDHCr0BLVdEAdfQQlYqw=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"rev": "4febf815bd2c2f1181e027c5b07fb66d85317cc6",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fenix_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"ferrosonic",
|
||||||
|
"naersk",
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"rust-analyzer-src": "rust-analyzer-src_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1752475459,
|
||||||
|
"narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ferrosonic": {
|
||||||
|
"inputs": {
|
||||||
|
"fenix": "fenix",
|
||||||
|
"naersk": "naersk",
|
||||||
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1782822043,
|
||||||
|
"narHash": "sha256-UsStOiULt4i7hO2dasJI4MqwK0i8JzsJKgzqQHEW6mA=",
|
||||||
|
"owner": "jaidaken",
|
||||||
|
"repo": "ferrosonic",
|
||||||
|
"rev": "ac0a146b515979238b9577a4b13f30479b02b07c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "jaidaken",
|
||||||
|
"repo": "ferrosonic",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
|
|
@ -103,11 +167,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1777679572,
|
"lastModified": 1781906751,
|
||||||
"narHash": "sha256-egYNbRrkn+6SwTHinhdb6WUfzzdC3nXfCRqS321VylY=",
|
"narHash": "sha256-6Ld1PqmptFtFKblE+SynhRgyBApUWcmrISetWqWHeeo=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "9cb587ade2aa1b4a7257f0238d41072690b0ca4f",
|
"rev": "37f21dfa5d27e71b75bacd9418b156f9265e312e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -140,7 +204,7 @@
|
||||||
"impermanence": {
|
"impermanence": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"home-manager": "home-manager_2",
|
"home-manager": "home-manager_2",
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_3"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769548169,
|
"lastModified": 1769548169,
|
||||||
|
|
@ -156,6 +220,49 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"microvm": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"spectrum": "spectrum"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1784320259,
|
||||||
|
"narHash": "sha256-9yPGZVcPV0W9Iq1qL4rfkNigKIIUk4jRk3YbJNr3pLA=",
|
||||||
|
"owner": "microvm-nix",
|
||||||
|
"repo": "microvm.nix",
|
||||||
|
"rev": "24ae5c9f140e4c4b06d132ea3fc7795b550dfe9e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "microvm-nix",
|
||||||
|
"repo": "microvm.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"naersk": {
|
||||||
|
"inputs": {
|
||||||
|
"fenix": "fenix_2",
|
||||||
|
"nixpkgs": [
|
||||||
|
"ferrosonic",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1782220280,
|
||||||
|
"narHash": "sha256-thLTFbp9D5Qknmh8q/v4FRpLGphUSijT3E86cbLYTXo=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"rev": "9aa07bb0256d300219b30622d2454e85f7f3667e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"niri-branch": {
|
"niri-branch": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|
@ -164,11 +271,11 @@
|
||||||
"rust-overlay": "rust-overlay"
|
"rust-overlay": "rust-overlay"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1771283045,
|
"lastModified": 1781817881,
|
||||||
"narHash": "sha256-AgD3KAkrQ4cs34kKZE8v/+FyFTc1Vq2sOJaPrWiCRio=",
|
"narHash": "sha256-pRPtSWYy9XsVnvjHhXhaGX3uwqFdfAn2fXvxQ0xKXnk=",
|
||||||
"owner": "argosnothing",
|
"owner": "argosnothing",
|
||||||
"repo": "niri",
|
"repo": "niri",
|
||||||
"rev": "eab116015a5a4d8f027c915dbd7b0a90e1e9a5e1",
|
"rev": "cd36d0374d6e66bc07248899d02478f42719ecc2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -203,11 +310,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776169885,
|
"lastModified": 1778443072,
|
||||||
"narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=",
|
"narHash": "sha256-zi7/fsqM/kFdNuED//4WOCUtezGtKKqRNORjMvfwjnA=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9",
|
"rev": "da5ad661ba4e5ef59ba743f0d112cbc30e474f32",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -218,6 +325,22 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1782467914,
|
||||||
|
"narHash": "sha256-pGvFkM8N0xEkIIXDe5YYfbEAvHrk4IxBrjB/x8OomhE=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e73de5be04e0eff4190a1432b946d469c794e7b4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1768564909,
|
"lastModified": 1768564909,
|
||||||
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
|
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
|
||||||
|
|
@ -233,7 +356,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
"nixpkgs_4": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1744536153,
|
"lastModified": 1744536153,
|
||||||
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
|
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
|
||||||
|
|
@ -249,13 +372,13 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_4": {
|
"nixpkgs_5": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1777731324,
|
"lastModified": 1781960011,
|
||||||
"narHash": "sha256-piLMdJYPP/9+/yiHxVMpqbAAoP8EnsqRO5921ilx0lk=",
|
"narHash": "sha256-66fKJZTRbxFJ48dE3kDdCaHTbux6nmApvIQhtwcaI0E=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "38e436af6ec1a3b1c9b666ceea098bf5ef05fc66",
|
"rev": "c1b9ab3ad7c39b61915438b2222e3655b7d8a16f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -264,13 +387,13 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_5": {
|
"nixpkgs_6": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1777578337,
|
"lastModified": 1781577229,
|
||||||
"narHash": "sha256-Ad49moKWeXtKBJNy2ebiTQUEgdLyvGmTeykAQ9xM+Z4=",
|
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "15f4ee454b1dce334612fa6843b3e05cf546efab",
|
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -283,14 +406,14 @@
|
||||||
"nur": {
|
"nur": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"nixpkgs": "nixpkgs_5"
|
"nixpkgs": "nixpkgs_6"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1777729540,
|
"lastModified": 1781959811,
|
||||||
"narHash": "sha256-tF5WMS4SSSmDvEZ7qgOosh8q0BVdz/ynb4Wnruc1rgY=",
|
"narHash": "sha256-ZKWWQbvWnZwHU6YTWB7uoIgeXw70z82mJglH7DmCTDg=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "1091dd1d0f6589dc9a88d808052dda9b85835670",
|
"rev": "8ccedaa4ba8b650594426145a6f67201b685359c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -299,41 +422,55 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"quickshell": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"dms",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1776854048,
|
|
||||||
"narHash": "sha256-lLbV66V3RMNp1l8/UelmR4YzoJ5ONtgvEtiUMJATH/o=",
|
|
||||||
"ref": "refs/heads/master",
|
|
||||||
"rev": "783c953987dc56ff0601abe6845ed96f1d00495a",
|
|
||||||
"revCount": 806,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.outfoxxed.me/quickshell/quickshell"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"rev": "783c953987dc56ff0601abe6845ed96f1d00495a",
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.outfoxxed.me/quickshell/quickshell"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
"dms": "dms",
|
"dms": "dms",
|
||||||
|
"ferrosonic": "ferrosonic",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"impermanence": "impermanence",
|
"impermanence": "impermanence",
|
||||||
|
"microvm": "microvm",
|
||||||
"niri-branch": "niri-branch",
|
"niri-branch": "niri-branch",
|
||||||
"niri-scratchpad": "niri-scratchpad",
|
"niri-scratchpad": "niri-scratchpad",
|
||||||
"nixpkgs": "nixpkgs_4",
|
"nixpkgs": "nixpkgs_5",
|
||||||
"nur": "nur",
|
"nur": "nur",
|
||||||
"sops-nix": "sops-nix"
|
"sops-nix": "sops-nix"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rust-analyzer-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1782469328,
|
||||||
|
"narHash": "sha256-EVrPvYr7VtAtiUWdKglwTSVT+KgQNcZ8EEWL/CnBC0o=",
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"rev": "a77548188dbecc332bdc292b01a5077ec770cd98",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"ref": "nightly",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-analyzer-src_2": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1752428706,
|
||||||
|
"narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=",
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"rev": "591e3b7624be97e4443ea7b5542c191311aa141d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"ref": "nightly",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rust-overlay": {
|
"rust-overlay": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|
@ -342,11 +479,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767322002,
|
"lastModified": 1781752752,
|
||||||
"narHash": "sha256-yHKXXw2OWfIFsyTjduB4EyFwR0SYYF0hK8xI9z4NIn0=",
|
"narHash": "sha256-kVG5tV9hddPviGAgqf9sGSuStvv+HAB9onfKqGptV0k=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "03c6e38661c02a27ca006a284813afdc461e9f7e",
|
"rev": "c06d86dabe5b92982b9d67acccb9990d58da3a0e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -357,7 +494,7 @@
|
||||||
},
|
},
|
||||||
"rust-overlay_2": {
|
"rust-overlay_2": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_3"
|
"nixpkgs": "nixpkgs_4"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772075164,
|
"lastModified": 1772075164,
|
||||||
|
|
@ -380,11 +517,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1777338324,
|
"lastModified": 1781943681,
|
||||||
"narHash": "sha256-bc+ZZCmOTNq86/svGnw0tVpH7vJaLYvGLLKFYP08Q8E=",
|
"narHash": "sha256-NFHmA7H47adqiyp+0iEOyZOQhmigDqA/NBAlf4imB6U=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "8eaee5c45428b28b8c47a83e4c09dccec5f279b5",
|
"rev": "420f8d2e9882911f65cfac15cc706f639ba96cca",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -393,6 +530,22 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"spectrum": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1783694892,
|
||||||
|
"narHash": "sha256-xO8f7Qng+18FK2UlB9vcrkxCaQMCt5WjCH24aW/11eg=",
|
||||||
|
"ref": "refs/heads/main",
|
||||||
|
"rev": "24c4346e30fdea8d8e80f34aec3554a15a667d24",
|
||||||
|
"revCount": 1410,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://spectrum-os.org/git/spectrum"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://spectrum-os.org/git/spectrum"
|
||||||
|
}
|
||||||
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
|
|
|
||||||
20
flake.nix
20
flake.nix
|
|
@ -7,10 +7,10 @@
|
||||||
url = "github:Mic92/sops-nix";
|
url = "github:Mic92/sops-nix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
# microvm = {
|
microvm = {
|
||||||
# url = "github:microvm-nix/microvm.nix/da28962a2ba84718895b7325f600686c3b4ee099";
|
url = "github:microvm-nix/microvm.nix";
|
||||||
# inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
# };
|
};
|
||||||
disko = {
|
disko = {
|
||||||
url = "github:nix-community/disko/latest";
|
url = "github:nix-community/disko/latest";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
dms.url = "github:AvengeMedia/DankMaterialShell";
|
dms.url = "github:AvengeMedia/DankMaterialShell";
|
||||||
|
ferrosonic.url = "github:jaidaken/ferrosonic";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
|
|
@ -39,6 +40,7 @@
|
||||||
sops-nix,
|
sops-nix,
|
||||||
impermanence,
|
impermanence,
|
||||||
home-manager,
|
home-manager,
|
||||||
|
microvm,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
|
@ -49,7 +51,7 @@
|
||||||
config.allowUnfree = true;
|
config.allowUnfree = true;
|
||||||
# overlays = [ inputs.neovim-nightly-overlay.overlays.default ];
|
# overlays = [ inputs.neovim-nightly-overlay.overlays.default ];
|
||||||
};
|
};
|
||||||
# microvm = inputs.microvm.nixosModules.host;
|
microvm = inputs.microvm.nixosModules.host;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
nixosConfigurations."${hostname}" = nixpkgs.lib.nixosSystem {
|
nixosConfigurations."${hostname}" = nixpkgs.lib.nixosSystem {
|
||||||
|
|
@ -59,7 +61,7 @@
|
||||||
nixpkgs
|
nixpkgs
|
||||||
impermanence
|
impermanence
|
||||||
home-manager
|
home-manager
|
||||||
# microvm
|
microvm
|
||||||
sops-nix
|
sops-nix
|
||||||
;
|
;
|
||||||
hostname = hostname;
|
hostname = hostname;
|
||||||
|
|
@ -73,9 +75,10 @@
|
||||||
./packages.nix
|
./packages.nix
|
||||||
./kernel
|
./kernel
|
||||||
./home
|
./home
|
||||||
|
./firejail.nix
|
||||||
inputs.sops-nix.nixosModules.sops
|
inputs.sops-nix.nixosModules.sops
|
||||||
# inputs.microvm.nixosModules.host
|
inputs.microvm.nixosModules.host
|
||||||
# (import ./vms)
|
(import ./microvm/sandbox.nix)
|
||||||
inputs.disko.nixosModules.disko
|
inputs.disko.nixosModules.disko
|
||||||
inputs.impermanence.nixosModules.impermanence
|
inputs.impermanence.nixosModules.impermanence
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
|
@ -105,6 +108,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
ferrosonic = inputs.ferrosonic.packages.${prev.stdenv.hostPlatform.system}.default;
|
||||||
})
|
})
|
||||||
inputs.nur.overlays.default
|
inputs.nur.overlays.default
|
||||||
(_: prev: {
|
(_: prev: {
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ let
|
||||||
enable = true;
|
enable = true;
|
||||||
setSessionVariables = false;
|
setSessionVariables = false;
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
XDG_CACHE_HOME = "$HOME/.cache";
|
XDG_CACHE_HOME = "${HOME}/.cache";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -236,8 +236,8 @@ in
|
||||||
{
|
{
|
||||||
home-manager.users = lib.mkMerge [
|
home-manager.users = lib.mkMerge [
|
||||||
(home-manager-config {
|
(home-manager-config {
|
||||||
uid = 1002;
|
uid = 1001;
|
||||||
username = "agent";
|
username = "sandbox";
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ in
|
||||||
less = { "prettierd" },
|
less = { "prettierd" },
|
||||||
blade = { "blade-formatter" },
|
blade = { "blade-formatter" },
|
||||||
go = { "gofmt" },
|
go = { "gofmt" },
|
||||||
wgsl = { "wgsl_fmt" },
|
wgsl = { "wgslfmt" },
|
||||||
odin = { "odinfmt" },
|
odin = { "odinfmt" },
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
@ -107,14 +107,6 @@ in
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
leap-nvim
|
leap-nvim
|
||||||
{
|
|
||||||
plugin = lsp_lines-nvim;
|
|
||||||
type = "lua";
|
|
||||||
config = ''
|
|
||||||
require("lsp_lines").setup()
|
|
||||||
vim.keymap.set("n", "<localleader>it", require("lsp_lines").toggle, { desc = "Toggle LSP lines" })
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
plugin = mini-icons;
|
plugin = mini-icons;
|
||||||
type = "lua";
|
type = "lua";
|
||||||
|
|
@ -151,13 +143,13 @@ in
|
||||||
# plugin = neotest-zig;
|
# plugin = neotest-zig;
|
||||||
# type = "lua";
|
# type = "lua";
|
||||||
# }
|
# }
|
||||||
# {
|
{
|
||||||
# plugin = nvim-autopairs;
|
plugin = nvim-autopairs;
|
||||||
# type = "lua";
|
type = "lua";
|
||||||
# config = ''
|
config = ''
|
||||||
# require('nvim-autopairs').setup()
|
require('nvim-autopairs').setup()
|
||||||
# '';
|
'';
|
||||||
# }
|
}
|
||||||
{
|
{
|
||||||
plugin = nvim-dap;
|
plugin = nvim-dap;
|
||||||
type = "lua";
|
type = "lua";
|
||||||
|
|
@ -380,23 +372,12 @@ in
|
||||||
require("ts-autotag").setup()
|
require("ts-autotag").setup()
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
# {
|
|
||||||
# plugin = toggleterm-nvim;
|
|
||||||
# type = "lua";
|
|
||||||
# config = ''
|
|
||||||
# require("toggleterm").setup()
|
|
||||||
# vim.keymap.set("n", "<leader>nt", "<cmd>ToggleTerm size=120 direction=tab name=ttermh<cr>", { desc = "Toggle tterm tab" })
|
|
||||||
# vim.keymap.set("n", "<leader>ns", "<cmd>ToggleTerm direction=vertical name=ttermv<cr>", { desc = "Toggle tterm vertical" })
|
|
||||||
# vim.keymap.set("n", "<C-n>", "<cmd>ToggleTerm direction=float name=ttermf<cr>", { desc = "Toggle tterm float" })
|
|
||||||
# '';
|
|
||||||
# }
|
|
||||||
{
|
{
|
||||||
plugin = trouble-nvim;
|
plugin = trouble-nvim;
|
||||||
type = "lua";
|
type = "lua";
|
||||||
config = ''
|
config = ''
|
||||||
require("trouble").setup({})
|
require("trouble").setup({})
|
||||||
vim.keymap.set("n", "<localleader>id", "<cmd>Trouble diagnostics toggle<cr>", { desc = "Trouble project" })
|
vim.keymap.set("n", "<localleader>id", "<cmd>Trouble diagnostics toggle<cr>", { desc = "Trouble project" })
|
||||||
-- vim.keymap.set("n", "<localleader>io", "<cmd>Trouble diagnostics toggle filter.buf=0<cr>", { desc = "Trouble buffer" })
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -152,15 +152,3 @@ vim.api.nvim_create_autocmd("CmdlineLeave", {
|
||||||
|
|
||||||
vim.keymap.set({ "n", "x", "o" }, "s", "<Plug>(leap)", { desc = "leap" })
|
vim.keymap.set({ "n", "x", "o" }, "s", "<Plug>(leap)", { desc = "leap" })
|
||||||
vim.keymap.set({ "n", "x", "o" }, "S", "<Plug>(leap-from-window)", { desc = "leap across window" })
|
vim.keymap.set({ "n", "x", "o" }, "S", "<Plug>(leap-from-window)", { desc = "leap across window" })
|
||||||
|
|
||||||
require("neotest").setup({
|
|
||||||
adapters = {
|
|
||||||
require("neotest-pest"),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
vim.keymap.set("n", "<localleader>pn", function()
|
|
||||||
require("neotest").run.run()
|
|
||||||
end, { desc = "test nearest" })
|
|
||||||
vim.keymap.set("n", "<localleader>pe", function()
|
|
||||||
require("neotest").run.run(vim.fn.expand("%"))
|
|
||||||
end, { desc = "test file" })
|
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ vim.diagnostic.config({
|
||||||
virtual_lines = true,
|
virtual_lines = true,
|
||||||
signs = true,
|
signs = true,
|
||||||
underline = true,
|
underline = true,
|
||||||
update_in_insert = false,
|
update_in_insert = true,
|
||||||
severity_sort = true,
|
severity_sort = true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
ssh = {
|
ssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableDefaultConfig = false;
|
enableDefaultConfig = false;
|
||||||
matchBlocks = {
|
settings = {
|
||||||
"icefox.sh" = {
|
"icefox.sh" = {
|
||||||
user = "git";
|
user = "git";
|
||||||
identityFile = "/root/.ssh/desktop";
|
identityFile = "/root/.ssh/desktop";
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,12 @@
|
||||||
|
|
||||||
sops.defaultSopsFile = ../secrets/home.yaml;
|
sops.defaultSopsFile = ../secrets/home.yaml;
|
||||||
sops.age.keyFile = "/.persist/${HOME}/.config/sops/age/keys.txt";
|
sops.age.keyFile = "/.persist/${HOME}/.config/sops/age/keys.txt";
|
||||||
sops.secrets."user/ssh/desktop" = {
|
sops.secrets = {
|
||||||
path = "${HOME}/.ssh/desktop";
|
"user/ssh/desktop" = {
|
||||||
mode = "0600";
|
path = "${HOME}/.ssh/desktop";
|
||||||
|
mode = "0600";
|
||||||
|
};
|
||||||
|
"navidrome/user" = { };
|
||||||
};
|
};
|
||||||
home.file."/.ssh/desktop.pub".text =
|
home.file."/.ssh/desktop.pub".text =
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILABd/iSJ4gn/ystDqNxLJTG0n0z5VIC9YXlmdUfOhHf desktop@icefox.sh";
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILABd/iSJ4gn/ystDqNxLJTG0n0z5VIC9YXlmdUfOhHf desktop@icefox.sh";
|
||||||
|
|
@ -59,13 +62,16 @@
|
||||||
systemd.user.services.waypipe-socket = {
|
systemd.user.services.waypipe-socket = {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "start waypipe client";
|
Description = "start waypipe client";
|
||||||
|
After = [ "niri.service" ];
|
||||||
|
Requires = [ "niri.service" ];
|
||||||
};
|
};
|
||||||
Install = {
|
Install = {
|
||||||
WantedBy = [ "graphical-session.target" ];
|
WantedBy = [ "graphical-session.target" ];
|
||||||
};
|
};
|
||||||
Service = {
|
Service = {
|
||||||
ExecStart = "${pkgs.waypipe}/bin/waypipe --socket /tmp/waypipe.sock client";
|
ExecStart = "${pkgs.waypipe}/bin/waypipe --socket /tmp/waypipe.sock client";
|
||||||
ExecStartPost = "${pkgs.acl}/bin/setfacl -m u:agent:rw /tmp/waypipe.sock";
|
ExecStartPost = "${pkgs.acl}/bin/setfacl -m g:sandbox:rw /tmp/waypipe.sock";
|
||||||
|
ExecStopPost = "${pkgs.coreutils}/bin/rm /tmp/waypipe.sock";
|
||||||
RuntimeDirectory = "waypipe";
|
RuntimeDirectory = "waypipe";
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
|
|
@ -100,6 +106,24 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
xdg.configFile."ferrosonic/config.toml".text = ''
|
||||||
|
BaseURL = "https://navidrome.icefox.sh"
|
||||||
|
Username = "user"
|
||||||
|
PasswordFile = "${config.sops.secrets."navidrome/user".path}"
|
||||||
|
Theme = "Catppuccin"
|
||||||
|
Cava = true
|
||||||
|
CavaSize = 40
|
||||||
|
Daemon = false
|
||||||
|
AutoContinue = false
|
||||||
|
RepeatMode = "Off"
|
||||||
|
CoverArt = true
|
||||||
|
CoverArtSize = 16
|
||||||
|
Scrobble = true
|
||||||
|
Notifications = true
|
||||||
|
RateSwitchDelayMs = 500
|
||||||
|
MusicFolderId = 1
|
||||||
|
'';
|
||||||
|
|
||||||
xdg.desktopEntries = {
|
xdg.desktopEntries = {
|
||||||
google-chrome = {
|
google-chrome = {
|
||||||
name = "Google Chrome";
|
name = "Google Chrome";
|
||||||
|
|
@ -229,16 +253,17 @@
|
||||||
|
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
SCREENSHOTS = "$HOME/pictures/screenshots";
|
SCREENSHOTS = "$HOME/pictures/screenshots";
|
||||||
XDG_CACHE_HOME = "$HOME/.cache";
|
XDG_CACHE_HOME = "${HOME}/.cache";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
|
opencode.enable = true;
|
||||||
dank-material-shell.enable = true;
|
dank-material-shell.enable = true;
|
||||||
ssh = {
|
ssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableDefaultConfig = false;
|
enableDefaultConfig = false;
|
||||||
matchBlocks = {
|
settings = {
|
||||||
"*" = {
|
"*" = {
|
||||||
serverAliveInterval = 60;
|
serverAliveInterval = 60;
|
||||||
serverAliveCountMax = 3;
|
serverAliveCountMax = 3;
|
||||||
|
|
@ -275,15 +300,15 @@
|
||||||
user = {
|
user = {
|
||||||
name = "felipematos";
|
name = "felipematos";
|
||||||
email = "5471818+fnzr@users.noreply.github.com";
|
email = "5471818+fnzr@users.noreply.github.com";
|
||||||
signingkey = "E6C30AB4CD83BB00";
|
signingkey = "${HOME}/.ssh/desktop.pub";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
settings = {
|
settings = {
|
||||||
user = {
|
user = {
|
||||||
email = "felipe@icefox.sh";
|
email = "felipe@imatos.dev";
|
||||||
name = "icefox";
|
name = "fmatos";
|
||||||
signingkey = "${HOME}/.ssh/desktop.pub";
|
signingkey = "${HOME}/.ssh/desktop.pub";
|
||||||
};
|
};
|
||||||
gpg.format = "ssh";
|
gpg.format = "ssh";
|
||||||
|
|
@ -330,7 +355,7 @@
|
||||||
};
|
};
|
||||||
safe = {
|
safe = {
|
||||||
directory = [
|
directory = [
|
||||||
"/home/agent/*"
|
"/home/sandbox/*"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -339,9 +364,14 @@
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
xrdb
|
xrdb
|
||||||
(writeShellScriptBin "agent" ''
|
# (writeShellScriptBin "agent" ''
|
||||||
machinectl shell agent@ ${waypipe}/bin/waypipe --socket /run/waypipe.sock server fish
|
# machinectl shell agent@ ${waypipe}/bin/waypipe --socket /run/waypipe.sock server fish
|
||||||
'')
|
# '')
|
||||||
|
(writeShellApplication {
|
||||||
|
name = "opencode-sandbox";
|
||||||
|
runtimeInputs = [ openssh ];
|
||||||
|
text = builtins.readFile ../executables/opencode.sh;
|
||||||
|
})
|
||||||
(writeShellApplication {
|
(writeShellApplication {
|
||||||
name = "tmux-sessionizer";
|
name = "tmux-sessionizer";
|
||||||
runtimeInputs = [
|
runtimeInputs = [
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,11 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
users.agent = {
|
# users.agent = {
|
||||||
files = [
|
# files = [
|
||||||
".config/sops/age/keys.txt"
|
# ".config/sops/age/keys.txt"
|
||||||
];
|
# ];
|
||||||
};
|
# };
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.persistence."/.nobackup" = {
|
environment.persistence."/.nobackup" = {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ let
|
||||||
"$@"
|
"$@"
|
||||||
'';
|
'';
|
||||||
nsWrapper = pkgs.writeShellScriptBin "ns" ''
|
nsWrapper = pkgs.writeShellScriptBin "ns" ''
|
||||||
|
|
||||||
exec /run/wrappers/bin/doas ${nsExec}/bin/ns-raw "$@"
|
exec /run/wrappers/bin/doas ${nsExec}/bin/ns-raw "$@"
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
|
|
@ -24,17 +23,16 @@ in
|
||||||
./hardened.nix
|
./hardened.nix
|
||||||
./vfio.nix
|
./vfio.nix
|
||||||
./standard.nix
|
./standard.nix
|
||||||
# ./apparmor.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
custom.kernel.hardened.enable = true;
|
custom.kernel.hardened.enable = true;
|
||||||
custom.kernel.vfio.enable = false;
|
custom.kernel.vfio.enable = false;
|
||||||
custom.kernel.standard.enable = true;
|
custom.kernel.standard.enable = true;
|
||||||
# security.apparmor.enable = false;
|
security.apparmor.enable = false;
|
||||||
|
|
||||||
specialisation.unhardened.configuration = {
|
specialisation.unhardened.configuration = {
|
||||||
custom.kernel.hardened.enable = lib.mkForce false;
|
custom.kernel.hardened.enable = lib.mkForce false;
|
||||||
# security.apparmor.enable = lib.mkForce false;
|
security.apparmor.enable = lib.mkForce false;
|
||||||
};
|
};
|
||||||
|
|
||||||
specialisation.vfio.configuration = {
|
specialisation.vfio.configuration = {
|
||||||
|
|
@ -57,6 +55,10 @@ in
|
||||||
runAs = "root";
|
runAs = "root";
|
||||||
keepEnv = true;
|
keepEnv = true;
|
||||||
persist = true;
|
persist = true;
|
||||||
|
setEnv = [
|
||||||
|
"EDITOR"
|
||||||
|
"TERM"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
users = [ "user" ];
|
users = [ "user" ];
|
||||||
|
|
@ -64,23 +66,6 @@ in
|
||||||
noPass = true;
|
noPass = true;
|
||||||
keepEnv = false;
|
keepEnv = false;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
users = [ "user" ];
|
|
||||||
runAs = "agent";
|
|
||||||
noPass = true;
|
|
||||||
keepEnv = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
users = [
|
|
||||||
"user"
|
|
||||||
"agent"
|
|
||||||
"work"
|
|
||||||
];
|
|
||||||
runAs = "root";
|
|
||||||
noPass = true;
|
|
||||||
keepEnv = true;
|
|
||||||
cmd = "${nsExec}/bin/ns-raw";
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -89,6 +74,19 @@ in
|
||||||
security.pam.services.su.requireWheel = true;
|
security.pam.services.su.requireWheel = true;
|
||||||
security.pam.services.newgrp.requireWheel = true;
|
security.pam.services.newgrp.requireWheel = true;
|
||||||
|
|
||||||
|
security.polkit = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
if ((action.id == "org.freedesktop.machine1.host-shell" ||
|
||||||
|
action.id == "org.freedesktop.machine1.login") &&
|
||||||
|
subject.user == "user") {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
loader = {
|
loader = {
|
||||||
systemd-boot.enable = true;
|
systemd-boot.enable = true;
|
||||||
|
|
|
||||||
234
microvm/sandbox.nix
Normal file
234
microvm/sandbox.nix
Normal file
|
|
@ -0,0 +1,234 @@
|
||||||
|
{
|
||||||
|
impermanence,
|
||||||
|
sops-nix,
|
||||||
|
home-manager,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
impermanenceModule = impermanence.nixosModules.impermanence;
|
||||||
|
sopsModule = sops-nix.nixosModules.sops;
|
||||||
|
homeManagerModule = home-manager.nixosModules.home-manager;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
microvm.host.useNotifySockets = true;
|
||||||
|
microvm.vms."sandbox" = {
|
||||||
|
config =
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
impermanenceModule
|
||||||
|
sopsModule
|
||||||
|
homeManagerModule
|
||||||
|
];
|
||||||
|
|
||||||
|
sops.defaultSopsFile = ./secrets/sandbox.yaml;
|
||||||
|
sops.age.keyFile = "/.persist/secrets/age-keys.txt";
|
||||||
|
sops.secrets."root-password-hash" = {
|
||||||
|
neededForUsers = true;
|
||||||
|
};
|
||||||
|
sops.secrets."sandbox-password-hash" = {
|
||||||
|
neededForUsers = true;
|
||||||
|
};
|
||||||
|
sops.secrets."deepseek-api-key" = {
|
||||||
|
owner = "sandbox";
|
||||||
|
mode = "0400";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/.persist".neededForBoot = true;
|
||||||
|
|
||||||
|
users.users.root = {
|
||||||
|
hashedPasswordFile = config.sops.secrets."root-password-hash".path;
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILABd/iSJ4gn/ystDqNxLJTG0n0z5VIC9YXlmdUfOhHf desktop@icefox.sh"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
users.users.host = {
|
||||||
|
isNormalUser = true;
|
||||||
|
uid = 1000;
|
||||||
|
group = "users";
|
||||||
|
};
|
||||||
|
users.users.sandbox = {
|
||||||
|
isNormalUser = true;
|
||||||
|
uid = 1001;
|
||||||
|
group = "users";
|
||||||
|
extraGroups = [
|
||||||
|
"video"
|
||||||
|
"render"
|
||||||
|
];
|
||||||
|
hashedPasswordFile = config.sops.secrets."sandbox-password-hash".path;
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILABd/iSJ4gn/ystDqNxLJTG0n0z5VIC9YXlmdUfOhHf desktop@icefox.sh"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
services.openssh.enable = true;
|
||||||
|
|
||||||
|
boot.kernelModules = [
|
||||||
|
"drm"
|
||||||
|
"virtio_gpu"
|
||||||
|
];
|
||||||
|
boot.blacklistedKernelModules = lib.mkForce [ ];
|
||||||
|
|
||||||
|
environment.sessionVariables = {
|
||||||
|
WAYLAND_DISPLAY = "wayland-1";
|
||||||
|
DISPLAY = ":0";
|
||||||
|
QT_QPA_PLATFORM = "wayland";
|
||||||
|
GDK_BACKEND = "wayland";
|
||||||
|
XDG_SESSION_TYPE = "wayland";
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.graphics.enable = true;
|
||||||
|
system.stateVersion = lib.trivial.release;
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
xdg-utils
|
||||||
|
tmux
|
||||||
|
waypipe
|
||||||
|
opencode
|
||||||
|
fd
|
||||||
|
ripgrep
|
||||||
|
podman-compose
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.persistence."/.persist" = {
|
||||||
|
enable = true;
|
||||||
|
hideMounts = true;
|
||||||
|
users.sandbox = {
|
||||||
|
directories = [
|
||||||
|
".local/share/opencode"
|
||||||
|
".claude"
|
||||||
|
];
|
||||||
|
files = [
|
||||||
|
".claude.json"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager = {
|
||||||
|
useGlobalPkgs = true;
|
||||||
|
users.sandbox = {
|
||||||
|
home.stateVersion = "26.11";
|
||||||
|
xdg.configFile."containers/containers.conf".text = ''
|
||||||
|
[engine]
|
||||||
|
compose_warning_logs=false
|
||||||
|
events_logger="file"
|
||||||
|
|
||||||
|
[containers]
|
||||||
|
log_driver="k8s-file"
|
||||||
|
'';
|
||||||
|
xdg.configFile."opencode/opencode.json".text = builtins.toJSON {
|
||||||
|
"$schema" = "https://opencode.ai/config.json";
|
||||||
|
provider = {
|
||||||
|
deepseek = {
|
||||||
|
npm = "@ai-sdk/openai-compatible";
|
||||||
|
name = "DeepSeek";
|
||||||
|
options = {
|
||||||
|
baseURL = "https://api.deepseek.com";
|
||||||
|
apiKey = "{file:${config.sops.secrets."deepseek-api-key".path}}";
|
||||||
|
};
|
||||||
|
models = {
|
||||||
|
"deepseek-v4-pro" = {
|
||||||
|
name = "DeepSeek-V4-Pro";
|
||||||
|
limit = {
|
||||||
|
context = 1048576;
|
||||||
|
output = 262144;
|
||||||
|
};
|
||||||
|
options = {
|
||||||
|
reasoningEffort = "high";
|
||||||
|
thinking.type = "enabled";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"deepseek-v4-flash" = {
|
||||||
|
name = "DeepSeek-V4-Flash";
|
||||||
|
limit = {
|
||||||
|
context = 1048576;
|
||||||
|
output = 262144;
|
||||||
|
};
|
||||||
|
options = {
|
||||||
|
reasoningEffort = "high";
|
||||||
|
thinking.type = "enabled";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.containers.enable = true;
|
||||||
|
virtualisation.podman = {
|
||||||
|
enable = true;
|
||||||
|
dockerCompat = true;
|
||||||
|
defaultNetwork.settings.dns_enabled = true;
|
||||||
|
};
|
||||||
|
microvm = {
|
||||||
|
vsock = {
|
||||||
|
cid = 3;
|
||||||
|
ssh.enable = true;
|
||||||
|
};
|
||||||
|
writableStoreOverlay = "/nix/.rw-store";
|
||||||
|
# graphics.enable = true;
|
||||||
|
mem = 4096;
|
||||||
|
interfaces = [
|
||||||
|
{
|
||||||
|
type = "user";
|
||||||
|
id = "vm-1";
|
||||||
|
mac = "02:00:00:01:01:01";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
volumes = [
|
||||||
|
{
|
||||||
|
mountPoint = "/var";
|
||||||
|
image = "var.img";
|
||||||
|
size = 256;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = "/nix/.rw-store";
|
||||||
|
image = "nix-store-overlay.img";
|
||||||
|
size = 512;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = "/.persist";
|
||||||
|
image = "persist.img";
|
||||||
|
size = 1;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
shares = [
|
||||||
|
{
|
||||||
|
proto = "virtiofs";
|
||||||
|
tag = "projects";
|
||||||
|
source = "/home/user/dev";
|
||||||
|
mountPoint = "/home/sandbox/dev";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
proto = "virtiofs";
|
||||||
|
tag = "work";
|
||||||
|
source = "/home/user/work";
|
||||||
|
mountPoint = "/home/sandbox/work";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
proto = "virtiofs";
|
||||||
|
tag = "screenshots";
|
||||||
|
source = "/home/user/pictures";
|
||||||
|
mountPoint = "/home/sandbox/pictures";
|
||||||
|
readOnly = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
proto = "virtiofs";
|
||||||
|
tag = "ro-store";
|
||||||
|
source = "/nix/store";
|
||||||
|
mountPoint = "/nix/.ro-store";
|
||||||
|
readOnly = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
hypervisor = "qemu";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
18
microvm/secrets/sandbox.yaml
Normal file
18
microvm/secrets/sandbox.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
root-password-hash: ENC[AES256_GCM,data:YTQn1UGwgrlCD381u+Z7xXMgUoigKXp+Na1/Aj0GExikEeIs9SkBIcAyQ2Dw0FimL0wgG4z+AxFhdAnzRHcbecvvb3tRrTX3VjFt+CLPWscZar1jjNesPyV1inXI2IFW06twHbAl4oQHFQ==,iv:Va0B4aFUlavJd3AGzDbAnmAnAX3fEow4ByIQzfPbheM=,tag:OIjXY7ngZow7Y3tRFZ8iiA==,type:str]
|
||||||
|
sandbox-password-hash: ENC[AES256_GCM,data:bxVKDAsk6ao0D+xIgAR2Sh1msoPJGEE8P0+O9YGZS/F+DZl33r/JQbNFYJzZgbHDqzLDbab0tnzyRwbfepT2eV/KWaroQDFcBCLJ07t4lTOtdJ3mR/dB1UftrCvvmoPubVrguDPvftQLAg==,iv:tDErYBYhfPrOKyH7W41SUAFgT54bA7QvUYmo35GWMIs=,tag:vNJVKrlCwCuZl4z8KFby2Q==,type:str]
|
||||||
|
deepseek-api-key: ENC[AES256_GCM,data:pzg/7L92Ig+m3nhZBiYFSfdLuJFmamWWmPQwMxmctRS2kVQ=,iv:yCu+kPXkOxhfpVLlOvUpB/BwygedRaJviPe2D0tCW78=,tag:YTM7hx4UdZEsB9qfXs5LXQ==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzQXlvQWl3aWtSWjU5QWVN
|
||||||
|
K3JGSzg0RElZSkVxNWFmTDNMNzVHckFuZkM4CnJiVDFDTTZ3cDBrTG5RR2RTR3A0
|
||||||
|
RmdDSVA1T1dDbUZTNWJQNzB1K0dhYnMKLS0tIDk3VVJBSUFLVjMrdzV5MTFzRXlF
|
||||||
|
N0ZZa3JnSXN2bHdLa1hoVFlmSUhXWWMK5JCznoaqS6svxcBl6UF9XqbfirZ9L2np
|
||||||
|
/CTlYyWRadRvRmxrNkYNdgGn4V+is9FG+Et0u8JHAMvI7x/+W99yGA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
recipient: age1mr42xh9llvrggrvuawr5253qk7gygf4gcg9clqdvjecw3d6tj59qsqxswd
|
||||||
|
lastmodified: "2026-07-18T18:23:56Z"
|
||||||
|
mac: ENC[AES256_GCM,data:d/vRaH5vFzTkb8WopwIDb9Ku7n0EXUR5PyE/fmYhDWcCGX71PcM23Y1DPX1SCY6ydnpxqtGxfRiJOZMfIAx+tCBKX5Szj2aPnKXpogtukZbWWT4pF5jYWnlXcA9R7b9CY0sSAXIetyKhAaH086PJ2i2tAx8TiqZNkUFyoR6g0+E=,iv:R+cOmhYJnVPMjaiL5J0zbFUR69sNR78Gz5ea3CV6X6Y=,tag:RlaTyampHdMtmzvHskM4Dw==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.13.1
|
||||||
|
|
@ -15,9 +15,8 @@
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
hostName = hostname;
|
hostName = hostname;
|
||||||
nameservers = [ "192.168.88.3" ];
|
|
||||||
networkmanager.enable = false;
|
networkmanager.enable = false;
|
||||||
firewall.trustedInterfaces = [ "vlan66" ];
|
nameservers = [ "192.168.88.3" ];
|
||||||
useDHCP = false;
|
useDHCP = false;
|
||||||
useNetworkd = true;
|
useNetworkd = true;
|
||||||
|
|
||||||
|
|
@ -72,20 +71,28 @@
|
||||||
linkConfig.RequiredForOnline = "routable";
|
linkConfig.RequiredForOnline = "routable";
|
||||||
};
|
};
|
||||||
|
|
||||||
# netdevs."30-vlan66" = {
|
networks."30-vm-1" = {
|
||||||
# netdevConfig = {
|
matchConfig.Name = "vm-1";
|
||||||
# Kind = "vlan";
|
address = [ "10.0.0.1/24" ];
|
||||||
# Name = "vlan66";
|
networkConfig.IPMasquerade = "both";
|
||||||
# };
|
};
|
||||||
# vlanConfig = {
|
|
||||||
# Id = 66;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# networks."30-vlan66" = {
|
};
|
||||||
# matchConfig.Name = "vlan66";
|
|
||||||
# networkConfig.DHCP = "yes";
|
networking.nat = {
|
||||||
# };
|
enable = true;
|
||||||
|
internalInterfaces = [ "vm-*" ];
|
||||||
|
externalInterface = "br0";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.resolved = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
Resolve = {
|
||||||
|
Domains = [ "~." ];
|
||||||
|
FallbackDNS = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.wireguard-netns = {
|
services.wireguard-netns = {
|
||||||
|
|
@ -113,46 +120,4 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# systemd.services."netns@wg0ns" = {
|
|
||||||
# description = "wg0 network namespace";
|
|
||||||
# before = [ "network.target" ];
|
|
||||||
# serviceConfig = {
|
|
||||||
# Type = "oneshot";
|
|
||||||
# RemainAfterExit = true;
|
|
||||||
# ExecStart = pkgs.writers.writeBash "wg0ns-up" ''
|
|
||||||
# ${pkgs.coreutils}/bin/mkdir -p /etc/netns/wg0ns
|
|
||||||
# echo "nameserver $(cat ${config.sops.secrets."wg0/dns".path})" > /etc/netns/wg0ns/resolv.conf
|
|
||||||
# ${pkgs.iproute2}/bin/ip netns add wg0ns
|
|
||||||
# '';
|
|
||||||
# ExecStop = "${pkgs.iproute2}/bin/ip netns del wg0ns";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# systemd.services.wg0 = {
|
|
||||||
# description = "wg0 network interface";
|
|
||||||
# bindsTo = [ "netns@wg0ns.service" ];
|
|
||||||
# requires = [ "network-online.target" ];
|
|
||||||
# after = [ "netns@wg0ns.service" ];
|
|
||||||
# wants = [ "network-online.target" ];
|
|
||||||
# wantedBy = [ "multi-user.target" ];
|
|
||||||
# serviceConfig = {
|
|
||||||
# Type = "oneshot";
|
|
||||||
# RemainAfterExit = true;
|
|
||||||
# ExecStart = pkgs.writers.writeBash "wg-up" ''
|
|
||||||
# ${pkgs.iproute2}/bin/ip link add wg0 type wireguard
|
|
||||||
# ${pkgs.iproute2}/bin/ip link set wg0 netns wg0ns
|
|
||||||
# ${pkgs.iproute2}/bin/ip -n wg0ns address add $(< ${config.sops.secrets."wg0/address".path}) dev wg0
|
|
||||||
# ${pkgs.iproute2}/bin/ip netns exec wg0ns \
|
|
||||||
# ${pkgs.wireguard-tools}/bin/wg setconf wg0 ${config.sops.secrets."wg0/conf".path}
|
|
||||||
# ${pkgs.iproute2}/bin/ip -n wg0ns link set lo up
|
|
||||||
# ${pkgs.iproute2}/bin/ip -n wg0ns link set wg0 up
|
|
||||||
# ${pkgs.iproute2}/bin/ip -n wg0ns route add default dev wg0
|
|
||||||
# '';
|
|
||||||
# ExecStop = pkgs.writers.writeBash "wg-down" ''
|
|
||||||
# ${pkgs.iproute2}/bin/ip -n wg0ns route del default dev wg0
|
|
||||||
# ${pkgs.iproute2}/bin/ip -n wg0ns link del wg0
|
|
||||||
# '';
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
66
packages.nix
66
packages.nix
|
|
@ -14,12 +14,12 @@
|
||||||
bluetuith
|
bluetuith
|
||||||
bluez
|
bluez
|
||||||
bluez-tools
|
bluez-tools
|
||||||
cargo
|
cava
|
||||||
clang
|
clang
|
||||||
clang-tools
|
clang-tools
|
||||||
clevis
|
clevis
|
||||||
cliphist
|
cliphist
|
||||||
chromium
|
ungoogled-chromium
|
||||||
distrobox
|
distrobox
|
||||||
dos2unix
|
dos2unix
|
||||||
dnsutils
|
dnsutils
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
(import ./templates/extract.sh.nix { inherit pkgs; })
|
(import ./templates/extract.sh.nix { inherit pkgs; })
|
||||||
eza
|
eza
|
||||||
fd
|
fd
|
||||||
|
ferrosonic
|
||||||
ffmpeg
|
ffmpeg
|
||||||
file
|
file
|
||||||
fira-code-symbols
|
fira-code-symbols
|
||||||
|
|
@ -38,7 +39,6 @@
|
||||||
git
|
git
|
||||||
gh
|
gh
|
||||||
ghostty
|
ghostty
|
||||||
go
|
|
||||||
google-chrome
|
google-chrome
|
||||||
gopass
|
gopass
|
||||||
gopass-jsonapi
|
gopass-jsonapi
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
htmx-lsp2
|
htmx-lsp2
|
||||||
imagemagick
|
imagemagick
|
||||||
inkscape
|
inkscape
|
||||||
|
# input-remapper
|
||||||
pavucontrol
|
pavucontrol
|
||||||
pciutils
|
pciutils
|
||||||
poppler
|
poppler
|
||||||
|
|
@ -54,16 +55,7 @@
|
||||||
jq
|
jq
|
||||||
kitty
|
kitty
|
||||||
lazygit
|
lazygit
|
||||||
(pkgs.writeShellScriptBin "lf" ''
|
lf
|
||||||
cd_file="/tmp/lf-lastdir"
|
|
||||||
|
|
||||||
${pkgs.lf}/bin/lf "$@"
|
|
||||||
|
|
||||||
if [ -f "$cd_file" ]; then
|
|
||||||
cd "$(cat "$cd_file")"
|
|
||||||
rm "$cd_file"
|
|
||||||
fi
|
|
||||||
'')
|
|
||||||
libreoffice
|
libreoffice
|
||||||
libvirt
|
libvirt
|
||||||
linux-firmware
|
linux-firmware
|
||||||
|
|
@ -113,11 +105,13 @@
|
||||||
thunderbird
|
thunderbird
|
||||||
tor-browser
|
tor-browser
|
||||||
unzip
|
unzip
|
||||||
|
usbutils
|
||||||
virt-manager
|
virt-manager
|
||||||
virt-viewer
|
virt-viewer
|
||||||
vscode-langservers-extracted
|
vscode-langservers-extracted
|
||||||
watchexec
|
watchexec
|
||||||
wayland
|
wayland
|
||||||
|
waypipe
|
||||||
wgsl-analyzer
|
wgsl-analyzer
|
||||||
# wineWowPackages.waylandFull
|
# wineWowPackages.waylandFull
|
||||||
wineWow64Packages.waylandFull
|
wineWow64Packages.waylandFull
|
||||||
|
|
@ -185,51 +179,6 @@
|
||||||
localNetworkGameTransfers.openFirewall = true;
|
localNetworkGameTransfers.openFirewall = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.firejail = {
|
|
||||||
enable = true;
|
|
||||||
wrappedBinaries = {
|
|
||||||
chromium-sandbox = {
|
|
||||||
executable = "${pkgs.chromium}/bin/chromium";
|
|
||||||
profile = "${pkgs.firejail}/etc/firejail/chromium-browser.profile";
|
|
||||||
extraArgs = [
|
|
||||||
"--netns=wg0ns"
|
|
||||||
"--whitelist=/home/user/downloads"
|
|
||||||
"--env=TGK_THEME=Adwaita:dark"
|
|
||||||
"--dns=10.2.0.1"
|
|
||||||
"--private=/data/sandbox/chromium"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
google-chrome-stable = {
|
|
||||||
# executable = "${chrome-argumented}/bin/google-chrome-stable";
|
|
||||||
executable = "${pkgs.google-chrome}/bin/google-chrome-stable";
|
|
||||||
profile = "${pkgs.firejail}/etc/firejail/google-chrome-stable.profile";
|
|
||||||
extraArgs = [
|
|
||||||
"--env=GTK_THEME=Adwaita:dark"
|
|
||||||
"--netns=wg-br0ns"
|
|
||||||
"--dns=10.2.0.1"
|
|
||||||
"--whitelist=/home/user/downloads"
|
|
||||||
"--whitelist=/home/user/pictures"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
tor-browser = {
|
|
||||||
executable = "${pkgs.tor-browser}/bin/tor-browser";
|
|
||||||
profile = "${pkgs.firejail}/etc/firejail/tor-browser-en-us.profile";
|
|
||||||
extraArgs = [
|
|
||||||
"--netns=wg0ns"
|
|
||||||
"--dns=1.1.1.1"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
freetube = {
|
|
||||||
executable = "${pkgs.freetube}/bin/freetube";
|
|
||||||
profile = "${pkgs.firejail}/etc/firejail/freetube.profile";
|
|
||||||
extraArgs = [
|
|
||||||
"--netns=wg0ns"
|
|
||||||
"--dns=1.1.1.1"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.ollama = {
|
services.ollama = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.ollama-cuda;
|
package = pkgs.ollama-cuda;
|
||||||
|
|
@ -239,6 +188,7 @@
|
||||||
"glm-5.1"
|
"glm-5.1"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
# services.input-remapper.enable = true;
|
||||||
# services.open-webui = {
|
# services.open-webui = {
|
||||||
# enable = true;
|
# enable = true;
|
||||||
# port = 11347;
|
# port = 11347;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
deepseek_api_key: ENC[AES256_GCM,data:HJXkEErncaOb2up0B45qisM+rIHoNmX9n6RZrdGN2JZlur8=,iv:4Dx5AjtDhWfYKlRiUrADT7HdHy/F2sfkzuPKuLhBRt4=,tag:AC3Zm+NHnnIQDCnlmBDUcQ==,type:str]
|
deepseek_api_key: ENC[AES256_GCM,data:HJXkEErncaOb2up0B45qisM+rIHoNmX9n6RZrdGN2JZlur8=,iv:4Dx5AjtDhWfYKlRiUrADT7HdHy/F2sfkzuPKuLhBRt4=,tag:AC3Zm+NHnnIQDCnlmBDUcQ==,type:str]
|
||||||
|
navidrome:
|
||||||
|
user: ENC[AES256_GCM,data:TkPLvX3AxC7Lbnh6s2j1q3XrQE1u16ykah9rSjlYPnuH,iv:dtjM4O4A4ABVyHQHPAUH5dVopgwLlKSUcbqFpCWV2eA=,tag:W2PVbIaLGbX4SR2ZNOGmsQ==,type:str]
|
||||||
root:
|
root:
|
||||||
password: ENC[AES256_GCM,data:qA7sbNvWvfmWiLX4pIYOzDmuCwc3+7I1KvTHHYF5jDHR0CNRuya0XglP8TNK5qGLEJkdmD9WphdWvYY60NTOf5NFhDnqtm3ZIw==,iv:B42jl40hQbRqMRfV39fNne0E3KKCwriAQ5MQ0DF4QQA=,tag:hH/u0Qw6A2is4XOOQpnr2Q==,type:str]
|
password: ENC[AES256_GCM,data:qA7sbNvWvfmWiLX4pIYOzDmuCwc3+7I1KvTHHYF5jDHR0CNRuya0XglP8TNK5qGLEJkdmD9WphdWvYY60NTOf5NFhDnqtm3ZIw==,iv:B42jl40hQbRqMRfV39fNne0E3KKCwriAQ5MQ0DF4QQA=,tag:hH/u0Qw6A2is4XOOQpnr2Q==,type:str]
|
||||||
ssh:
|
ssh:
|
||||||
|
|
@ -13,8 +15,7 @@ user:
|
||||||
legacy_rsa: ENC[AES256_GCM,data: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,iv:oGGm7bveDXNmxqe5Zina03vSVLJx9P3VBC/DbuI6KzY=,tag:taEL0E4Uinv1MQPxeRbPzA==,type:str]
|
legacy_rsa: ENC[AES256_GCM,data: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,iv:oGGm7bveDXNmxqe5Zina03vSVLJx9P3VBC/DbuI6KzY=,tag:taEL0E4Uinv1MQPxeRbPzA==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- recipient: age1y0tj3kt67pfnj38t9c8g2ghry3a0mhcq8rrqv5xr4jekwepxaelqzu3dkf
|
- enc: |
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOZ3dERmxMbEJmSVhVRmVw
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOZ3dERmxMbEJmSVhVRmVw
|
||||||
TUZZL0FzTHprci9ENHFodnRVWmRSbk1ab2xnCnZYeXN3MWRJZENlYmtWeFM0azdR
|
TUZZL0FzTHprci9ENHFodnRVWmRSbk1ab2xnCnZYeXN3MWRJZENlYmtWeFM0azdR
|
||||||
|
|
@ -22,8 +23,8 @@ sops:
|
||||||
bFhna3RyY1kxK0IyVWlnR2FpMXk3UjQKvJaecXqAecBljJ9cNcHX13nxSxVey3LG
|
bFhna3RyY1kxK0IyVWlnR2FpMXk3UjQKvJaecXqAecBljJ9cNcHX13nxSxVey3LG
|
||||||
NdvJaMfEV4m3SqRF7YUoTzGYhucYjtX58E5SuvHnaP2qa21aDF+AZQ==
|
NdvJaMfEV4m3SqRF7YUoTzGYhucYjtX58E5SuvHnaP2qa21aDF+AZQ==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age16v8w7q4wmn22hhakq2uzaus2508rhldm7lcwh0kukshzjzyhuqesqz44ze
|
recipient: age1y0tj3kt67pfnj38t9c8g2ghry3a0mhcq8rrqv5xr4jekwepxaelqzu3dkf
|
||||||
enc: |
|
- enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSZnV1T0JKTXoyeUlZQ3o4
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSZnV1T0JKTXoyeUlZQ3o4
|
||||||
QkR4OHZUbzQrbjdSK2VLTDNzMU9qdlUvVVUwClI4SDhMZTRDRXY3NlJSZ3REdmpJ
|
QkR4OHZUbzQrbjdSK2VLTDNzMU9qdlUvVVUwClI4SDhMZTRDRXY3NlJSZ3REdmpJ
|
||||||
|
|
@ -31,7 +32,8 @@ sops:
|
||||||
NVlzQlQvMVc2dHZNK2pEWk80MStwY1UK38mxk1dJWi6XRKSwzcDA9qt8i1Grw2KJ
|
NVlzQlQvMVc2dHZNK2pEWk80MStwY1UK38mxk1dJWi6XRKSwzcDA9qt8i1Grw2KJ
|
||||||
ac2EbJIFwYLOaMNOKF9hu+NrMdruRpU/2B8HlYYZjpNWmLb9jwI4wQ==
|
ac2EbJIFwYLOaMNOKF9hu+NrMdruRpU/2B8HlYYZjpNWmLb9jwI4wQ==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-05-04T12:41:30Z"
|
recipient: age16v8w7q4wmn22hhakq2uzaus2508rhldm7lcwh0kukshzjzyhuqesqz44ze
|
||||||
mac: ENC[AES256_GCM,data:OxKBSbx/NrkprIHTdI+iM2yMh1lhTMYuS7UO09NzxXHkyEoXtacDm7XtWIrELIxDIpqQGkousKcNRDmfiejzkpD6aLpdR1S0exXe1A+heWUMB9D+I+an51Nuv/LBGKeelK71RAq2H0VQZQgZd6OuzDECsK07lxnxUAWo8rxhScs=,iv:0cREbkAyUz1a6ze74MKmfeX8RJjMIrwgRoTPeGADEiE=,tag:DJaNf7gckCDoYLzzw+SRUg==,type:str]
|
lastmodified: "2026-07-05T22:42:52Z"
|
||||||
|
mac: ENC[AES256_GCM,data:La8bfH1u7pmukx9OZTUS9gdZODiYcY07dMU08kEkEeojHGoh/VAUrBK3Sj5W33WnbqpXnuiRKgF34mqVav5T9TE0ds31PMc/VceWkd5pJ2crCjbmlR6Zm/XCHgilIO4IoGlCO5Zz+LXpsPbD3vv1AwmzYBRwgik69vyWiXwT0UA=,iv:vSzK3eE+Jpy//dzdOT+PHmdOOKmNlbiFDeDdtZ9Lz9o=,tag:Fo6IUvyyMxWy1gsa7faV7w==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.12.2
|
version: 3.13.1
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,14 @@ wg-br0:
|
||||||
private_key: ENC[AES256_GCM,data:y8djTiZ00DIhdN1YNUNmjqCPeSUrS+YWKfr4iLT8h54fSlgDn1OPAoyJllM=,iv:Wz/EiISOlaiSXSIa4h8L2wJPm34rxpQkErpuqAR/uC8=,tag:RS100jf8INb12q6+hGQDiw==,type:str]
|
private_key: ENC[AES256_GCM,data:y8djTiZ00DIhdN1YNUNmjqCPeSUrS+YWKfr4iLT8h54fSlgDn1OPAoyJllM=,iv:Wz/EiISOlaiSXSIa4h8L2wJPm34rxpQkErpuqAR/uC8=,tag:RS100jf8INb12q6+hGQDiw==,type:str]
|
||||||
conf: ENC[AES256_GCM,data:3TJ34y3NI1wO2Oyh7D72t2WmlOq/pMS43Ck3gDFV9QPSC7E3GHtc86aZqRQm8qbRqnkJco1+nlJZmsC+BQdmW+U5RkRL7vUyDmrCyeDyJvEkNIJLzcFi4lppbYXG3A+fRO2l5guQA5qNSQmnyux51yY11/OCahoFEEenL1wH+R0ugMK/LIPwK0/Y2u7c+7SvNwwtK9xQUlb4azqUsdLX0xkUFbBje2BgN50BB2TxLZJexUNjOTW9TE57tw3yI4VjYEvIyBXOK4uuuST+TcNJY5B45tjd8PmO9vPYDw==,iv:BdNVbiMjzGtX0rzkLBb/YCDxqBv15L7bJcLTPzvt/yM=,tag:NmEMTPasBSsg1GSkYi/HxA==,type:str]
|
conf: ENC[AES256_GCM,data:3TJ34y3NI1wO2Oyh7D72t2WmlOq/pMS43Ck3gDFV9QPSC7E3GHtc86aZqRQm8qbRqnkJco1+nlJZmsC+BQdmW+U5RkRL7vUyDmrCyeDyJvEkNIJLzcFi4lppbYXG3A+fRO2l5guQA5qNSQmnyux51yY11/OCahoFEEenL1wH+R0ugMK/LIPwK0/Y2u7c+7SvNwwtK9xQUlb4azqUsdLX0xkUFbBje2BgN50BB2TxLZJexUNjOTW9TE57tw3yI4VjYEvIyBXOK4uuuST+TcNJY5B45tjd8PmO9vPYDw==,iv:BdNVbiMjzGtX0rzkLBb/YCDxqBv15L7bJcLTPzvt/yM=,tag:NmEMTPasBSsg1GSkYi/HxA==,type:str]
|
||||||
wg-us0:
|
wg-us0:
|
||||||
private_key: ENC[AES256_GCM,data:PWzeqoYLICXjYL5AV+dxUxYn6RL/tUMkfTMYhm+OdC85cPBPU135Ov15nUk=,iv:1CdiayG3F4xp3eid/ilboFUOL4Y92RUqipASOPT8Jl0=,tag:cJulFquSHjmKF+lUegp37Q==,type:str]
|
private_key: ENC[AES256_GCM,data:rouU6q7Qn8wu93YL+uAWKsItXK2d21rRbTLLURk15wmC8YUytt/Hx8XNCbk=,iv:6m4+yS1LIZMfwZrWkb/4I4ABFLca24G8Nz3UTMQw8Q8=,tag:eTR7MW7Y9m34S5CRKIWsLw==,type:str]
|
||||||
conf: ENC[AES256_GCM,data:x4bpjE/icVqe3lXHRNWf5W9w8EVAiNyqmFUR2LslSrEz0ekmJ4YDKDuU//+VoomsZzHhY6GhKtEVJ4Me/xY0G1+dSBBgpZlO8UyZVg8aydsVmA09fHYgwKovzHXc0XM9cbbovf2yyK8kO+X8e3ODy1dSu+a1SA3YsEp2G46kbRRxTdYazeHMJ+hJdmCONEvx0p0NcPlPAW8eZWEsAbVT/eQzB3TnF2THy/t4oWrn4r/MVvcsWgc1LJ3rVJ6L8RREU/PYBJoyDMgAs3DP79E8iOQS+bwdJj0+gcrP,iv:Ngqn/EA3QpOnBxz+slSyn+oOO33hLZlGhAg+RIlN+wI=,tag:BZFjGxI0nRsdPn99rvijdA==,type:str]
|
conf: ENC[AES256_GCM,data:QTc6Y4VOT0UQKY9il4p4dCGYiGRYYF6Pi80ytwMweMWr1aHNl3RyFfSkAtCW3GErO6Y2OUdiwukSBKpmP6DDmBMZfhH/bQzWTFX+bAbcMBD6Ql3rMYl3rZ7pfbAZpa5a/tnzsfK+0ee8GfAo9IKci5gq7ic6E5zD9IsNPNxUH4HWNWfpSfnQo4Z6V/S05/Yb+GH4gQuX/K/eLh1b/8oWePpcRSKaQSSDzEd2NtvAv8S2LUwJxg/QYSC0CxrOGWXGdaDE,iv:05MM/v8OjjwSijhLAqlLeohYMbyV932QvgWsPhaCXLI=,tag:qpgaYyb4jkEhJTI46RMvhA==,type:str]
|
||||||
wg-uk0:
|
wg-uk0:
|
||||||
private_key: ENC[AES256_GCM,data:r1BEMvO+Q/6VTuC7N/iqWf1Cyp4WZsUitVF14n5QXPzYK9PoWgPGylQQpmg=,iv:wR1gsHzzu0C629bs7yGW6evjdieONyzMnc9vvtTEh2Q=,tag:lMk4DuTDFtOW0heIJ0Ef2A==,type:str]
|
private_key: ENC[AES256_GCM,data:r1BEMvO+Q/6VTuC7N/iqWf1Cyp4WZsUitVF14n5QXPzYK9PoWgPGylQQpmg=,iv:wR1gsHzzu0C629bs7yGW6evjdieONyzMnc9vvtTEh2Q=,tag:lMk4DuTDFtOW0heIJ0Ef2A==,type:str]
|
||||||
conf: ENC[AES256_GCM,data:tCQaQEJ1Pa0jw96q/LRtqhAWes04GkGOUYAlZu3W3C9EGHj123dYZiWXcUgymSsi999M3RbO2mWNllSl17zkV1iGZAkA23aQLKDUU0/m/SSCLm2ohJOdLKkGeRK41TMGFRRydfYZJ9rg0iJdacfXrX2t4RGWgtprSlS2crOcrAQ+jhMjCNxKuAg0gaJyUh1lcTmOohe0aBiqxGJE+mc4mKMwCiUytNoprAc2TrnKUTQ7/eyIv9hn0PeRvLL59KFNrcVpCb7VRkufYpYlNtO1zyl2oczYzw+IXCHt,iv:S74FbQLM5sXhvoSaUD0wuMeAd7U4rL/dneaVS3ah8Bo=,tag:0U/k1Cyy4XbvmnlApg2BYg==,type:str]
|
conf: ENC[AES256_GCM,data:tCQaQEJ1Pa0jw96q/LRtqhAWes04GkGOUYAlZu3W3C9EGHj123dYZiWXcUgymSsi999M3RbO2mWNllSl17zkV1iGZAkA23aQLKDUU0/m/SSCLm2ohJOdLKkGeRK41TMGFRRydfYZJ9rg0iJdacfXrX2t4RGWgtprSlS2crOcrAQ+jhMjCNxKuAg0gaJyUh1lcTmOohe0aBiqxGJE+mc4mKMwCiUytNoprAc2TrnKUTQ7/eyIv9hn0PeRvLL59KFNrcVpCb7VRkufYpYlNtO1zyl2oczYzw+IXCHt,iv:S74FbQLM5sXhvoSaUD0wuMeAd7U4rL/dneaVS3ah8Bo=,tag:0U/k1Cyy4XbvmnlApg2BYg==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- recipient: age1y0tj3kt67pfnj38t9c8g2ghry3a0mhcq8rrqv5xr4jekwepxaelqzu3dkf
|
- enc: |
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtOHZSRkpBVVdUUk9OYUFH
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtOHZSRkpBVVdUUk9OYUFH
|
||||||
cVBra014WXJyRTJ0QWFKallLQlc0SXhNSlFBCmpwME92M2lCN2liVjZBRndlSVBk
|
cVBra014WXJyRTJ0QWFKallLQlc0SXhNSlFBCmpwME92M2lCN2liVjZBRndlSVBk
|
||||||
|
|
@ -22,8 +21,8 @@ sops:
|
||||||
OWhIdUxDcHB4Z3dTdDkyZWF6NEJCYzAKfPB9AZFQ08yqil+4AhIi6EMy8PXI4CAz
|
OWhIdUxDcHB4Z3dTdDkyZWF6NEJCYzAKfPB9AZFQ08yqil+4AhIi6EMy8PXI4CAz
|
||||||
lK4ON/M67T0UrlWN/m3pryOOr4Lj4oiZvdOR0BCO3kn4Pj0nq5jQOA==
|
lK4ON/M67T0UrlWN/m3pryOOr4Lj4oiZvdOR0BCO3kn4Pj0nq5jQOA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age16v8w7q4wmn22hhakq2uzaus2508rhldm7lcwh0kukshzjzyhuqesqz44ze
|
recipient: age1y0tj3kt67pfnj38t9c8g2ghry3a0mhcq8rrqv5xr4jekwepxaelqzu3dkf
|
||||||
enc: |
|
- enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMSC9Td1NTMzk2NlJDTDNM
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMSC9Td1NTMzk2NlJDTDNM
|
||||||
UVUzTSt1dGkrUVRGT1UzeXcwR1REN1U0dW5JCnNJRzdKZHVyR0dzaUw2TlVzQnQ2
|
UVUzTSt1dGkrUVRGT1UzeXcwR1REN1U0dW5JCnNJRzdKZHVyR0dzaUw2TlVzQnQ2
|
||||||
|
|
@ -31,7 +30,8 @@ sops:
|
||||||
OEZ4WUp1QlVrTkVTN1BHMG0yaXFuSk0KLw3ZuvWTurJDTpyoq5YafLm8YFT4v4Vh
|
OEZ4WUp1QlVrTkVTN1BHMG0yaXFuSk0KLw3ZuvWTurJDTpyoq5YafLm8YFT4v4Vh
|
||||||
s+ay8ju3kA1CKjMF3gBQF08EoCdP/jU6tZerNwwcs17el5zIvRmG7Q==
|
s+ay8ju3kA1CKjMF3gBQF08EoCdP/jU6tZerNwwcs17el5zIvRmG7Q==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-02-08T19:15:21Z"
|
recipient: age16v8w7q4wmn22hhakq2uzaus2508rhldm7lcwh0kukshzjzyhuqesqz44ze
|
||||||
mac: ENC[AES256_GCM,data:IxRNC13NPMIhVon0vCH3df+JxQlIPzv79H6JQzj8hkQNLxbFtPzk9DlHW1PWX90UAQbaXnzUM9uyHZhg4TypVsuKiEhpGyE4LXn/O7wD3U66YMkbqGrpKtnWbCQNdj///N5nDf71QwdLTEAzH+Kn9zRmiZ60rEu3w1Wm5vitB78=,iv:jWQvvO8kJDULepEUbWRym57whNpd23Q2PkXCDNQeJLo=,tag:wPBtn7Onr3S9ksEmdCZFzg==,type:str]
|
lastmodified: "2026-07-12T15:08:29Z"
|
||||||
|
mac: ENC[AES256_GCM,data:RiyjNVLep6kPx8oNno+v/GSCXQ0mo4SJFo54+KUyP/up79mPYTxLiuRsEZXO5P3d5pzMqMubQntDaMj8h6C4IJjojPIFvl4AeOveXkOeFz50ufeNBkwKEsDJgNNQfw/3vgq5rTR5WegsLzEMagXuDGwEJPA3uQQf0Ea2pXFO/Nw=,iv:YpTw0+Q+tBK3j3uEYiHLUzwygUFPrUanH8apNwpJwDM=,tag:o5opSInF5D9Q0OgB/7uf7Q==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.11.0
|
version: 3.13.1
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,13 @@
|
||||||
"noatime"
|
"noatime"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
"@downloads" = {
|
||||||
|
mountpoint = "/home/user/downloads";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
273
tailscale.nix
Normal file
273
tailscale.nix
Normal file
|
|
@ -0,0 +1,273 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.tailscale-netns;
|
||||||
|
|
||||||
|
instanceOptions =
|
||||||
|
{ name, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
authKeyFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = "Path to file containing a Tailscale auth key.";
|
||||||
|
};
|
||||||
|
|
||||||
|
hostname = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Tailscale hostname for this instance.
|
||||||
|
Defaults to "<system-hostname>-<instance-name>".
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
advertiseRoutes = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "Subnet routes to advertise (e.g. [ \"10.0.0.0/24\" ]).";
|
||||||
|
};
|
||||||
|
|
||||||
|
dns = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Bootstrap DNS server for the namespace before Tailscale is connected.
|
||||||
|
Defaults to `1.1.1.1`. Only used for the initial coordination server
|
||||||
|
connection; once Tailscale is up it manages DNS inside the namespace.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
advertiseExitNode = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to advertise this node as an exit node.";
|
||||||
|
};
|
||||||
|
|
||||||
|
acceptRoutes = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to accept routes advertised by other nodes.";
|
||||||
|
};
|
||||||
|
|
||||||
|
exitNode = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Tailscale IP or hostname of exit node to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraUpFlags = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "Extra flags passed to `tailscale up`.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraDaemonFlags = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "Extra flags passed to `tailscaled`.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkUpFlags =
|
||||||
|
instanceCfg:
|
||||||
|
let
|
||||||
|
hostFlag = optional (
|
||||||
|
instanceCfg.hostname != null
|
||||||
|
) "--hostname=${escapeShellArg instanceCfg.hostname}";
|
||||||
|
routeFlags = map (r: "--advertise-routes=${escapeShellArg r}") instanceCfg.advertiseRoutes;
|
||||||
|
exitFlag = optional instanceCfg.advertiseExitNode "--advertise-exit-node";
|
||||||
|
acceptFlag = optional instanceCfg.acceptRoutes "--accept-routes";
|
||||||
|
exitNodeFlag = optional (
|
||||||
|
instanceCfg.exitNode != null
|
||||||
|
) "--exit-node=${escapeShellArg instanceCfg.exitNode}";
|
||||||
|
in
|
||||||
|
hostFlag ++ routeFlags ++ exitFlag ++ acceptFlag ++ exitNodeFlag ++ instanceCfg.extraUpFlags;
|
||||||
|
|
||||||
|
mkAutoconnectScript =
|
||||||
|
name: instanceCfg:
|
||||||
|
pkgs.writers.writeBash "tailscale-autoconnect-${name}" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TS="${pkgs.tailscale}/bin/tailscale"
|
||||||
|
SOCKET="/run/tailscale-${name}/tailscaled.sock"
|
||||||
|
TS_ARGS="--socket $SOCKET"
|
||||||
|
|
||||||
|
get_state() {
|
||||||
|
$TS $TS_ARGS status --json --peers=false 2>/dev/null | ${pkgs.jq}/bin/jq -r '.BackendState // "NoState"'
|
||||||
|
}
|
||||||
|
|
||||||
|
last_state=""
|
||||||
|
while state="$(get_state)"; do
|
||||||
|
if [[ "$state" != "$last_state" ]]; then
|
||||||
|
case "$state" in
|
||||||
|
NeedsLogin|NeedsMachineAuth|Stopped)
|
||||||
|
echo "[tailscale-netns:${name}] server needs authentication, sending auth key"
|
||||||
|
$TS $TS_ARGS up \
|
||||||
|
--auth-key "$(cat ${instanceCfg.authKeyFile})" \
|
||||||
|
${escapeShellArgs (mkUpFlags instanceCfg)}
|
||||||
|
;;
|
||||||
|
Running)
|
||||||
|
echo "[tailscale-netns:${name}] tailscale is running"
|
||||||
|
${pkgs.systemd}/bin/systemd-notify --ready
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
NoState)
|
||||||
|
echo "[tailscale-netns:${name}] tailscaled not ready yet"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "[tailscale-netns:${name}] waiting for Running (state=$state)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
last_state="$state"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
|
||||||
|
mkNetnsSetup =
|
||||||
|
index: name: instanceCfg:
|
||||||
|
let
|
||||||
|
ns = "ts-${name}ns";
|
||||||
|
hostIP = "10.201.${toString index}.1/24";
|
||||||
|
nsIP = "10.201.${toString index}.2/24";
|
||||||
|
vethHost = "veth-ts-${name}";
|
||||||
|
vethNS = "veth-ts-${name}-ns";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"netns@ts-${name}" = {
|
||||||
|
description = "Network namespace for Tailscale instance ${name}";
|
||||||
|
before = [ "network.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = pkgs.writers.writeBash "ts-${name}-netns-up" ''
|
||||||
|
set -euo pipefail
|
||||||
|
${pkgs.coreutils}/bin/mkdir -p /etc/netns/${ns}
|
||||||
|
|
||||||
|
# Build resolv.conf for the netns. Skip loopback addresses
|
||||||
|
# (systemd-resolved stub at 127.0.0.53 is not reachable from the netns).
|
||||||
|
NS_DNS="${if instanceCfg.dns != null then instanceCfg.dns else "1.1.1.1"}"
|
||||||
|
{
|
||||||
|
${pkgs.gawk}/bin/awk '$1 == "nameserver" && $2 !~ /^127\./ && $2 != "::1" {print}' /etc/resolv.conf
|
||||||
|
echo "nameserver $NS_DNS"
|
||||||
|
} > /etc/netns/${ns}/resolv.conf
|
||||||
|
|
||||||
|
${pkgs.iproute2}/bin/ip netns add ${ns}
|
||||||
|
${pkgs.iproute2}/bin/ip link add ${vethHost} type veth peer name ${vethNS}
|
||||||
|
${pkgs.iproute2}/bin/ip link set ${vethNS} netns ${ns}
|
||||||
|
|
||||||
|
${pkgs.iproute2}/bin/ip addr add ${hostIP} dev ${vethHost}
|
||||||
|
${pkgs.iproute2}/bin/ip link set ${vethHost} up
|
||||||
|
|
||||||
|
${pkgs.iproute2}/bin/ip -n ${ns} addr add ${nsIP} dev ${vethNS}
|
||||||
|
${pkgs.iproute2}/bin/ip -n ${ns} link set ${vethNS} up
|
||||||
|
${pkgs.iproute2}/bin/ip -n ${ns} link set lo up
|
||||||
|
|
||||||
|
${pkgs.iptables}/bin/iptables -t nat -C POSTROUTING -s ${nsIP} -j MASQUERADE 2>/dev/null \
|
||||||
|
|| ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s ${nsIP} -j MASQUERADE
|
||||||
|
'';
|
||||||
|
ExecStop = pkgs.writers.writeBash "ts-${name}-netns-down" ''
|
||||||
|
set -euo pipefail
|
||||||
|
${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s ${nsIP} -j MASQUERADE 2>/dev/null || true
|
||||||
|
${pkgs.iproute2}/bin/ip link del ${vethHost} 2>/dev/null || true
|
||||||
|
${pkgs.iproute2}/bin/ip netns del ${ns} 2>/dev/null || true
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
"tailscaled-${name}" = {
|
||||||
|
description = "Tailscale daemon for instance ${name}";
|
||||||
|
bindsTo = [ "netns@ts-${name}.service" ];
|
||||||
|
after = [ "netns@ts-${name}.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = pkgs.writers.writeBash "tailscaled-${name}-start" ''
|
||||||
|
exec ${pkgs.iproute2}/bin/ip netns exec ${ns} \
|
||||||
|
${pkgs.tailscale}/bin/tailscaled \
|
||||||
|
--statedir=/var/lib/tailscale-${name} \
|
||||||
|
--socket=/run/tailscale-${name}/tailscaled.sock \
|
||||||
|
--tun=ts-${name} \
|
||||||
|
--port=41641 \
|
||||||
|
${escapeShellArgs instanceCfg.extraDaemonFlags}
|
||||||
|
'';
|
||||||
|
ExecStopPost = pkgs.writers.writeBash "tailscaled-${name}-stop" ''
|
||||||
|
${pkgs.iproute2}/bin/ip netns exec ${ns} \
|
||||||
|
${pkgs.tailscale}/bin/tailscaled --cleanup \
|
||||||
|
--statedir=/var/lib/tailscale-${name} \
|
||||||
|
--socket=/run/tailscale-${name}/tailscaled.sock \
|
||||||
|
2>/dev/null || true
|
||||||
|
'';
|
||||||
|
Restart = "on-failure";
|
||||||
|
RuntimeDirectory = "tailscale-${name}";
|
||||||
|
RuntimeDirectoryMode = "0755";
|
||||||
|
StateDirectory = "tailscale-${name}";
|
||||||
|
StateDirectoryMode = "0700";
|
||||||
|
CacheDirectory = "tailscale-${name}";
|
||||||
|
CacheDirectoryMode = "0750";
|
||||||
|
|
||||||
|
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_RAW";
|
||||||
|
LimitNOFILE = "infinity";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.tailscale-netns = {
|
||||||
|
enable = mkEnableOption "Tailscale instances in isolated network namespaces";
|
||||||
|
|
||||||
|
instances = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule instanceOptions);
|
||||||
|
default = { };
|
||||||
|
description = "Tailscale instances configured in separate network namespaces.";
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
work = {
|
||||||
|
authKeyFile = "/run/secrets/ts-work/authkey";
|
||||||
|
acceptRoutes = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services = listToAttrs (
|
||||||
|
flatten (
|
||||||
|
imap1 (
|
||||||
|
index: elem:
|
||||||
|
let
|
||||||
|
name = elem.name;
|
||||||
|
instanceCfg = elem.value;
|
||||||
|
units = mkNetnsSetup index name instanceCfg;
|
||||||
|
in
|
||||||
|
[
|
||||||
|
units."netns@ts-${name}"
|
||||||
|
units."tailscaled-${name}"
|
||||||
|
]
|
||||||
|
++ optional (instanceCfg.authKeyFile != null) {
|
||||||
|
"tailscaled-autoconnect-${name}" = {
|
||||||
|
description = "Tailscale autoconnect for instance ${name}";
|
||||||
|
after = [ "tailscaled-${name}.service" ];
|
||||||
|
requires = [ "tailscaled-${name}.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "notify";
|
||||||
|
};
|
||||||
|
script = "${mkAutoconnectScript name instanceCfg}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) (attrsToList cfg.instances)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
37
users.nix
37
users.nix
|
|
@ -7,7 +7,7 @@
|
||||||
imports = [
|
imports = [
|
||||||
./home/user.nix
|
./home/user.nix
|
||||||
./home/root.nix
|
./home/root.nix
|
||||||
./home/agents.nix
|
# ./home/agents.nix
|
||||||
];
|
];
|
||||||
sops.secrets."user/password" = {
|
sops.secrets."user/password" = {
|
||||||
neededForUsers = true;
|
neededForUsers = true;
|
||||||
|
|
@ -41,26 +41,25 @@
|
||||||
# ];
|
# ];
|
||||||
# linger = true;
|
# linger = true;
|
||||||
# };
|
# };
|
||||||
agent = {
|
# agent = {
|
||||||
uid = 1002;
|
# uid = 1002;
|
||||||
homeMode = "770";
|
|
||||||
home = "/home/agent";
|
|
||||||
shell = pkgs.fish;
|
|
||||||
isNormalUser = true;
|
|
||||||
group = "agent";
|
|
||||||
extraGroups = [ "public" ];
|
|
||||||
linger = true;
|
|
||||||
};
|
|
||||||
# sandbox = {
|
|
||||||
# uid = 1003;
|
|
||||||
# homeMode = "770";
|
# homeMode = "770";
|
||||||
# home = "/home/sandbox";
|
# home = "/home/agent";
|
||||||
# shell = pkgs.fish;
|
# shell = pkgs.fish;
|
||||||
# isNormalUser = true;
|
# isNormalUser = true;
|
||||||
# group = "sandbox";
|
# group = "agent";
|
||||||
# extraGroups = [ "public" ];
|
# extraGroups = [ "public" ];
|
||||||
# linger = true;
|
# linger = true;
|
||||||
# };
|
# };
|
||||||
|
sandbox = {
|
||||||
|
uid = 1001;
|
||||||
|
homeMode = "770";
|
||||||
|
home = "/home/sandbox";
|
||||||
|
shell = pkgs.fish;
|
||||||
|
isNormalUser = true;
|
||||||
|
group = "users";
|
||||||
|
linger = true;
|
||||||
|
};
|
||||||
user = {
|
user = {
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
homeMode = "700";
|
homeMode = "700";
|
||||||
|
|
@ -72,12 +71,11 @@
|
||||||
"libvirt"
|
"libvirt"
|
||||||
"systemd-journal"
|
"systemd-journal"
|
||||||
"kvm"
|
"kvm"
|
||||||
"public"
|
|
||||||
"agent"
|
|
||||||
"sandbox"
|
|
||||||
"audio"
|
"audio"
|
||||||
"video"
|
"video"
|
||||||
|
"render"
|
||||||
"bluetooth"
|
"bluetooth"
|
||||||
|
"users"
|
||||||
# "work"
|
# "work"
|
||||||
];
|
];
|
||||||
hashedPasswordFile = config.sops.secrets."user/password".path;
|
hashedPasswordFile = config.sops.secrets."user/password".path;
|
||||||
|
|
@ -86,9 +84,6 @@
|
||||||
};
|
};
|
||||||
groups = {
|
groups = {
|
||||||
user.gid = 1000;
|
user.gid = 1000;
|
||||||
agent.gid = 1002;
|
|
||||||
public.gid = 777;
|
|
||||||
# sandbox.gid = 1003;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue