19 Commits

Author SHA1 Message Date
57cb48a11c feat(gaming): cleaning up gaming related pkgs 2025-10-11 16:44:54 +02:00
6b7ca2b194 feat(update): new kernel, new container versions and temporarily moving to zfs_unstable in waiting for stable to catch up with new kernel 2025-10-11 11:04:15 +02:00
e578a280db chore(update): flake lock and removing unmaintained pkgs 2025-10-11 09:40:35 +02:00
01ca3d7ebe feat(gitea): integrate with authentik 2025-10-08 20:39:54 +02:00
46aa5a9deb fix(fail2ban): some hacky fix 2025-10-07 21:05:43 +02:00
549037fe69 chore(flake) lock 2025-10-06 21:00:09 +02:00
0cb6862dcd feat(sqlite): adding sqlite pkgs 2025-10-06 20:57:01 +02:00
9e4454ff57 feat(gitea): move to cnst.dev domain, cf tunnel 2025-10-06 20:55:31 +02:00
15a20dd8e0 feat(pkgs): adding some dev pkgs to sobotka and dig as default 2025-10-05 19:27:15 +02:00
3306598f8a feat(jellyfin): adding to tnet 2025-10-05 19:10:43 +02:00
93f227ba7e feat(network): adding options for dns and search 2025-10-05 15:40:52 +02:00
9d20eff7f9 feat(jellyfin): TS testing 2025-10-05 10:47:08 +02:00
94d3f2ad35 feat(jellyfin): will this break things? 2025-10-05 10:35:22 +02:00
1d5bc22274 Merge branch 'main' into working 2025-10-05 10:21:16 +02:00
f2386a851e working 1 2025-10-05 10:11:40 +02:00
c9edc99a85 chore(revert): slowly introducing changes 2025-10-05 09:27:51 +02:00
67e83e3e4e feat(authentik): fixing some fail2ban things 2025-10-02 05:45:35 +02:00
923c810972 feat(authentik): fixing some fail2ban things 2025-10-01 18:00:55 +02:00
6ab35f4e91 feat(www): fixing fail2ban and other minor tweaks 2025-09-30 18:16:49 +02:00
29 changed files with 490 additions and 316 deletions

154
flake.lock generated
View File

@@ -29,11 +29,11 @@
"systems": "systems_2" "systems": "systems_2"
}, },
"locked": { "locked": {
"lastModified": 1758874004, "lastModified": 1760083914,
"narHash": "sha256-+RUCBtT01Z595NpGc6Tvms+dJ/C/cn1zdjT9+gE6dbU=", "narHash": "sha256-I9IMO9d+z71oeqOz6gOre07tK2Du3vp2FcOW3x4FDXw=",
"owner": "anyrun-org", "owner": "anyrun-org",
"repo": "anyrun", "repo": "anyrun",
"rev": "3c571bc1514c4211d1d6c011a1d482f97efd9c5f", "rev": "3050aa30e25957bbb9e1ac91a44d3979eccadf59",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -153,11 +153,11 @@
"rust-overlay": "rust-overlay" "rust-overlay": "rust-overlay"
}, },
"locked": { "locked": {
"lastModified": 1759532138, "lastModified": 1760148209,
"narHash": "sha256-sLQIlgDwMP3mEY2PwjGW+cL56QQ2n2WXoZ3GpG5QWOY=", "narHash": "sha256-ssMUeLk1cmLqzNMW6l9dgGoLtOY9F9dEGplJlWJmNis=",
"owner": "chaotic-cx", "owner": "chaotic-cx",
"repo": "nyx", "repo": "nyx",
"rev": "bad02bbca5b5c6d45539a0d740ad0e21b1ba9afc", "rev": "b51bb724939dbfa264f08522efffce2bb47b6135",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -212,11 +212,11 @@
"rust-analyzer-src": "rust-analyzer-src" "rust-analyzer-src": "rust-analyzer-src"
}, },
"locked": { "locked": {
"lastModified": 1759560021, "lastModified": 1760164678,
"narHash": "sha256-J/rtMKVUAEqOFj0ogvcHKK8HbaKhw+tiNrDOpEM+ZDY=", "narHash": "sha256-yxcfwZCysR6zPaFv7is3/FWd1h0h6kXME0vueSwTBhU=",
"owner": "nix-community", "owner": "nix-community",
"repo": "fenix", "repo": "fenix",
"rev": "6ffcbf59c119b0c6384c7d98f18cea06a9af7e9c", "rev": "2579f163559b902959cc420a6d3bfbd98c46a323",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -571,11 +571,11 @@
}, },
"hardware": { "hardware": {
"locked": { "locked": {
"lastModified": 1759582739, "lastModified": 1760106635,
"narHash": "sha256-spZegilADH0q5OngM86u6NmXxduCNv5eX9vCiUPhOYc=", "narHash": "sha256-2GoxVaKWTHBxRoeUYSjv0AfSOx4qw5CWSFz2b+VolKU=",
"owner": "nixos", "owner": "nixos",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "3441b5242af7577230a78ffb03542add264179ab", "rev": "9ed85f8afebf2b7478f25db0a98d0e782c0ed903",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -590,11 +590,11 @@
"rust-overlay": "rust-overlay_2" "rust-overlay": "rust-overlay_2"
}, },
"locked": { "locked": {
"lastModified": 1759201995, "lastModified": 1759850138,
"narHash": "sha256-3STv6fITv8Ar/kl0H7vIA7VV0d2gyLh8UL0BOiVacXg=", "narHash": "sha256-fYHIxjTvVIAEDWzenUROuzDPxy1rBCXZNPgh4b1dfgo=",
"owner": "helix-editor", "owner": "helix-editor",
"repo": "helix", "repo": "helix",
"rev": "bfcbef10c513108c7b43317569416c2eefc4ed44", "rev": "5b0563419eeeaf0595c848865c46be4abad246a7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -610,11 +610,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759573136, "lastModified": 1760130406,
"narHash": "sha256-ILSPD0Dm8p0w0fCVzOx98ZH8yFDrR75GmwmH3fS2VnE=", "narHash": "sha256-GKMwBaFRw/C1p1VtjDz4DyhyzjKUWyi1K50bh8lgA2E=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "5f06ceafc6c9b773a776b9195c3f47bbe1defa43", "rev": "d305eece827a3fe317a2d70138f53feccaf890a1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -652,11 +652,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759337100, "lastModified": 1760061988,
"narHash": "sha256-CcT3QvZ74NGfM+lSOILcCEeU+SnqXRvl1XCRHenZ0Us=", "narHash": "sha256-CeuMo7fjWm3XaoK+b1PGyaVIlE1GHudoxk9jrJFvfbY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "004753ae6b04c4b18aa07192c1106800aaacf6c3", "rev": "c7f4214faca2f196c551b767c12a70bfa0614510",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -739,11 +739,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1750621377, "lastModified": 1759490292,
"narHash": "sha256-8u6b5oAdX0rCuoR8wFenajBRmI+mzbpNig6hSCuWUzE=", "narHash": "sha256-T6iWzDOXp8Wv0KQOCTHpBcmAOdHJ6zc/l9xaztW6Ivc=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprgraphics", "repo": "hyprgraphics",
"rev": "b3d628d01693fb9bb0a6690cd4e7b80abda04310", "rev": "9431db625cd9bb66ac55525479dce694101d6d7a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -803,11 +803,11 @@
"xdph": "xdph" "xdph": "xdph"
}, },
"locked": { "locked": {
"lastModified": 1759530922, "lastModified": 1760143218,
"narHash": "sha256-9NgZKpibALekGTPDc2O8lP8vFealQSZkXe+L+S7MMZU=", "narHash": "sha256-OhJPROcRcwBkjOKkXr/f3/7wuSjhAIqr8WfmEUF9Uuo=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprland", "repo": "hyprland",
"rev": "76d998743ac10e712238c1016db4d8e8d16f1049", "rev": "d599513d4a72d66ac62ffdedc41d6653fa81b39e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -824,11 +824,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759238633, "lastModified": 1759613406,
"narHash": "sha256-4/AtRCQKXuU49ozZZouWuC+T7vCjQh9HAz3N8Tt5OZE=", "narHash": "sha256-PzgQJydp+RlKvwDi807pXPlURdIAVqLppZDga3DwPqg=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "contrib", "repo": "contrib",
"rev": "513d71d3f42c05d6a38e215382c5a6ce971bd77d", "rev": "32e1a75b65553daefb419f0906ce19e04815aa3a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1006,11 +1006,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759572448, "lastModified": 1760023949,
"narHash": "sha256-o+r44fqPQM+/hQdjFy9qV9C51Jhty6M4icFVYocyJfA=", "narHash": "sha256-fu0B4duamVdbkPio/czu1XhsPLRXUJpZLDrSk3nih4U=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprlock", "repo": "hyprlock",
"rev": "c8a6768dca626cf7d7cbc333095f048bc007b6d9", "rev": "36ec73f166d9434a3f27c96c575198906f77644a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1044,11 +1044,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1754481642, "lastModified": 1760120448,
"narHash": "sha256-e1phd6KwtUsS9C2ShD+fQvfk2Dgr2JQi+rTDQUW15iE=", "narHash": "sha256-l/OxM4q/nLVv47OuS4bG2J7k0m+G7/3AMtvrV64XLb0=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprpaper", "repo": "hyprpaper",
"rev": "bcb1ffa322369c4898347ab5a7399a3d18494c8f", "rev": "1733e0025b194c9bc083f4cd8782c5f151858a58",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1069,11 +1069,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759490926, "lastModified": 1759619523,
"narHash": "sha256-7IbZGJ5qAAfZsGhBHIsP8MBsfuFYS0hsxYHVkkeDG5Q=", "narHash": "sha256-r1ed7AR2ZEb2U8gy321/Xcp1ho2tzn+gG1te/Wxsj1A=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprutils", "repo": "hyprutils",
"rev": "94cce794344538c4d865e38682684ec2bbdb2ef3", "rev": "3df7bde01efb3a3e8e678d1155f2aa3f19e177ef",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1144,11 +1144,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1750371869, "lastModified": 1755184602,
"narHash": "sha256-lGk4gLjgZQ/rndUkzmPYcgbHr8gKU5u71vyrjnwfpB4=", "narHash": "sha256-RCBQN8xuADB0LEgaKbfRqwm6CdyopE1xIEhNc67FAbw=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprwayland-scanner", "repo": "hyprwayland-scanner",
"rev": "aa38edd6e3e277ae6a97ea83a69261a5c3aab9fd", "rev": "b3b0f1f40ae09d4447c20608e5a4faf8bf3c492d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1191,11 +1191,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759387127, "lastModified": 1759815224,
"narHash": "sha256-uuwJAP92SkHmnI1zo7rrK/gEuHtb97vFZcMa5w+0SZA=", "narHash": "sha256-HbdOyjqHm38j6o5mV24i0bn+r5ykS+VJBnWJuZ0fE+A=",
"owner": "Jovian-Experiments", "owner": "Jovian-Experiments",
"repo": "Jovian-NixOS", "repo": "Jovian-NixOS",
"rev": "0cc290e05882745060fccfe6d7d073f913e0cce7", "rev": "ee974f496a080c61b3164992c850f43741edcc52",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1278,11 +1278,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759455985, "lastModified": 1760146997,
"narHash": "sha256-8qDv7NXH3fj1CDXed7c7vJLtrRKDZSo0x6TaWSfelVg=", "narHash": "sha256-x2sF8Q4tWz3DI166s+KFDXySrK+cN+/YEd3DfhnhBLQ=",
"owner": "fufexan", "owner": "fufexan",
"repo": "nix-gaming", "repo": "nix-gaming",
"rev": "eb5ab503cbd3cb386e8d85a55a9faed73ec7dc37", "rev": "ad505387568d024654da88fef03d9c5319cba92f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1363,11 +1363,11 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1759147044, "lastModified": 1760038930,
"narHash": "sha256-3ZPFytJOcLjTChljeaGgoaNj+tOqzgEpqZAvRe3bU90=", "narHash": "sha256-Oncbh0UmHjSlxO7ErQDM3KM0A5/Znfofj2BSzlHLeVw=",
"owner": "PedroHLC", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "18e83bbe13aa50992777832b52bd0e0d8585fb3b", "rev": "0b4defa2584313f3b781240b29d61f6f9f7e0df3",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1395,11 +1395,11 @@
}, },
"nixpkgs_5": { "nixpkgs_5": {
"locked": { "locked": {
"lastModified": 1740560979, "lastModified": 1759381078,
"narHash": "sha256-Vr3Qi346M+8CjedtbyUevIGDZW8LcA1fTG0ugPY/Hic=", "narHash": "sha256-gTrEEp5gEspIcCOx9PD8kMaF1iEmfBcTbO0Jag2QhQs=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5135c59491985879812717f4c9fea69604e7f26f", "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1443,11 +1443,11 @@
}, },
"nixpkgs_8": { "nixpkgs_8": {
"locked": { "locked": {
"lastModified": 1759381078, "lastModified": 1760038930,
"narHash": "sha256-gTrEEp5gEspIcCOx9PD8kMaF1iEmfBcTbO0Jag2QhQs=", "narHash": "sha256-Oncbh0UmHjSlxO7ErQDM3KM0A5/Znfofj2BSzlHLeVw=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", "rev": "0b4defa2584313f3b781240b29d61f6f9f7e0df3",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1482,11 +1482,11 @@
"systems": "systems_5" "systems": "systems_5"
}, },
"locked": { "locked": {
"lastModified": 1759469269, "lastModified": 1760153667,
"narHash": "sha256-DP833ejGUNRRHsJOB3WRTaWWXLNucaDga2ju/fGe+sc=", "narHash": "sha256-F7KmXT/Izse6Q6CkD5GCImoGPaDJxl03Kd7eD+eY/bU=",
"owner": "notashelf", "owner": "notashelf",
"repo": "nvf", "repo": "nvf",
"rev": "e48638aef3a95377689de0ef940443c64f870a09", "rev": "9df9d51fd9fc8f9a8fc377f984ea3b7ae796172d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1626,11 +1626,11 @@
"rust-analyzer-src": { "rust-analyzer-src": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1759301569, "lastModified": 1760090851,
"narHash": "sha256-7StxDed3v2fAWLkl+Hse9FlpjT7Dk7Cn/4vxTFyEhIg=", "narHash": "sha256-XGkBjf4Dzg6tXd0KGgKzeW4oVX/iLzLhD3rQ1cATpqM=",
"owner": "rust-lang", "owner": "rust-lang",
"repo": "rust-analyzer", "repo": "rust-analyzer",
"rev": "472037b789cf593172d6adf3b8d9f7a429f6cd9b", "rev": "b93180b4f2cb3c81ac7f17f46e3dfcb30ecc7843",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1648,11 +1648,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759458749, "lastModified": 1760063676,
"narHash": "sha256-WKnbJnm1B2+TO2ZUudgS39EzecQeLl4/bnRtd3y46LI=", "narHash": "sha256-s5Fjh43skH2L+avOGioLmEHoYZffDbg3abV5h0gjeew=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "bbc3a8ae797d1700e57a4f4bcc4e79af727d4138", "rev": "897deed0923cc5a1d560c5176abe0d172ec9716d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1669,11 +1669,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1740623427, "lastModified": 1759631821,
"narHash": "sha256-3SdPQrZoa4odlScFDUHd4CUPQ/R1gtH4Mq9u8CBiK8M=", "narHash": "sha256-V8A1L0FaU/aSXZ1QNJScxC12uP4hANeRBgI4YdhHeRM=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "d342e8b5fd88421ff982f383c853f0fc78a847ab", "rev": "1d7cbdaad90f8a5255a89a6eddd8af24dc89cafe",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1815,11 +1815,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1758728421, "lastModified": 1760120816,
"narHash": "sha256-ySNJ008muQAds2JemiyrWYbwbG+V7S5wg3ZVKGHSFu8=", "narHash": "sha256-gq9rdocpmRZCwLS5vsHozwB6b5nrOBDNc2kkEaTXHfg=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "5eda4ee8121f97b218f7cc73f5172098d458f1d1", "rev": "761ae7aff00907b607125b2f57338b74177697ed",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1923,11 +1923,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1759590499, "lastModified": 1759969704,
"narHash": "sha256-EBToRzqe5WMz4DQyxOp9/CP+rWjdaZ2EUwbItfNf3VI=", "narHash": "sha256-T7f/invcFIKHrBqD+FLf/C/HOGmpYfbZUzTDxFscpOA=",
"ref": "refs/heads/main", "ref": "refs/heads/main",
"rev": "6e606c8bfa6a88209488790388b1005bc489fa66", "rev": "1173c777dc8daddcc4959260a7b00fd8abc884c5",
"revCount": 136, "revCount": 137,
"type": "git", "type": "git",
"url": "https://git.sr.ht/~canasta/zen-browser-flake" "url": "https://git.sr.ht/~canasta/zen-browser-flake"
}, },

View File

@@ -29,6 +29,13 @@
}; };
network = { network = {
enable = true; enable = true;
nameservers = [
"192.168.88.1"
"192.168.88.69"
];
search = [
"taila7448a.ts.net"
];
interfaces = { interfaces = {
"eno1" = { "eno1" = {
allowedTCPPorts = [ allowedTCPPorts = [
@@ -66,7 +73,7 @@
}; };
}; };
gamescope = { gamescope = {
enable = true; enable = false;
}; };
gimp = { gimp = {
enable = true; enable = true;

View File

@@ -68,7 +68,10 @@ in {
boot = { boot = {
supportedFilesystems = ["zfs"]; supportedFilesystems = ["zfs"];
zfs.extraPools = ["data"]; zfs = {
package = pkgs.zfs_unstable;
extraPools = ["data"];
};
}; };
services.zfs = { services.zfs = {

View File

@@ -109,7 +109,7 @@
enable = true; enable = true;
}; };
dev = { dev = {
enable = false; enable = true;
}; };
}; };
mysql-workbench = { mysql-workbench = {
@@ -214,7 +214,7 @@
flags = "--performance"; flags = "--performance";
}; };
tailscale = { tailscale = {
enable = true; enable = false;
}; };
udisks = { udisks = {
enable = true; enable = true;

View File

@@ -11,7 +11,7 @@
traefik = { traefik = {
enable = true; enable = true;
}; };
gitea = { tailscale = {
enable = true; enable = true;
}; };
unbound = { unbound = {
@@ -47,6 +47,14 @@
uptime-kuma = { uptime-kuma = {
enable = true; enable = true;
}; };
gitea = {
enable = true;
url = "git.cnst.dev";
cloudflared = {
tunnelId = "33e2fb8e-ecef-4d42-b845-6d15e216e448";
credentialsFile = config.age.secrets.giteaCloudflared.path;
};
};
vaultwarden = { vaultwarden = {
enable = true; enable = true;
url = "vault.cnst.dev"; url = "vault.cnst.dev";

View File

@@ -144,6 +144,7 @@
./server/traefik ./server/traefik
./server/www ./server/www
./server/authentik ./server/authentik
./server/tailscale
]; ];
}; };
settings = { settings = {

View File

@@ -88,7 +88,7 @@ in
hyprpicker hyprpicker
libnotify libnotify
pamixer pamixer
oculante loupe
adwaita-icon-theme adwaita-icon-theme
qt5.qtwayland qt5.qtwayland
qt6.qtwayland qt6.qtwayland

View File

@@ -84,15 +84,15 @@ in
"application/pdf" = "org.pwmt.zathura-pdf-mupdf.desktop"; "application/pdf" = "org.pwmt.zathura-pdf-mupdf.desktop";
"inode/directory" = "thunar.desktop"; "inode/directory" = "thunar.desktop";
"image/apng" = "oculante.desktop"; "image/apng" = "feh.desktop";
"image/avif" = "oculante.desktop"; "image/avif" = "feh.desktop";
"image/bmp" = "oculante.desktop"; "image/bmp" = "feh.desktop";
"image/gif" = "oculante.desktop"; "image/gif" = "feh.desktop";
"image/jpeg" = "oculante.desktop"; "image/jpeg" = "feh.desktop";
"image/png" = "oculante.desktop"; "image/png" = "feh.desktop";
"image/svg+xml" = "oculante.desktop"; "image/svg+xml" = "feh.desktop";
"image/tiff" = "oculante.desktop"; "image/tiff" = "feh.desktop";
"image/webp" = "oculante.desktop"; "image/webp" = "feh.desktop";
"video/H264" = [ "video/H264" = [
"mpv.desktop" "mpv.desktop"

View File

@@ -2,38 +2,47 @@
config, config,
lib, lib,
... ...
}: }: let
let inherit
inherit (lib) (lib)
mkIf mkIf
mkEnableOption mkEnableOption
mkOption mkOption
types types
; ;
cfg = config.nixos.hardware.network; cfg = config.nixos.hardware.network;
in in {
{
options = { options = {
nixos.hardware.network = { nixos.hardware.network = {
enable = mkEnableOption "Enable the custom networking module"; enable = mkEnableOption "Enable the custom networking module";
nameservers = mkOption {
type = types.listOf types.str;
default = [];
description = "The list of nameservers ";
};
search = mkOption {
type = types.listOf types.str;
default = [];
description = "Domain search paths";
};
interfaces = mkOption { interfaces = mkOption {
type = types.attrsOf ( type = types.attrsOf (
types.submodule { types.submodule {
options = { options = {
allowedTCPPorts = mkOption { allowedTCPPorts = mkOption {
type = types.listOf types.int; type = types.listOf types.int;
default = [ ]; default = [];
description = "List of allowed TCP ports for this interface."; description = "List of allowed TCP ports for this interface.";
}; };
allowedUDPPorts = mkOption { allowedUDPPorts = mkOption {
type = types.listOf types.int; type = types.listOf types.int;
default = [ ]; default = [];
description = "List of allowed UDP ports for this interface."; description = "List of allowed UDP ports for this interface.";
}; };
}; };
} }
); );
default = { }; default = {};
description = "Network interface configurations."; description = "Network interface configurations.";
}; };
extraHosts = mkOption { extraHosts = mkOption {
@@ -47,7 +56,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = [
{ {
assertion = cfg.interfaces != { } -> config.networking.networkmanager.enable; assertion = cfg.interfaces != {} -> config.networking.networkmanager.enable;
message = "Network interfaces configured but NetworkManager is not enabled"; message = "Network interfaces configured but NetworkManager is not enabled";
} }
]; ];
@@ -55,6 +64,8 @@ in
networking = { networking = {
networkmanager.enable = true; networkmanager.enable = true;
nftables.enable = true; nftables.enable = true;
nameservers = cfg.nameservers;
search = cfg.search;
firewall = { firewall = {
enable = true; enable = true;
inherit (cfg) interfaces; inherit (cfg) interfaces;
@@ -63,8 +74,8 @@ in
}; };
systemd.services.NetworkManager = { systemd.services.NetworkManager = {
wants = [ "nftables.service" ]; wants = ["nftables.service"];
after = [ "nftables.service" ]; after = ["nftables.service"];
}; };
}; };
} }

View File

@@ -78,6 +78,7 @@ in
openssl openssl
xmrig xmrig
ocl-icd ocl-icd
dig
] ]
(mkIf cfg.common.enable [ (mkIf cfg.common.enable [
@@ -96,9 +97,6 @@ in
]) ])
(mkIf cfg.desktop.enable [ (mkIf cfg.desktop.enable [
protonup
winetricks
wine
geekbench geekbench
unigine-heaven unigine-heaven
]) ])
@@ -109,15 +107,13 @@ in
(mkIf cfg.server.enable [ (mkIf cfg.server.enable [
nvtopPackages.intel nvtopPackages.intel
nvtopPackages.amd
dig
helix helix
zfs
zfstools zfstools
]) ])
(mkIf cfg.dev.enable [ (mkIf cfg.dev.enable [
# lldb_20 # some biuld error atm # lldb_20 # some biuld error atm
sqlite
gemini-cli gemini-cli
nfs-utils nfs-utils
gcc gcc
@@ -144,7 +140,6 @@ in
prettierd prettierd
# php84Packages.php-cs-fixer # php84Packages.php-cs-fixer
shfmt shfmt
luaformatter
black black
]) ])
]; ];

View File

@@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
pkgs,
... ...
}: }:
let let
@@ -17,6 +18,20 @@ in
enable = true; enable = true;
gamescopeSession.enable = true; gamescopeSession.enable = true;
}; };
gamescope = {
enable = true;
capSysNice = true;
args = [
"--rt"
"--expose-wayland"
];
};
}; };
environment.systemPackages = with pkgs; [
protonup
wine
winetricks
wine-wayland
];
}; };
} }

View File

@@ -45,7 +45,6 @@ in
# nodePackages_latest.sql-formatter # nodePackages_latest.sql-formatter
prettierd prettierd
shfmt shfmt
luaformatter
black black
]; ];
}; };

View File

@@ -53,11 +53,9 @@ in {
age.secrets = { age.secrets = {
authentikEnv = { authentikEnv = {
file = "${self}/secrets/authentikEnv.age"; file = "${self}/secrets/authentikEnv.age";
owner = "authentik";
}; };
authentikCloudflared = { authentikCloudflared = {
file = "${self}/secrets/authentikCloudflared.age"; file = "${self}/secrets/authentikCloudflared.age";
owner = "authentik";
}; };
}; };
@@ -65,8 +63,8 @@ in {
fail2ban = lib.mkIf cfg.enable { fail2ban = lib.mkIf cfg.enable {
jails = { jails = {
authentik = { authentik = {
serviceName = "${cfg.url}"; serviceName = "authentik";
failRegex = "^.*Username or password is incorrect. Try again. IP: <HOST>. Username: <F-USER>.*</F-USER>.$"; failRegex = ''^.*Username or password is incorrect.*IP:\s*<HOST>'';
}; };
}; };
}; };
@@ -99,7 +97,6 @@ in {
middlewares = { middlewares = {
authentik = { authentik = {
forwardAuth = { forwardAuth = {
tls.insecureSkipVerify = true;
address = "https://localhost:9443/outpost.goauthentik.io/auth/traefik"; address = "https://localhost:9443/outpost.goauthentik.io/auth/traefik";
trustForwardHeader = true; trustForwardHeader = true;
authResponseHeaders = [ authResponseHeaders = [
@@ -130,7 +127,7 @@ in {
routers = { routers = {
auth = { auth = {
entryPoints = ["websecure"]; entryPoints = ["websecure"];
rule = "Host(`${cfg.url}`) || HostRegexp(`{subdomain:[a-z0-9]+}.${srv.www.url}`) && PathPrefix(`/outpost.goauthentik.io/`)"; rule = "Host(`${cfg.url}`) && PathPrefix(`/outpost.goauthentik.io/`)";
service = "auth"; service = "auth";
tls.certResolver = "letsencrypt"; tls.certResolver = "letsencrypt";
}; };

View File

@@ -4,11 +4,9 @@
config, config,
pkgs, pkgs,
... ...
}: }: let
let
cfg = config.server.fail2ban; cfg = config.server.fail2ban;
in in {
{
options.server.fail2ban = { options.server.fail2ban = {
enable = lib.mkEnableOption { enable = lib.mkEnableOption {
description = "Enable cloudflare fail2ban"; description = "Enable cloudflare fail2ban";
@@ -17,7 +15,7 @@ in
description = "File containing your API key, scoped to Firewall Rules: Edit"; description = "File containing your API key, scoped to Firewall Rules: Edit";
type = lib.types.str; type = lib.types.str;
example = lib.literalExpression '' example = lib.literalExpression ''
Authorization: Bearer Qj06My1wXJEzcW46QCyjFbSMgVtwIGfX63Ki3NOj79o= Authorization: Bearer vH6-p0y=i4w3n7TjKqZ@x8D_lR!A9b2cOezXgUuJdE5F
''' '''
''; '';
}; };
@@ -32,14 +30,28 @@ in
example = "vaultwarden"; example = "vaultwarden";
type = lib.types.str; type = lib.types.str;
}; };
_groupsre = lib.mkOption {
type = lib.types.lines;
example = ''(?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)'';
default = "";
};
failRegex = lib.mkOption { failRegex = lib.mkOption {
type = lib.types.str; type = lib.types.lines;
example = "Login failed from IP: <HOST>"; example = ''
^Login failed from IP: <HOST>$
^Two-factor challenge failed from <HOST>$
'';
}; };
ignoreRegex = lib.mkOption { ignoreRegex = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = ""; default = "";
}; };
datePattern = lib.mkOption {
type = lib.types.str;
default = "";
example = '',?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"'';
description = "Optional datepattern line for the fail2ban filter.";
};
maxRetry = lib.mkOption { maxRetry = lib.mkOption {
type = lib.types.int; type = lib.types.int;
default = 3; default = 3;
@@ -57,54 +69,61 @@ in
pkgs.jq pkgs.jq
]; ];
jails = lib.attrsets.mapAttrs (name: value: { jails =
settings = { lib.attrsets.mapAttrs (name: value: {
bantime = "30d"; settings = {
findtime = "1h"; bantime = "24h";
enabled = true; findtime = "10m";
backend = "systemd"; enabled = true;
journalmatch = "_SYSTEMD_UNIT=${value.serviceName}.service"; backend = "systemd";
port = "http,https"; journalmatch = "_SYSTEMD_UNIT=${value.serviceName}.service";
filter = "${name}"; port = "http,https";
maxretry = 3; filter = "${name}";
action = "cloudflare-token-agenix"; maxretry = 3;
}; action = "cloudflare-token-agenix";
}) cfg.jails; };
})
cfg.jails;
}; };
environment.etc = lib.attrsets.mergeAttrsList [ environment.etc = lib.attrsets.mergeAttrsList [
(lib.attrsets.mapAttrs' ( (lib.attrsets.mapAttrs' (
name: value: name: value: (lib.nameValuePair "fail2ban/filter.d/${name}.conf" {
(lib.nameValuePair "fail2ban/filter.d/${name}.conf" { text =
text = '' ''
[Definition] [Definition]
failregex = ${value.failRegex} failregex = ${value.failRegex}
ignoreregex = ${value.ignoreRegex} ignoreregex = ${value.ignoreRegex}
''; ''
}) + lib.optionalString (value.datePattern != "") ''
) cfg.jails) datepattern = ${value.datePattern}
''
+ lib.optionalString (value._groupsre != "") ''
_groupsre = ${value._groupsre}
'';
})
)
cfg.jails)
{ {
"fail2ban/action.d/cloudflare-token-agenix.conf".text = "fail2ban/action.d/cloudflare-token-agenix.conf".text = let
let notes = "Fail2Ban on ${config.networking.hostName}";
notes = "Fail2Ban on ${config.networking.hostName}"; cfapi = "https://api.cloudflare.com/client/v4/zones/${cfg.zoneId}/firewall/access_rules/rules";
cfapi = "https://api.cloudflare.com/client/v4/zones/${cfg.zoneId}/firewall/access_rules/rules"; in ''
in [Definition]
'' actionstart =
[Definition] actionstop =
actionstart = actioncheck =
actionstop = actionunban = id=$(curl -s -X GET "${cfapi}" \
actioncheck = -H @${cfg.apiKeyFile} -H "Content-Type: application/json" \
actionunban = id=$(curl -s -X GET "${cfapi}" \ | jq -r '.result[] | select(.notes == "${notes}" and .configuration.target == "ip" and .configuration.value == "<ip>") | .id')
-H @${cfg.apiKeyFile} -H "Content-Type: application/json" \ if [ -z "$id" ]; then echo "id for <ip> cannot be found"; exit 0; fi; \
| jq -r '.result[] | select(.notes == "${notes}" and .configuration.target == "ip" and .configuration.value == "<ip>") | .id') curl -s -X DELETE "${cfapi}/$id" \
if [ -z "$id" ]; then echo "id for <ip> cannot be found"; exit 0; fi; \ -H @${cfg.apiKeyFile} -H "Content-Type: application/json" \
curl -s -X DELETE "${cfapi}/$id" \ --data '{"cascade": "none"}'
-H @${cfg.apiKeyFile} -H "Content-Type: application/json" \ actionban = curl -X POST "${cfapi}" -H @${cfg.apiKeyFile} -H "Content-Type: application/json" --data '{"mode":"block","configuration":{"target":"ip","value":"<ip>"},"notes":"${notes}"}'
--data '{"cascade": "none"}' [Init]
actionban = curl -X POST "${cfapi}" -H @${cfg.apiKeyFile} -H "Content-Type: application/json" --data '{"mode":"block","configuration":{"target":"ip","value":"<ip>"},"notes":"${notes}"}' name = cloudflare-token-agenix
[Init] '';
name = cloudflare-token-agenix
'';
} }
]; ];
}; };

View File

@@ -1,7 +1,8 @@
# taken from @jtojnar # "inspired" by @jtojnar <3
{ {
config, config,
lib, lib,
self,
... ...
}: let }: let
unit = "gitea"; unit = "gitea";
@@ -21,6 +22,20 @@ in {
default = 5003; default = 5003;
description = "The port to host Gitea on."; description = "The port to host Gitea on.";
}; };
cloudflared = {
credentialsFile = lib.mkOption {
type = lib.types.str;
example = lib.literalExpression ''
pkgs.writeText "cloudflare-credentials.json" '''
{"AccountTag":"secret"."TunnelSecret":"secret","TunnelID":"secret"}
'''
'';
};
tunnelId = lib.mkOption {
type = lib.types.str;
example = "00000000-0000-0000-0000-000000000000";
};
};
homepage.name = lib.mkOption { homepage.name = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "Gitea"; default = "Gitea";
@@ -39,62 +54,92 @@ in {
}; };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.${unit} = { age.secrets = {
enable = true; giteaCloudflared.file = "${self}/secrets/giteaCloudflared.age";
appName = "cnix code forge"; };
database = { server = {
type = "postgres"; fail2ban = lib.mkIf config.server.fail2ban.enable {
socket = "/run/postgresql"; jails = {
name = "gitea"; gitea = {
user = "gitea"; serviceName = "gitea";
createDatabase = false; failRegex = ''.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>'';
};
};
}; };
};
lfs = { services = {
cloudflared = {
enable = true; enable = true;
tunnels.${cfg.cloudflared.tunnelId} = {
credentialsFile = cfg.cloudflared.credentialsFile;
default = "http_status:404";
ingress."${cfg.url}".service = "http://localhost:${toString cfg.port}";
};
}; };
settings = { ${unit} = {
cors = { enable = true;
ENABLED = true; appName = "cnix code forge";
SCHEME = "https";
ALLOW_DOMAIN = cfg.url; database = {
type = "postgres";
socket = "/run/postgresql";
name = "gitea";
user = "gitea";
createDatabase = false;
}; };
log = {
MODE = "console"; lfs = {
enable = true;
}; };
mailer = {
ENABLED = false; settings = {
MAILER_TYPE = "sendmail"; cors = {
FROM = "noreply+adam@cnst.dev"; ENABLED = true;
SENDMAIL_PATH = "/run/wrappers/bin/sendmail"; SCHEME = "https";
}; ALLOW_DOMAIN = cfg.url;
picture = { };
DISABLE_GRAVATAR = true; log = {
}; MODE = "console";
repository = { };
DEFAULT_BRANCH = "main"; mailer = {
DEFAULT_REPO_UNITS = "repo.code,repo.issues,repo.pulls"; ENABLED = false;
DISABLE_DOWNLOAD_SOURCE_ARCHIVES = true; MAILER_TYPE = "sendmail";
}; FROM = "noreply+adam@cnst.dev";
indexer = { SENDMAIL_PATH = "/run/wrappers/bin/sendmail";
REPO_INDEXER_ENABLED = true; };
}; picture = {
server = { DISABLE_GRAVATAR = true;
DOMAIN = cfg.url; };
LANDING_PAGE = "explore"; repository = {
HTTP_PORT = cfg.port; DEFAULT_BRANCH = "main";
ROOT_URL = "https://${cfg.url}/"; DEFAULT_REPO_UNITS = "repo.code,repo.issues,repo.pulls";
}; DISABLE_DOWNLOAD_SOURCE_ARCHIVES = true;
security = { };
DISABLE_GIT_HOOKS = false; indexer = {
}; REPO_INDEXER_ENABLED = true;
service = { };
DISABLE_REGISTRATION = true; oauth2_client = {
}; ENABLE_AUTO_REGISTRATION = true;
session = { ACCOUNT_LINKING = "auto";
COOKIE_SECURE = true; };
server = {
DOMAIN = cfg.url;
LANDING_PAGE = "explore";
HTTP_PORT = cfg.port;
ROOT_URL = "https://${cfg.url}/";
};
security = {
DISABLE_GIT_HOOKS = false;
};
service = {
DISABLE_REGISTRATION = true;
};
session = {
COOKIE_SECURE = true;
};
}; };
}; };
}; };

View File

@@ -101,7 +101,7 @@ in {
label = "SYSTEM"; label = "SYSTEM";
memory = true; memory = true;
cpu = true; cpu = true;
uptime = true; uptime = false;
}; };
} }
]; ];

View File

@@ -4,21 +4,21 @@
pkgs, pkgs,
... ...
}: let }: let
service = "jellyfin"; unit = "jellyfin";
cfg = config.server.${service}; cfg = config.server.${unit};
srv = config.server; srv = config.server;
in { in {
options.server.${service} = { options.server.${unit} = {
enable = lib.mkEnableOption { enable = lib.mkEnableOption {
description = "Enable ${service}"; description = "Enable ${unit}";
}; };
configDir = lib.mkOption { configDir = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "/var/lib/${service}"; default = "/var/lib/${unit}";
}; };
url = lib.mkOption { url = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "jellyfin.${srv.domain}"; default = "fin.${srv.tailscale.url}";
}; };
homepage.name = lib.mkOption { homepage.name = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@@ -38,7 +38,7 @@ in {
}; };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.${service} = { services.${unit} = {
enable = true; enable = true;
user = srv.user; user = srv.user;
group = srv.group; group = srv.group;
@@ -49,14 +49,13 @@ in {
services.traefik = { services.traefik = {
dynamicConfigOptions = { dynamicConfigOptions = {
http = { http = {
services.jellyfin.loadBalancer.servers = [{url = "http://127.0.0.1:8096";}]; services.${unit}.loadBalancer.servers = [{url = "http://localhost:8096";}];
routers = { routers = {
jellyfin = { jellyfinRouter = {
entryPoints = ["websecure"]; entryPoints = ["websecure"];
rule = "Host(`${cfg.url}`)"; rule = "Host(`${cfg.url}`)";
service = "jellyfin"; service = "${unit}";
tls.certResolver = "letsencrypt"; tls.certResolver = "letsencrypt";
# middlewares = ["authentik"];
}; };
}; };
}; };

View File

@@ -3,17 +3,18 @@
lib, lib,
... ...
}: let }: let
service = "jellyseerr"; unit = "jellyseerr";
srv = config.server; srv = config.server;
cfg = config.server.${service}; cfg = config.server.${unit};
in { in {
options.server.${service} = { options.server.${unit} = {
enable = lib.mkEnableOption { enable = lib.mkEnableOption {
description = "Enable ${service}"; description = "Enable ${unit}";
}; };
url = lib.mkOption { url = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "${service}.${srv.domain}"; # default = "seer.${srv.tailscale.url}";
default = "jellyseerr.${srv.domain}";
}; };
port = lib.mkOption { port = lib.mkOption {
type = lib.types.port; type = lib.types.port;
@@ -37,21 +38,20 @@ in {
}; };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
services.${service} = { services.${unit} = {
enable = true; enable = true;
port = cfg.port; port = cfg.port;
}; };
services.traefik = { services.traefik = {
dynamicConfigOptions = { dynamicConfigOptions = {
http = { http = {
services.jellyseerr.loadBalancer.servers = [{url = "http://127.0.0.1:${toString cfg.port}";}]; services.jellyseerr.loadBalancer.servers = [{url = "http://localhost:${toString cfg.port}";}];
routers = { routers = {
jellyseerr = { jellyseerr = {
entryPoints = ["websecure"]; entryPoints = ["websecure"];
rule = "Host(`${cfg.url}`)"; rule = "Host(`${cfg.url}`)";
service = "jellyseerr"; service = "${unit}";
tls.certResolver = "letsencrypt"; tls.certResolver = "letsencrypt";
# middlewares = ["authentik"];
}; };
}; };
}; };

View File

@@ -54,8 +54,14 @@ in {
server.fail2ban = lib.mkIf config.server.fail2ban.enable { server.fail2ban = lib.mkIf config.server.fail2ban.enable {
jails = { jails = {
nextcloud = { nextcloud = {
serviceName = "phpfpm-nextcloud"; serviceName = "${unit}";
failRegex = "^.*Login failed:.*(Remote IP: <HOST>).*$"; _groupsre = ''(?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)'';
failRegex = ''
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Two-factor challenge failed:
^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
'';
datePattern = '',?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"'';
}; };
}; };
}; };
@@ -63,7 +69,7 @@ in {
services = { services = {
${unit} = { ${unit} = {
enable = true; enable = true;
package = pkgs.nextcloud31; package = pkgs.nextcloud32;
hostName = "nextcloud"; hostName = "nextcloud";
configureRedis = true; configureRedis = true;
caching = { caching = {

View File

@@ -143,61 +143,63 @@ in {
]; ];
}; };
services.traefik = lib.mkMerge [ services = {
(lib.mkIf cfg.pihole.enable { traefik = lib.mkMerge [
dynamicConfigOptions = { (lib.mkIf cfg.pihole.enable {
http = { dynamicConfigOptions = {
services = { http = {
pihole.loadBalancer.servers = [{url = "http://localhost:${toString cfg.pihole.port}";}]; services = {
}; pihole.loadBalancer.servers = [{url = "http://localhost:${toString cfg.pihole.port}";}];
routers = { };
pihole = { routers = {
entryPoints = ["websecure"]; pihole = {
rule = "Host(`${cfg.pihole.url}`)"; entryPoints = ["websecure"];
service = "pihole"; rule = "Host(`${cfg.pihole.url}`)";
tls.certResolver = "letsencrypt"; service = "pihole";
tls.certResolver = "letsencrypt";
};
}; };
}; };
}; };
}; })
})
(lib.mkIf cfg.qbittorrent.enable { (lib.mkIf cfg.qbittorrent.enable {
dynamicConfigOptions = { dynamicConfigOptions = {
http = { http = {
services = { services = {
qbittorrent.loadBalancer.servers = [{url = "http://localhost:${toString cfg.qbittorrent.port}";}]; qbittorrent.loadBalancer.servers = [{url = "http://localhost:${toString cfg.qbittorrent.port}";}];
}; };
routers = { routers = {
qbittorrent = { qbittorrent = {
entryPoints = ["websecure"]; entryPoints = ["websecure"];
rule = "Host(`${cfg.qbittorrent.url}`)"; rule = "Host(`${cfg.qbittorrent.url}`)";
service = "qbittorrent"; service = "qbittorrent";
tls.certResolver = "letsencrypt"; tls.certResolver = "letsencrypt";
};
}; };
}; };
}; };
}; })
})
(lib.mkIf cfg.slskd.enable { (lib.mkIf cfg.slskd.enable {
dynamicConfigOptions = { dynamicConfigOptions = {
http = { http = {
services = { services = {
slskd.loadBalancer.servers = [{url = "http://localhost:${toString cfg.slskd.port}";}]; slskd.loadBalancer.servers = [{url = "http://localhost:${toString cfg.slskd.port}";}];
}; };
routers = { routers = {
slskd = { slskd = {
entryPoints = ["websecure"]; entryPoints = ["websecure"];
rule = "Host(`${cfg.slskd.url}`)"; rule = "Host(`${cfg.slskd.url}`)";
service = "slskd"; service = "slskd";
tls.certResolver = "letsencrypt"; tls.certResolver = "letsencrypt";
};
}; };
}; };
}; };
}; })
}) ];
]; };
virtualisation.oci-containers.containers = lib.mkMerge [ virtualisation.oci-containers.containers = lib.mkMerge [
(lib.mkIf cfg.gluetun.enable { (lib.mkIf cfg.gluetun.enable {
@@ -293,7 +295,7 @@ in {
(lib.mkIf cfg.pihole.enable { (lib.mkIf cfg.pihole.enable {
pihole = { pihole = {
autoStart = true; autoStart = true;
image = "pihole/pihole:latest"; image = "pihole/pihole:2025.08.0";
volumes = [ volumes = [
"/var/lib/pihole:/etc/pihole/" "/var/lib/pihole:/etc/pihole/"
"/var/lib/dnsmasq.d:/etc/dnsmasq.d/" "/var/lib/dnsmasq.d:/etc/dnsmasq.d/"

View File

@@ -0,0 +1,31 @@
{
config,
lib,
self,
...
}:
with lib; let
cfg = config.server.tailscale;
in {
options.server.tailscale = {
enable = mkEnableOption "Enable tailscale server configuration";
url = lib.mkOption {
type = lib.types.str;
default = "ts.cnst.dev";
};
};
config = mkIf cfg.enable {
age.secrets.sobotkaTsAuth.file = "${self}/secrets/sobotkaTsAuth.age";
services.tailscale = {
enable = true;
openFirewall = true;
useRoutingFeatures = "server";
authKeyFile = config.age.secrets.sobotkaTsAuth.path;
extraSetFlags = [
"--advertise-exit-node"
];
};
};
}

View File

@@ -23,7 +23,7 @@ in {
age.secrets.traefikEnv = { age.secrets.traefikEnv = {
file = "${self}/secrets/traefikEnv.age"; file = "${self}/secrets/traefikEnv.age";
mode = "640"; mode = "640";
owner = "root"; owner = "traefik";
group = "traefik"; group = "traefik";
}; };
@@ -49,7 +49,7 @@ in {
dashboard = true; dashboard = true;
}; };
certificatesResolvers = { certificatesResolvers = {
tailscale.tailscale = {}; vpn.tailscale = {};
letsencrypt = { letsencrypt = {
acme = { acme = {
email = "adam@cnst.dev"; email = "adam@cnst.dev";
@@ -89,6 +89,10 @@ in {
main = "cnix.dev"; main = "cnix.dev";
sans = ["*.cnix.dev"]; sans = ["*.cnix.dev"];
} }
{
main = "ts.cnst.dev";
sans = ["*ts.cnst.dev"];
}
]; ];
}; };
}; };

View File

@@ -44,7 +44,7 @@ in {
jails = { jails = {
vaultwarden = { vaultwarden = {
serviceName = "vaultwarden"; serviceName = "vaultwarden";
failRegex = "^.*Username or password is incorrect. Try again. IP: <HOST>. Username: <F-USER>.*</F-USER>.$"; failRegex = ''^.*?Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$'';
}; };
}; };
}; };
@@ -72,7 +72,7 @@ in {
logLevel = "warn"; logLevel = "warn";
extendedLogging = true; extendedLogging = true;
useSyslog = true; useSyslog = true;
invitationsAllowed = false; invitationsAllowed = true;
showPasswordHint = false; showPasswordHint = false;
}; };
}; };

View File

@@ -44,9 +44,11 @@ in {
server = { server = {
fail2ban = lib.mkIf config.server.www.enable { fail2ban = lib.mkIf config.server.www.enable {
jails = { jails = {
www = { nginx-404 = {
serviceName = "cnst.dev"; serviceName = "nginx";
failRegex = "^.*Username or password is incorrect. Try again. IP: <HOST>. Username: <F-USER>.*</F-USER>.$"; failRegex = ''^.*\[error\].*directory index of.* is forbidden.*client: <HOST>.*$'';
ignoreRegex = '''';
maxRetry = 5;
}; };
}; };
}; };
@@ -64,14 +66,23 @@ in {
virtualHosts."webfinger" = { virtualHosts."webfinger" = {
forceSSL = false; forceSSL = false;
serverName = cfg.url; serverName = cfg.url;
root = "/etc/webfinger"; root = "/var/www/webfinger";
locations."= /.well-known/webfinger" = { locations."= /.well-known/webfinger" = {
root = "/etc/webfinger"; root = "/var/www/webfinger";
extraConfig = '' extraConfig = ''
default_type application/jrd+json; default_type application/jrd+json;
try_files /.well-known/webfinger =404; try_files /.well-known/webfinger =404;
''; '';
}; };
locations."= /robots.txt" = {
root = "/var/www/webfinger";
extraConfig = ''
default_type text/plain;
try_files /robots.txt =404;
'';
};
}; };
}; };
@@ -85,17 +96,24 @@ in {
}; };
}; };
environment.etc."webfinger/.well-known/webfinger".text = '' environment.etc = {
{ "webfinger/.well-known/webfinger".text = ''
"subject": "acct:adam@${cfg.url}", {
"links": [ "subject": "acct:adam@${cfg.url}",
{ "links": [
"rel": "http://openid.net/specs/connect/1.0/issuer", {
"href": "https://auth.${cfg.url}/application/o/tailscale/" "rel": "http://openid.net/specs/connect/1.0/issuer",
} "href": "https://auth.${cfg.url}/application/o/tailscale/"
] }
} ]
''; }
'';
"webfinger/robots.txt".text = ''
User-agent: *
Disallow: /
'';
};
services.traefik.dynamicConfigOptions.http = { services.traefik.dynamicConfigOptions.http = {
routers.webfinger = { routers.webfinger = {

View File

@@ -0,0 +1,12 @@
age-encryption.org/v1
-> ssh-ed25519 t9iOEg RnlIwFO8LSwzj94G0Uru9qibXqOOpCU2kWWdNa2tRFU
lIC3K/jjBMKRfLfepoNYIkBe5rhHuR0l3Uf1Xuk8uZg
-> ssh-ed25519 KUYMFA k16GBRcaaSwJm/8+Vm2QBOu05u6eEro/7YYj7kbuNSU
VCpt918MBBFfFZKKypV9pSwz/Zhsxr+Ob6YjFuJ/oL0
-> ssh-ed25519 76RhUQ FIKn3nuOT1ywu6pmYBbpC54HhpJGeMFejp5c0XibfAY
WDsh/5G4wXYt21yIDxmI6u1l/xPOdZRxgTazf6QLXP8
-> ssh-ed25519 Jf8sqw 2EvD96Ec8h97ACoOBYzn1Ugx4ZyYSHIRnsmtB5lb/XQ
mFY8O8qwWWihsLe5ayB5iGm1JUY2B/9el/XSf5sPe7M
--- uuwibRk7LS4/lUx9gwL+x5NMrxLjGM1Yf55bzjxQTKM
<EFBFBD>H<>Ԅ6K<36>A<01>~<7E><>)!B<08><>^S!Wd<><64>$.:S'c<>d<EFBFBD><64><EFBFBD>_WW<57>Bj<42>,<2C><>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD>V<>S<EFBFBD><53>h<EFBFBD>
h<EFBFBD><EFBFBD><12><>k

View File

@@ -1,11 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 t9iOEg pfPhWigjvnJ5tfVv8qPpk3VYvLH9I01HVVbpu+r2NjY
Kaj8aZv+9pSYjwoE7EHWGHfsZIPFZOgUVaKf8VxWKcQ
-> ssh-ed25519 KUYMFA 9Xy82Cl3HUQcFDcJMxxnnIfLOngW8xLfVE0S1wRliGg
mOOcyJp5+ZqFwdkZkHC63+cMA0ToGcuI6kqMjAJ9jJk
-> ssh-ed25519 76RhUQ +OvUSQwpy6+xxlom8bJFn8CBdSKECa9YY0U+YYNYdGM
MWfmfGzd6/lOPvggUG8uJgBAp1CTqSdk+NDkk7vSQEQ
-> ssh-ed25519 Jf8sqw jQR/wT/+f63cJdFzR/Ogw6pdiYXoyVNu1+UCni2BYSM
Iicwg/XJJskvWFmAbxFDh3gSJyjid5fw9JXmDJPhzkU
--- xK8vBWioTgSDPHkKh7SJxstCzYtUSmTz6QuN/+niFME
<08><>f<<3C>`VR<56><52>p<><70>)>|<7C>+aئI<D8A6>g<08> <0B><><EFBFBD><EFBFBD><EFBFBD><19><>x<EFBFBD><78>HH+<2B><EFBFBD><E7B7AD>o>$4H<><48><EFBFBD><EFBFBD>B?<3F>l6TSqμ<71>Ǿ<EFBFBD><C7BE>Kj-l

View File

@@ -48,6 +48,7 @@ in {
"homepageEnvironment.age".publicKeys = kima ++ sobotka; "homepageEnvironment.age".publicKeys = kima ++ sobotka;
"cloudflareFirewallApiKey.age".publicKeys = kima ++ sobotka; "cloudflareFirewallApiKey.age".publicKeys = kima ++ sobotka;
"vaultwardenCloudflared.age".publicKeys = kima ++ sobotka; "vaultwardenCloudflared.age".publicKeys = kima ++ sobotka;
"giteaCloudflared.age".publicKeys = kima ++ sobotka;
"nextcloudCloudflared.age".publicKeys = kima ++ sobotka; "nextcloudCloudflared.age".publicKeys = kima ++ sobotka;
"nextcloudAdminPass.age".publicKeys = kima ++ sobotka; "nextcloudAdminPass.age".publicKeys = kima ++ sobotka;
"cloudflareDnsApiToken.age".publicKeys = kima ++ sobotka; "cloudflareDnsApiToken.age".publicKeys = kima ++ sobotka;
@@ -61,6 +62,7 @@ in {
"traefikEnv.age".publicKeys = kima ++ sobotka; "traefikEnv.age".publicKeys = kima ++ sobotka;
"wwwCloudflared.age".publicKeys = kima ++ sobotka; "wwwCloudflared.age".publicKeys = kima ++ sobotka;
"authentikCloudflared.age".publicKeys = kima ++ sobotka; "authentikCloudflared.age".publicKeys = kima ++ sobotka;
"sobotkaTsAuth.age".publicKeys = kima ++ sobotka;
# Ziggy-specific # Ziggy-specific
"cloudflareDnsCredentialsZiggy.age".publicKeys = kima ++ ziggy; "cloudflareDnsCredentialsZiggy.age".publicKeys = kima ++ ziggy;

11
secrets/sobotkaTsAuth.age Normal file
View File

@@ -0,0 +1,11 @@
age-encryption.org/v1
-> ssh-ed25519 t9iOEg fftdt8orBZoM0sDRAXf0TScDLosNWWWIg7JmmuunuWM
2IfpTH6ptSyLnBtBStkk7SINct6LtBHrL6h22BVNb+k
-> ssh-ed25519 KUYMFA HI04mnVOGPRsRhnqCkbO4My/sBq5v/3UYxDVcfIe4RM
fcSApUYCnJlpzVW5e77CFoSHamEmP+6ztMmzp2WlJvY
-> ssh-ed25519 76RhUQ c2FbmTXGl/F+1acZFEJUoenkxiIGdoXkT67VgxvoFHg
eWExqblEp5VIeXuPEuvj4QAIWtFX5KLfMyh6/fZ9bnA
-> ssh-ed25519 Jf8sqw IAcUf70EufTyjsva8XIlXOfPxwXvtr9AFl0LwrdAMgc
bY098fejLaFbUMX0iF89gz8kiOGZHI8JIg4NzX4ItFw
--- WNqpLyRM2EqISbZky++NbKLw4GCEgwbz2O5+VO7aKzE
<EFBFBD><EFBFBD><1A><>(5<0F>q <09><>m<EFBFBD>C<EFBFBD><43>G<EFBFBD>r<><72><16><><EFBFBD><EFBFBD>ޒ3<DE92><33><17><1F>7<><37><EFBFBD>rG<72>i<EFBFBD>c7<63>i<EFBFBD>P<EFBFBD><50>l<EFBFBD><19>7<EFBFBD><<3C>r?cGo<47><>W<0E>V<EFBFBD><56>f,2<>Qg!<21>t_<74>

Binary file not shown.