feat: netbird

This commit is contained in:
danny 2026-01-08 14:21:53 +08:00
parent 53b83b3471
commit ea118b7995
64 changed files with 1088 additions and 665 deletions

607
flake.lock generated

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,7 @@
neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay"; neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
lanzaboote = { lanzaboote = {
url = "github:nix-community/lanzaboote/v0.4.2"; url = "github:nix-community/lanzaboote/v1.0.0";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
@ -112,12 +112,6 @@
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
}; };
actual-budget-server = {
url = "git+file:///home/danny/projects/actual-budget-flake";
# url = "github:dachxy/actual-budget-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
mail-server = { mail-server = {
url = "github:dachxy/nix-mail-server"; url = "github:dachxy/nix-mail-server";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@ -234,6 +228,7 @@
inputs.attic.nixosModules.atticd inputs.attic.nixosModules.atticd
inputs.mail-server.nixosModules.default inputs.mail-server.nixosModules.default
inputs.niri.nixosModules.niri inputs.niri.nixosModules.niri
inputs.lanzaboote.nixosModules.lanzaboote
./options ./options
# ==== Private Configuration ==== # # ==== Private Configuration ==== #

View file

@ -1,4 +1,9 @@
{ config, lib, ... }: {
config,
lib,
pkgs,
...
}:
let let
inherit (lib) inherit (lib)
mkIf mkIf
@ -11,7 +16,7 @@ in
{ {
options.services.sunsetr = { options.services.sunsetr = {
enable = mkEnableOption "Enable sunsetr."; enable = mkEnableOption "Enable sunsetr.";
package = mkPackageOption "sunsetr"; package = mkPackageOption pkgs "sunsetr" { };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {

View file

@ -13,11 +13,13 @@ let
--sudo --ask-sudo-password $@''; --sudo --ask-sudo-password $@'';
in in
pkgs.writeShellScriptBin "rRebuild" '' pkgs.writeShellScriptBin "rRebuild" ''
NOTIFY="''\${NOTIFY:-0}"
TARGET=$1 TARGET=$1
BUILD=$2 BUILD=$2
shift set -euo pipefail
shift
shift 2
${ ${
if shouldNotify then if shouldNotify then
@ -25,6 +27,11 @@ pkgs.writeShellScriptBin "rRebuild" ''
export NTFY_TITLE="🎯 $TARGET built by 🏗 ''\${BUILD:-${hostName}}" export NTFY_TITLE="🎯 $TARGET built by 🏗 ''\${BUILD:-${hostName}}"
export NTFY_TAGS="gear" export NTFY_TAGS="gear"
if [ "$NOTIFY" -eq 0 ] ; then
${rebuildCommand}
exit 0
fi
if ${rebuildCommand} if ${rebuildCommand}
then then
ntfy pub system-build " Build success" > /dev/null 2>&1 ntfy pub system-build " Build success" > /dev/null 2>&1

View file

@ -1,10 +1,12 @@
{ {
lib,
osConfig, osConfig,
config, config,
pkgs, pkgs,
... ...
}: }:
let let
inherit (lib) mkForce;
remoteRebuld = import ../scripts/remoteRebuild.nix { inherit osConfig config pkgs; }; remoteRebuld = import ../scripts/remoteRebuild.nix { inherit osConfig config pkgs; };
in in
{ {

View file

@ -23,6 +23,7 @@ in
./sops ./sops
./utility ./utility
./virtualisation ./virtualisation
./network
]; ];
users.users."${username}".openssh.authorizedKeys.keys = [ users.users."${username}".openssh.authorizedKeys.keys = [

View file

@ -0,0 +1,5 @@
{
imports = [
../../../modules/netbird-client.nix
];
}

View file

@ -1,5 +1,7 @@
wireguard: wireguard:
wg0.conf: ENC[AES256_GCM,data:9wegrw4ZbY+T/gNYi0gt4n6Db1/rRpsiqVbQr8QoYTwOiWBjKO2PGTTM5aK3khk5t2pYOTSqEBn5+5J/JYZpQ6nvJMcqn0+31KMuMT9/0akxOm112Tj31vOdBwRvSQVLBzmQtPABgMlV36lRtpVU71lwiNO4M33ygzL/tm7EMt0e75Nr9CZkGI7BGtnATBzbj3ysftsbFPF2iIgZ9fej4I78rJ1HavAsAgcrxksWAJjFZyFGWinkW4eiwDKlqBvRUW0tE8TF897ZmX90UnwXwjtyJcyJH6nzwrRDJgxR7uyRL/HIusmVZHCNSlo8dSaxAROXOw5ULjmQpXzzPAVUxw==,iv:FCv2ADYZXflBYuI9B9xvUSAYX8+v2Qf9EJjZ/TX27sA=,tag:caR4HS3yYrjNP1IzxgoOXA==,type:str] wg0.conf: ENC[AES256_GCM,data:9wegrw4ZbY+T/gNYi0gt4n6Db1/rRpsiqVbQr8QoYTwOiWBjKO2PGTTM5aK3khk5t2pYOTSqEBn5+5J/JYZpQ6nvJMcqn0+31KMuMT9/0akxOm112Tj31vOdBwRvSQVLBzmQtPABgMlV36lRtpVU71lwiNO4M33ygzL/tm7EMt0e75Nr9CZkGI7BGtnATBzbj3ysftsbFPF2iIgZ9fej4I78rJ1HavAsAgcrxksWAJjFZyFGWinkW4eiwDKlqBvRUW0tE8TF897ZmX90UnwXwjtyJcyJH6nzwrRDJgxR7uyRL/HIusmVZHCNSlo8dSaxAROXOw5ULjmQpXzzPAVUxw==,iv:FCv2ADYZXflBYuI9B9xvUSAYX8+v2Qf9EJjZ/TX27sA=,tag:caR4HS3yYrjNP1IzxgoOXA==,type:str]
netbird:
wt0-setupKey: ENC[AES256_GCM,data:bj3w7lGMJ0ZPQpGF0nKuhPKNWb04xVr6wNqoFGNzPnEJ+Q+b,iv:0helVFJqu4TNFY6LTG7LpD3tqsArwJHWH2XnlpPKEZk=,tag:yGrExGSmliHXxKAHqiHK/g==,type:str]
sops: sops:
age: age:
- recipient: age1uvsvf5ljaezh5wze32p685kfentyle0l2mvysc67yvgct2h4850qqph9lv - recipient: age1uvsvf5ljaezh5wze32p685kfentyle0l2mvysc67yvgct2h4850qqph9lv
@ -20,7 +22,7 @@ sops:
V09NYXpBYXBtYWdBajJubmVFL2loY0EKJdYKQHPriOT0eouvRUiCyqLSTzugUZxl V09NYXpBYXBtYWdBajJubmVFL2loY0EKJdYKQHPriOT0eouvRUiCyqLSTzugUZxl
BFTwfCez1/K2ERKQkKsMfIARbHaI2SRyDxM2O1IJ+DOIJ2383K6Gvw== BFTwfCez1/K2ERKQkKsMfIARbHaI2SRyDxM2O1IJ+DOIJ2383K6Gvw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-19T12:39:58Z" lastmodified: "2026-01-06T08:39:04Z"
mac: ENC[AES256_GCM,data:tTvNyD6Lekc0RUIr9CpCjhWl2Gb9pHRubeoTrwceUCkm074EjYIzvqwiX5fzt6Cc5/H/k8NWJZBAoI3tOeCrXpo1Lbb0fCjGqxTldGN44pLR/5q9bdAxLom3EEqKiBBryVxqAkkm1a98UXPtnh+oDyaFsqTbS65LolEtFEbV/3U=,iv:J0gMlpWc9TVSCRxcdUnlXtNnmahvbc12EsLeFB4BJlY=,tag:h0EaNQ/sl+3sU9+g4ohjtw==,type:str] mac: ENC[AES256_GCM,data:xPMGZ7SUVih97hWeeARhoZVn4B8D/lNzLuxRRkQEG5PqdtXHwH9HVIHz6AG3Pc72aRKroGF0E2sidJU7WxIUde4IuoktecHq2e2e+tVLZWg50Y/keG7SMR5MamapCiYxK88a9vG4a8PYytSOFvF5DUUjKGkFJZOaelK+ydOPbek=,iv:lh+dwiBl26sEYpvXx6HtUwKs2Mz5F0hRKD4q2q1jlkI=,tag:+gDW5nRmBkjCryFTudyqMA==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.11.0 version: 3.11.0

View file

@ -3,7 +3,7 @@
... ...
}: }:
{ {
boot.kernelPackages = pkgs.linuxPackages_6_17; boot.kernelPackages = pkgs.linuxPackages_latest;
fileSystems."/mnt/ssd" = { fileSystems."/mnt/ssd" = {
device = "/dev/disk/by-label/DN-SSD"; device = "/dev/disk/by-label/DN-SSD";
@ -19,6 +19,7 @@
"uid=1000" "uid=1000"
"dmask=000" "dmask=000"
"fmask=000" "fmask=000"
"exec"
]; ];
}; };

View file

@ -44,6 +44,7 @@ in
../public/dn ../public/dn
../public/dn/ntfy.nix ../public/dn/ntfy.nix
./expr ./expr
./network
./common ./common
./games ./games
./home ./home
@ -53,6 +54,7 @@ in
./virtualisation ./virtualisation
../../modules/shells/noctalia ../../modules/shells/noctalia
../../modules/sunshine.nix ../../modules/sunshine.nix
../../modules/secure-boot.nix
]; ];
# Live Sync D # Live Sync D

View file

@ -1,6 +1,5 @@
{ {
imports = [ imports = [
# ./netbird.nix
# ./osx-kvm.nix # ./osx-kvm.nix
]; ];
} }

View file

@ -1,65 +0,0 @@
{
domain,
idpSecret,
dataStoreEncryptionKey,
coturnPassFile,
...
}:
let
port = 51820;
in
{
services.netbird = {
server = {
enable = true;
domain = "netbird.${domain}";
enableNginx = true;
management = {
oidcConfigEndpoint = "https://keycloak.net.dn/realms/master/.well-known/openid-configuration";
settings = {
DataStoreEncryptionKey = {
_secret = dataStoreEncryptionKey;
};
TURNConfig = {
Secret = {
_secret = idpSecret;
};
};
IdpManagerConfig = {
ClientConfig = {
ClientID = "netbird-backend";
ClientSecret = {
_secret = idpSecret;
};
};
};
};
};
coturn = {
user = "netbird";
passwordFile = coturnPassFile;
enable = true;
};
dashboard.settings = {
USE_AUTH0 = false;
AUTH_AUTHORITY = "https://keycloak.net.dn/realms/master";
AUTH_CLIENT_ID = "netbird";
AUTH_AUDIENCE = "netbird";
AUTH_SUPPORTED_SCOPES = "openid profile email offline_access api";
};
};
clients.default = {
inherit port;
openFirewall = true;
name = "netbird";
interface = "wt0";
hardened = true;
dns-resolver.address = "10.0.0.1";
};
};
services.nginx.virtualHosts."netbird.${domain}" = {
enableACME = true;
forceSSL = true;
};
}

View file

@ -1,6 +1,7 @@
{ {
imports = [ imports = [
../../../modules/gaming.nix ../../../modules/gaming.nix
./game.nix ./shadps4.nix
./minecraft.nix
]; ];
} }

View file

@ -0,0 +1,12 @@
{ pkgs, ... }:
{
home-manager.sharedModules = [
{
home.packages = with pkgs; [
prismlauncher
lsfg-vk
lsfg-vk-ui
];
}
];
}

View file

@ -0,0 +1,6 @@
{
imports = [
../../../modules/netbird-client.nix
# ../../../modules/wireguard.nix
];
}

View file

@ -3,8 +3,7 @@
../../../modules/postgresql.nix ../../../modules/postgresql.nix
# ./mail.nix # ./mail.nix
./nginx.nix ./nginx.nix
./wireguard.nix # ./pangolin.nix
# ./nextcloud.nix # ./nextcloud.nix
# ./netbird.nix
]; ];
} }

View file

@ -1,11 +0,0 @@
{ config, ... }:
{
imports = [
(import ../expr/netbird.nix {
domain = "pre7780.dn";
coturnPassFile = config.sops.secrets."netbird/coturn/password".path;
idpSecret = config.sops.secrets."netbird/oidc/secret".path;
dataStoreEncryptionKey = config.sops.secrets."netbird/dataStoreKey".path;
})
];
}

View file

@ -0,0 +1,48 @@
{ config, lib, ... }:
let
inherit (lib) mkForce;
secrets = config.sops.secrets;
domain = "net.dn";
in
{
sops.secrets = {
"pangolin/env" = { };
"pangolin/traefik" = {
key = "acme/pdns";
};
};
services.pangolin = {
enable = true;
openFirewall = true;
dashboardDomain = "auth.${domain}";
baseDomain = domain;
environmentFile = secrets."pangolin/env".path;
letsEncryptEmail = "danny@net.dn";
dnsProvider = "pdns";
settings = {
app = {
save_logs = true;
};
domains = {
};
traefik.prefer_wildcard_cert = true;
};
};
services.traefik = {
staticConfigOptions = {
certificatesResolvers.letsencrypt.acme = {
caServer = mkForce "https://ca.net.dn/acme/acme/directory";
dnsChallenge = {
provider = "pdns";
resolvers = [ "10.0.0.1:53" ];
};
};
};
environmentFiles = [ secrets."pangolin/traefik".path ];
};
}

View file

@ -1,5 +0,0 @@
{
imports = [
../../../modules/wireguard.nix
];
}

View file

@ -1,11 +1,12 @@
wireguard: wireguard:
wg0.conf: ENC[AES256_GCM,data:ozySeNEvkiLt9TGrZCrlJWKT5gcSlZ9T8AeXGO97SPgxI394eCQ/LOkVFl7AykhZvs7YkxMpZzAZxc0oNdTYuDlqfrNr0pqTUJmpX+5PVRmDb5z2MJvERktVkJ4LSvVodoYznDwT/y9q199AFKf3t4EoWuRyR/il6P8HuGVHXrKRYUrwuB4nuq1SIByY+8D2gzohFB/s6pSOPYy6/xCt0Nm+x0wmcdrlyOb0S+4WXlcou2ll98o9q2YDdVBKeW4jyUjFqXM2XzD0JXpAi9ZFlyzxyYNwa4oMYATyCBCH4BNHqe850QHEoCaOovioEdDH/tluB2X/891ixqzURypzbg==,iv:3Q5xOgGcg8/DIwHt4fHsQGtN8f2hGpVDtf47PcwW62I=,tag:SbJqhWi3+h1O5ZIOayDrUw==,type:str] wg0.conf: ENC[AES256_GCM,data:ozySeNEvkiLt9TGrZCrlJWKT5gcSlZ9T8AeXGO97SPgxI394eCQ/LOkVFl7AykhZvs7YkxMpZzAZxc0oNdTYuDlqfrNr0pqTUJmpX+5PVRmDb5z2MJvERktVkJ4LSvVodoYznDwT/y9q199AFKf3t4EoWuRyR/il6P8HuGVHXrKRYUrwuB4nuq1SIByY+8D2gzohFB/s6pSOPYy6/xCt0Nm+x0wmcdrlyOb0S+4WXlcou2ll98o9q2YDdVBKeW4jyUjFqXM2XzD0JXpAi9ZFlyzxyYNwa4oMYATyCBCH4BNHqe850QHEoCaOovioEdDH/tluB2X/891ixqzURypzbg==,iv:3Q5xOgGcg8/DIwHt4fHsQGtN8f2hGpVDtf47PcwW62I=,tag:SbJqhWi3+h1O5ZIOayDrUw==,type:str]
netbird:
wt0-setupKey: ENC[AES256_GCM,data:166VX+rgzxhar+GFKxA5d8G3/9ewISdv2hUSwvbggyyjwwvE,iv:w8p4gDP6U0ZONX59t2dnglTC9S2dW2TX5A4OoCzRuzM=,tag:zf3jvlERJtM+osBd4ZQjMA==,type:str]
dovecot: dovecot:
openldap: ENC[AES256_GCM,data:U3YYreEqoh+F0Mrli52jgQowrUqIUPmdQps=,iv:vTjHBFsue+89GOCDigVIktgGSZNZv8A2e3GM80o6TXc=,tag:GGh+hsT+yV/I12meXxflbQ==,type:str] openldap: ENC[AES256_GCM,data:U3YYreEqoh+F0Mrli52jgQowrUqIUPmdQps=,iv:vTjHBFsue+89GOCDigVIktgGSZNZv8A2e3GM80o6TXc=,tag:GGh+hsT+yV/I12meXxflbQ==,type:str]
nextcloud: nextcloud:
adminPassword: ENC[AES256_GCM,data:69NrA/iP0sfrkdv8ahv7I+ZY,iv:/TXTs0fZw64HELdGr5CzgToO2L2G2mCNdN4Zexz8p+o=,tag:p2hNTxv1xdYmEJ6ZAO3w3Q==,type:str] adminPassword: ENC[AES256_GCM,data:69NrA/iP0sfrkdv8ahv7I+ZY,iv:/TXTs0fZw64HELdGr5CzgToO2L2G2mCNdN4Zexz8p+o=,tag:p2hNTxv1xdYmEJ6ZAO3w3Q==,type:str]
whiteboard: ENC[AES256_GCM,data:qcZOLX1qJyciKm+4uuOVIopZXG70Jg9Grc07SCjG5ww9DK0myzdqlfWeZKdTsOyTBLMyCE9K7lC5rtBFeSv3ZeqkAUXTQt9QiAN05+tTpHk=,iv:v6fgSz/eh8MZANSbLbeSrKVOdX09pHYZ599BK8Ug2Lo=,tag:JTezfqrInm82K3gB0zpniw==,type:str] whiteboard: ENC[AES256_GCM,data:qcZOLX1qJyciKm+4uuOVIopZXG70Jg9Grc07SCjG5ww9DK0myzdqlfWeZKdTsOyTBLMyCE9K7lC5rtBFeSv3ZeqkAUXTQt9QiAN05+tTpHk=,iv:v6fgSz/eh8MZANSbLbeSrKVOdX09pHYZ599BK8Ug2Lo=,tag:JTezfqrInm82K3gB0zpniw==,type:str]
signaling.conf: ENC[AES256_GCM,data:Ede61FM7k3VQHt4hO7O4UOE0p5nHk8lYsqaNWh8ZxfdGRJoMoLJYFcJs8nemAj1AGCh1Ep4ehtgQGcFfILUcek280m4paSIfaE2cwsI+1F+diXn98YmsmiR3swryw518gmfTZ7DrHlns7EWr/Udflz91F5+CKAuPNKtsYRSkB4KmJmEc4k2ioPus7hHEz/edLqA4mob/DuRXrWmFkDtlEj4I9aS5CJpyeDrsYoticnp5/QCWBnpxN2itqvbwjspid085Us7p4wbrM7Di/gPjj0D84Hw4biOLWSHm1oMRXqXIBP3ntPvvKJ2sKy7czcbeIGeJAIwEctStG7hqLAv3bfxiMn8DQ8eNp/xWw6tnwYklS4KCBJbDUucGvNcSx41JLCm+TShxaPIv/l6y+Z7Hkvri1WW2WSRvRsMFFEy3PrZLu0GstESYyARBrVdJ+OdaEtt3tthYLCUQcTT5xd484TTEyF9z3d5CBPC62BXZBdFRyEPD696nXV0ztVTBz2oWCmD6jHL0v+nTn3sojTDet0vmPo6o6cE0RqX6G/oVx+Y9l52QirFxOaNALk3R1l/lvXhDhlrAp8EldGhfnZf8y7X2HoC/XHQud9pA0N89Xrgp/Ak+9d+tRtmr4icLNVtwBg91md9P1tCyqPTUGR3JHc1KtmDHVI3NqgekUAmHrNRE5m633fchV2sTYSOfvdtL,iv:/xlMQoexPA9rXIlMd7bTQY1ojHuprBX/5quVSnNslvI=,tag:geAR+vPBmDB37/oSnnpqSA==,type:str]
openldap: openldap:
adminPassword: ENC[AES256_GCM,data:jEGuzgs5QTWfdyJenC3t3g==,iv:StfFOcvbDapnma6eAlpaGiBWnqiD3I/wfQsMBzufol0=,tag:892q7N4KrsSQoZYGy6CQrA==,type:str] adminPassword: ENC[AES256_GCM,data:jEGuzgs5QTWfdyJenC3t3g==,iv:StfFOcvbDapnma6eAlpaGiBWnqiD3I/wfQsMBzufol0=,tag:892q7N4KrsSQoZYGy6CQrA==,type:str]
lam: lam:
@ -18,15 +19,13 @@ acme:
pdns: ENC[AES256_GCM,data:eKnahc8HWboYCUpBuEUrdCMhN8A2N2VN0wrmzcyU2OfMeQaswIYSWV4sBzUbj/pono8PaVxK1FBKsn+Ycd4Y6tcxsAkbPfnPkOsbe0FJpz4t9RFLJBLw3U0YTE/TaURiDYipHnvPGYgyq3AziH/xa4WXZxLHGI0x+a/y3PpWy37rT87DWUT2kktPshdO7Mbwn7nSC78WByXmyaUMkT74Sc0FNmCgfijrHk/ATXGb,iv:y3eRZXFbqqf4VuuqHHYdIoiEa1zqRU1XIlEqooJ28lU=,tag:2bIALJFGZyIZT7fyo/y5Nw==,type:str] pdns: ENC[AES256_GCM,data:eKnahc8HWboYCUpBuEUrdCMhN8A2N2VN0wrmzcyU2OfMeQaswIYSWV4sBzUbj/pono8PaVxK1FBKsn+Ycd4Y6tcxsAkbPfnPkOsbe0FJpz4t9RFLJBLw3U0YTE/TaURiDYipHnvPGYgyq3AziH/xa4WXZxLHGI0x+a/y3PpWy37rT87DWUT2kktPshdO7Mbwn7nSC78WByXmyaUMkT74Sc0FNmCgfijrHk/ATXGb,iv:y3eRZXFbqqf4VuuqHHYdIoiEa1zqRU1XIlEqooJ28lU=,tag:2bIALJFGZyIZT7fyo/y5Nw==,type:str]
cloudflare: cloudflare:
secret: ENC[AES256_GCM,data:Ktk7BtyjaDeOc4Okflz/ZBYpJ7Uy1SeEBV6ofWcToZsvCDT6aTVxGrAKEHIE/eknvnyWOFeSQv/z/Q==,iv:x2ymbLwa1E2FzdomISeyhchya5bowgieO/XuOnoi81w=,tag:Nj+1DRnbvcwiLiEeu2WaRQ==,type:str] secret: ENC[AES256_GCM,data:Ktk7BtyjaDeOc4Okflz/ZBYpJ7Uy1SeEBV6ofWcToZsvCDT6aTVxGrAKEHIE/eknvnyWOFeSQv/z/Q==,iv:x2ymbLwa1E2FzdomISeyhchya5bowgieO/XuOnoi81w=,tag:Nj+1DRnbvcwiLiEeu2WaRQ==,type:str]
netbird:
oidc:
secret: ENC[AES256_GCM,data:hSVMUEBL0kCvRLD3zd57SLhNIAFOR4eaJPcIIIIUJng=,iv:VhfseftQNlXSDCWuaYQUIklMUCkUbChyWbJl3qgD75M=,tag:vbqov0VgA0XNZfzcr3FZgA==,type:str]
dataStoreKey: ENC[AES256_GCM,data:vV2wgo5qFS+DC1NmOjVddZW9HAsRMpUFH+t/70iQ3A5YXkhbWoCeSxZDyAg=,iv:tKqh28qj8gqHfcb44Ej731w6NKi29X4iEwIOQ4ZcCzA=,tag:ObAxVrUctm6pbmXSQw7j5w==,type:str]
crowdsec: crowdsec:
lapi.yaml: ENC[AES256_GCM,data:BpDlz/liFYVZTA66TMWDifGfT4R9l0W9/LOU33rrPVC4YKeFbB1gIxqkUOEDl8fxsou5Jx/MQivyz90lE8yxbcGV/Zzx4ZJaHN+jz6mfM6mADEWp/nUcfO9tECijOhPPYt/8aE3py38NlFZuafZ2CwdL7RmDX7YCjpiIYxXaIjSv61WPD1SLkOkusnoA7bJZ2xmJ/dfEMXEA4LCCOfGQ,iv:922rrz94pD3/R1kGlQyIFkoq/fRSyxaIQ5qllldQMCY=,tag:AAPlwiQP4KMzHZmcMH76AQ==,type:str] lapi.yaml: ENC[AES256_GCM,data:BpDlz/liFYVZTA66TMWDifGfT4R9l0W9/LOU33rrPVC4YKeFbB1gIxqkUOEDl8fxsou5Jx/MQivyz90lE8yxbcGV/Zzx4ZJaHN+jz6mfM6mADEWp/nUcfO9tECijOhPPYt/8aE3py38NlFZuafZ2CwdL7RmDX7YCjpiIYxXaIjSv61WPD1SLkOkusnoA7bJZ2xmJ/dfEMXEA4LCCOfGQ,iv:922rrz94pD3/R1kGlQyIFkoq/fRSyxaIQ5qllldQMCY=,tag:AAPlwiQP4KMzHZmcMH76AQ==,type:str]
capi.yaml: ENC[AES256_GCM,data:UuBESeHfKEPSIzP7RPNES0BVWwJsmPqLP3QJbAeAcm6eQ3sRzUSrVxY8A2yoiLD2lnuJPy2BbYHJpBR7VSfs7oUCc7LljgAp1uB2GH1y8YE46xJLo0TDp873bZJdcsO00ozsbtmWlGWJm7HLrzIUEe0mAjBzZeXe1WDJByGeVqupNLwpXSMaos2ktHjXA6hTGAdE5iIxBAXI6qjldWjRnlqE,iv:hZ2nUaOipU7Top0vsn23yU0XWP9SKcoj85xFo5hD/mU=,tag:32E2o+FOJXM9aMnLQA6KYA==,type:str] capi.yaml: ENC[AES256_GCM,data:UuBESeHfKEPSIzP7RPNES0BVWwJsmPqLP3QJbAeAcm6eQ3sRzUSrVxY8A2yoiLD2lnuJPy2BbYHJpBR7VSfs7oUCc7LljgAp1uB2GH1y8YE46xJLo0TDp873bZJdcsO00ozsbtmWlGWJm7HLrzIUEe0mAjBzZeXe1WDJByGeVqupNLwpXSMaos2ktHjXA6hTGAdE5iIxBAXI6qjldWjRnlqE,iv:hZ2nUaOipU7Top0vsn23yU0XWP9SKcoj85xFo5hD/mU=,tag:32E2o+FOJXM9aMnLQA6KYA==,type:str]
consoleToken: ENC[AES256_GCM,data:Q6QWWwcvLd8+ddwPMBzyB+X4gh8I53qSLA==,iv:JD48L59nQYttglAfuKL/lNBzWgBfj01rkIeP8pqmo70=,tag:6cxsQViDGuzjScKkBuO4Bw==,type:str] consoleToken: ENC[AES256_GCM,data:Q6QWWwcvLd8+ddwPMBzyB+X4gh8I53qSLA==,iv:JD48L59nQYttglAfuKL/lNBzWgBfj01rkIeP8pqmo70=,tag:6cxsQViDGuzjScKkBuO4Bw==,type:str]
rspamd: ENC[AES256_GCM,data:8DryYdMyhzBqwqcbYUQ=,iv:5w21u3xqshRSf8IJbG16/Gf6AC2Zw6VnI3MOchN+w8A=,tag:OiiYUDT69SZObgOh1qCL0g==,type:str] rspamd: ENC[AES256_GCM,data:8DryYdMyhzBqwqcbYUQ=,iv:5w21u3xqshRSf8IJbG16/Gf6AC2Zw6VnI3MOchN+w8A=,tag:OiiYUDT69SZObgOh1qCL0g==,type:str]
pangolin:
env: ENC[AES256_GCM,data:f5Pq+DE9PeRyOKeygREuovlqOMhe/bmTOrBA7Px3Oq+pWG5kGwnxqDdP/PwawJAskQPC9LN+QP6hIPNrJbPyxtk87hoRMb/3X0ggOw==,iv:yqqQizPwf3EfCelczf/7piH9kYiAwGLTtassvQ8oXNs=,tag:UzVuKIS8WZNAHgpLkzc9XA==,type:str]
sops: sops:
age: age:
- recipient: age1uvsvf5ljaezh5wze32p685kfentyle0l2mvysc67yvgct2h4850qqph9lv - recipient: age1uvsvf5ljaezh5wze32p685kfentyle0l2mvysc67yvgct2h4850qqph9lv
@ -38,7 +37,7 @@ sops:
MEdmWkFwNXZoR1ZVRnQ0aWlkYzZwSmsK0EFecUIdqlDKX08oRCoDQQ3QCX1wzb8w MEdmWkFwNXZoR1ZVRnQ0aWlkYzZwSmsK0EFecUIdqlDKX08oRCoDQQ3QCX1wzb8w
lghDJhWlfuKr+X24GoE4UK04aJVLqVMRRI4BJW+LQXeHS+dWKu3mQA== lghDJhWlfuKr+X24GoE4UK04aJVLqVMRRI4BJW+LQXeHS+dWKu3mQA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-19T12:39:37Z" lastmodified: "2026-01-07T08:17:20Z"
mac: ENC[AES256_GCM,data:JSwphdjAfZcLSuctzruwVjBQXhbQKnEda93KlrH8eoSJcFXBRCMz0v+HY2nBlrC9lwp9vgT3HnGmR6hIPi48UtyxYcGOJy33OY4M1it0WGE2r8Ikg++5cBUtacK4QdwuMCADhNT5ZHs5T7UUX0GMLeqAtrcJ3FKt+4+catsOvnE=,iv:7ZTi86IkbScizZlOCk+uXDyWzrFDsLRuLuzjUFsMFR0=,tag:3/i7BZ8XYALj7RYj4dIUgA==,type:str] mac: ENC[AES256_GCM,data:M9hBNU2KetaGEhJnYW10nWEWetFWs9c5gPN/0W6UIOsP2Y9E2d8J09Ary9O9z6TjjxqkS+H15SQfo6bjuc19jSwtdQ/scqy9nV1H0pOEHzWj8zG/bzC71WmwhZbx4+1cK83HYS9pJhzbO+5tbOK75GwJscXAhXKDzzNBmTW2Y3U=,iv:qozD5Z2uiI5vFApsRVkjiXLOPATs3VV0PDk5szX+mrc=,tag:WpM+Ab9U2q9GR0qvyMZO8w==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.11.0 version: 3.11.0

View file

@ -7,17 +7,6 @@ in
secrets = { secrets = {
"lam/env" = { }; "lam/env" = { };
"netbird/oidc/secret" = mkIf config.services.netbird.server.dashboard.enable {
owner = "netbird";
};
"netbird/coturn/password" = mkIf config.services.netbird.server.coturn.enable {
owner = "turnserver";
key = "netbird/oidc/secret";
};
"netbird/dataStoreKey" = mkIf config.services.netbird.server.management.enable {
owner = "netbird";
};
"acme/pdns" = mkIf (hasAttr "acme" config.users.users) { "acme/pdns" = mkIf (hasAttr "acme" config.users.users) {
owner = "acme"; owner = "acme";
}; };

View file

@ -67,6 +67,7 @@ in
"roundcube" "roundcube"
"grafana" "grafana"
"crowdsec" "crowdsec"
"netbird"
]; ];
location = "${backupPath}/postgresql"; location = "${backupPath}/postgresql";
}; };

View file

@ -17,11 +17,9 @@ in
"maps.rspamd.com" "maps.rspamd.com"
"cdn-hub.crowdsec.net" "cdn-hub.crowdsec.net"
"api.crowdsec.net" "api.crowdsec.net"
"mx1.daccc.info"
"mx1.dnywe.com" "mx1.dnywe.com"
]; ];
allowedIPs = [ allowedIPs = [
"10.0.0.0/24"
"127.0.0.1" "127.0.0.1"
# CrowdSec # CrowdSec
"52.51.161.146" "52.51.161.146"

View file

@ -3,5 +3,6 @@
./nginx.nix ./nginx.nix
./services.nix ./services.nix
./step-ca.nix ./step-ca.nix
./wireguard.nix
]; ];
} }

View file

@ -64,14 +64,6 @@
locations."/".proxyPass = "http://10.0.0.130:8001/phone.html"; locations."/".proxyPass = "http://10.0.0.130:8001/phone.html";
}; };
"ca.net.dn" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "https://10.0.0.1:8443/";
};
};
}; };
}; };
} }

View file

@ -6,8 +6,9 @@
}: }:
let let
inherit (config.systemConf) username security; inherit (config.systemConf) username security;
inherit (lib) concatStringsSep; inherit (lib) concatStringsSep mkForce optionalString;
inherit (helper.nftables) mkElementsStatement; inherit (helper.nftables) mkElementsStatement;
netbirdCfg = config.services.netbird;
ethInterface = "enp0s31f6"; ethInterface = "enp0s31f6";
sshPorts = [ 30072 ]; sshPorts = [ 30072 ];
@ -23,19 +24,16 @@ let
restrict = "10.0.0.128/25"; restrict = "10.0.0.128/25";
}; };
kube = { infra = {
ip = "10.10.0.1/24"; ip = "10.10.0.2/32";
range = "10.10.0.0/24";
interface = "wg1"; interface = "wg1";
port = 51821; range = "10.10.0.0/24";
masterIP = "10.10.0.1";
masterHostname = "api-kube.${config.networking.domain}";
masterAPIServerPort = 6443;
}; };
allowedSSHIPs = concatStringsSep ", " [ allowedSSHIPs = concatStringsSep ", " [
"122.117.215.55" "122.117.215.55"
"192.168.100.1/24" "192.168.100.1/24"
"100.64.0.0/16"
personal.range personal.range
]; ];
@ -168,6 +166,13 @@ let
]; ];
in in
{ {
systemConf.security.allowedIPs = [
"10.10.0.0/24"
"10.0.0.0/24"
];
services.resolved.enable = mkForce false;
networking = { networking = {
nat = { nat = {
enable = true; enable = true;
@ -175,7 +180,6 @@ in
externalInterface = ethInterface; externalInterface = ethInterface;
internalInterfaces = [ internalInterfaces = [
personal.interface personal.interface
kube.interface
]; ];
}; };
@ -183,15 +187,12 @@ in
allowedUDPPorts = [ allowedUDPPorts = [
53 53
personal.port personal.port
kube.port
25565 25565
kube.masterAPIServerPort
5359 5359
]; ];
allowedTCPPorts = sshPorts ++ [ allowedTCPPorts = sshPorts ++ [
53 53
25565 25565
kube.masterAPIServerPort
5359 5359
]; ];
}; };
@ -235,9 +236,10 @@ in
tcp dport { ${sshPortsString} } jump ssh-filter tcp dport { ${sshPortsString} } jump ssh-filter
iifname { ${ethInterface}, ${personal.interface}, ${kube.interface} } udp dport { ${toString personal.port}, ${toString kube.port} } accept iifname { ${ethInterface}, ${personal.interface} } udp dport { ${toString personal.port} } accept
iifname ${personal.interface} ip saddr ${personal.ip} jump wg-subnet iifname ${infra.interface} ip saddr ${infra.range} accept
iifname ${kube.interface} ip saddr ${kube.ip} jump kube-filter iifname ${personal.interface} ip saddr ${personal.range} jump wg-subnet
iifname ${netbirdCfg.clients.wt0.interface} accept
drop drop
} }
@ -251,6 +253,11 @@ in
udp dport 53 accept udp dport 53 accept
tcp dport 53 accept tcp dport 53 accept
# Allow UDP hole punching
${optionalString (
netbirdCfg.clients ? wt0
) ''udp sport ${toString netbirdCfg.clients.wt0.port} accept''}
meta skuid ${toString config.users.users.systemd-timesync.uid} accept meta skuid ${toString config.users.users.systemd-timesync.uid} accept
ct state vmap { invalid : drop, established : accept, related : accept } ct state vmap { invalid : drop, established : accept, related : accept }
@ -273,16 +280,11 @@ in
meta l4proto { icmp, ipv6-icmp } accept meta l4proto { icmp, ipv6-icmp } accept
iifname ${personal.interface} ip saddr ${personal.ip} jump wg-subnet iifname ${personal.interface} ip saddr ${personal.ip} jump wg-subnet
iifname ${kube.interface} ip saddr ${kube.ip} jump kube-filter iifname ${infra.interface} ip saddr ${infra.ip} accept
counter counter
} }
chain kube-filter {
ip saddr ${kube.ip} ip daddr ${kube.ip} accept
counter drop
}
chain wg-subnet { chain wg-subnet {
ip saddr ${personal.full} accept ip saddr ${personal.full} accept
ip saddr ${personal.restrict} ip daddr ${personal.range} accept ip saddr ${personal.restrict} ip daddr ${personal.range} accept
@ -309,17 +311,8 @@ in
inherit (r) publicKey allowedIPs; inherit (r) publicKey allowedIPs;
}) (fullRoute ++ meshRoute); }) (fullRoute ++ meshRoute);
}; };
${kube.interface} = {
ips = [ kube.ip ];
listenPort = kube.port;
privateKeyFile = config.sops.secrets."wireguard/privateKey".path;
peers = [ ];
};
}; };
}; };
extraHosts = "${kube.masterIP} ${kube.masterHostname}";
}; };
services = { services = {
@ -349,7 +342,7 @@ in
openssh = { openssh = {
enable = true; enable = true;
ports = sshPorts; ports = mkForce sshPorts;
settings = { settings = {
PasswordAuthentication = false; PasswordAuthentication = false;
UseDns = false; UseDns = false;
@ -385,9 +378,7 @@ in
pdns-recursor = { pdns-recursor = {
enable = true; enable = true;
forwardZones = { forwardZones = {
"${config.networking.domain}." = "127.0.0.1:5359"; "dn." = "127.0.0.1:5359";
"pre7780.dn." = "127.0.0.1:5359";
"test.local." = "127.0.0.1:5359";
}; };
forwardZonesRecurse = { forwardZonesRecurse = {
# ==== Rspamd DNS ==== # # ==== Rspamd DNS ==== #
@ -514,7 +505,7 @@ in
"uptime.${config.networking.domain}" = { "uptime.${config.networking.domain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/".proxyPass = "http://localhost:3001"; locations."/".proxyPass = "http://127.0.0.1:3001";
}; };
}; };

View file

@ -80,4 +80,12 @@ Bq-3sY8n13Dv0E6yx2hVIAlzLj3aE29LC4A2j81vW5MtpaM27lMpg.cwlqZ-8l1iZNeeS9.idRpRJ9zB
openFirewall = true; openFirewall = true;
intermediatePasswordFile = config.sops.secrets."step_ca/password".path; intermediatePasswordFile = config.sops.secrets."step_ca/password".path;
}; };
services.nginx.virtualHosts."ca.net.dn" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "https://10.0.0.1:8443/";
};
};
} }

View file

@ -0,0 +1,5 @@
{ config, ... }:
{
sops.secrets."wireguard/wg1.conf" = { };
networking.wg-quick.interfaces.wg1.configFile = config.sops.secrets."wireguard/wg1.conf".path;
}

View file

@ -5,7 +5,12 @@
... ...
}: }:
let let
inherit (lib) mkOption types concatStringsSep; inherit (lib)
mkOption
types
concatStringsSep
unique
;
cfg = config.systemConf.security; cfg = config.systemConf.security;
in in
{ {
@ -14,6 +19,7 @@ in
type = with types; listOf str; type = with types; listOf str;
description = "Domains that allowed to query dns."; description = "Domains that allowed to query dns.";
default = [ ]; default = [ ];
apply = v: unique v;
}; };
rules = { rules = {
setName = mkOption { setName = mkOption {

View file

@ -4,6 +4,8 @@
extraAllowList = [ extraAllowList = [
"10.0.0.0/24" "10.0.0.0/24"
"122.117.215.55" "122.117.215.55"
# Netbird
"100.104.0.0/16"
]; ];
}) })
]; ];

View file

@ -3,11 +3,15 @@
imports = [ imports = [
./actual-budget.nix ./actual-budget.nix
./bitwarden.nix ./bitwarden.nix
# ./docmost.nix ./minecraft-server.nix
./mail-server.nix ./mail-server.nix
./nextcloud.nix ./nextcloud.nix
./paperless-ngx.nix ./paperless-ngx.nix
./metrics.nix ./metrics.nix
./forgejo.nix
./keycloak.nix
./netbird.nix
./hideTTY.nix
# (import ../../../modules/opencloud.nix { # (import ../../../modules/opencloud.nix {
# fqdn = "opencloud.net.dn"; # fqdn = "opencloud.net.dn";
# envFile = config.sops.secrets."opencloud".path; # envFile = config.sops.secrets."opencloud".path;

View file

@ -0,0 +1,72 @@
{ lib, config, ... }:
let
cfg = config.services.forgejo;
srv = cfg.settings.server;
domain = "git.dnywe.com";
mailServer = "mx1.net.dn";
forgejoOwner = {
owner = "forgejo";
mode = "400";
};
in
{
sops.secrets = {
"forgejo/mailer/password" = forgejoOwner;
"forgejo/server/secretKey" = forgejoOwner;
};
networking.firewall.allowedTCPPorts = [ srv.HTTP_PORT ];
services.postgresqlBackup.databases = [ cfg.database.name ];
systemd.services.forgejo.preStart =
let
adminCmd = "${lib.getExe cfg.package} admin user";
pwd = config.sops.secrets."forgejo/mailer/password";
user = "forgejo";
in
''
${adminCmd} create --admin --email "noreply@${srv.DOMAIN}" --username ${user} --password "$(tr -d '\n' < ${pwd.path})" || true
'';
services.openssh.settings.AllowUsers = [ cfg.user ];
services.forgejo = {
enable = true;
database.type = "postgres";
lfs.enable = true;
settings = {
server = {
DOMAIN = domain;
ROOT_URL = "https://${srv.DOMAIN}";
HTTP_PORT = 32006;
SSH_PORT = lib.head config.services.openssh.ports;
# ==== OpenID Connect ==== #
ENABLE_OPENID_SIGNIN = true;
WHITELISTED_URIS = "https://${config.services.keycloak.settings.hostname}/*";
};
services.DISABLE_REGISTRATION = true;
actions = {
ENABLE = true;
DEFAULT_ACTION_URL = "github";
};
mailer = {
ENABLED = true;
SMTP_ADDR = mailServer;
SMTP_PORT = 587;
FROM = "noreply@${srv.DOMAIN}";
USER = "noreply@${srv.DOMAIN}";
};
};
secrets = {
mailer.PASSWD = config.sops.secrets."forgejo/mailer/password".path;
server.SECRET_KEY = config.sops.secrets."forgejo/server/secretKey".path;
};
};
}

View file

@ -0,0 +1,13 @@
{ ... }:
{
systemd.services.hideTTY = {
description = "Auto turn off monitor ";
wantedBy = [ "multi-user.target" ];
script = ''
echo 1 > /sys/class/graphics/fb0/blank
'';
serviceConfig = {
Type = "oneshot";
};
};
}

View file

@ -0,0 +1,17 @@
# NOTE: This is keycloak partial overwrite for `mail-server.nix`.
{ lib, config, ... }:
let
inherit (lib) mkForce;
domain = "dnywe.com";
cfg = config.services.keycloak;
in
{
services.keycloak = {
settings = {
hostname = mkForce "login.${domain}";
};
};
# Disable nginx reverse proxy
services.nginx.virtualHosts."${cfg.settings.hostname}" = mkForce { };
}

View file

@ -1,9 +1,25 @@
{ config, lib, ... }: {
config,
lib,
...
}:
let let
inherit (lib) mkForce; inherit (lib) mkForce;
inherit (config.systemConf) username; inherit (config.systemConf) username;
in in
{ {
systemConf.security.allowedDomains = [
"registry-1.docker.io"
"auth.docker.io"
"login.docker.com"
"auth.docker.com"
"production.cloudflare.docker.com"
"docker-images-prod.6aa30f8b08e16409b46e0173d6de2f56.r2.cloudflarestorage"
"api.docker.com"
"cdn.segment.com"
"api.segment.io"
];
mail-server = mail-server =
let let
domain = "net.dn"; domain = "net.dn";
@ -81,29 +97,16 @@ in
}; };
}; };
services.openldap.settings.attrs.olcLogLevel = mkForce "config"; virtualisation.oci-containers.containers.phpLDAPadmin = {
environment = {
services.postfix.settings.main = { LDAP_ALLOW_GUEST = "true";
# internal_mail_filter_classes = [ "bounce" ]; LOG_LEVEL = "debug";
LDAP_LOGGING = "true";
};
}; };
services.rspamd = { services.openldap.settings = {
locals."logging.conf".text = '' attrs.olcLogLevel = mkForce "config";
level = "debug"; # children."cn=schema".includes = extraSchemas;
'';
locals."settings.conf".text = ''
bounce {
id = "bounce";
priority = high;
ip = "127.0.0.1";
selector = 'smtp_from.regexp("/^$/").last';
apply {
BOUNCE = -25.0;
}
symbols [ "BOUNCE" ]
}
'';
}; };
} }

View file

@ -63,7 +63,7 @@ in
job_name = "powerdns_recursor"; job_name = "powerdns_recursor";
static_configs = [ static_configs = [
{ {
targets = [ "localhost:${toString config.services.pdns-recursor.api.port}" ]; targets = [ "127.0.0.1:${toString config.services.pdns-recursor.api.port}" ];
labels = { labels = {
machine = "${hostName}"; machine = "${hostName}";
}; };
@ -87,7 +87,7 @@ in
static_configs = [ static_configs = [
{ {
targets = [ targets = [
"localhost:${toString config.services.crowdsec.settings.general.prometheus.listen_port}" "127.0.0.1:${toString config.services.crowdsec.settings.general.prometheus.listen_port}"
]; ];
labels = { labels = {
machine = "${hostName}"; machine = "${hostName}";

View file

@ -0,0 +1,40 @@
{ pkgs, ... }:
let
modpack = pkgs.fetchPackwizModpack {
url = "https://git.dnywe.com/dachxy/shader-retired-modpack/raw/branch/main/pack.toml";
packHash = "sha256-NPMS8j5NXbtbsso8R4s4lhx5L7rQJdek62G2Im3JdmM=";
};
in
{
systemConf.security.allowedDomains = [
"api.mojang.com"
"textures.minecraft.net"
"session.minecraft.net"
"login.microsoftonline.com"
];
services.minecraft-servers = {
enable = true;
eula = true;
};
services.minecraft-servers.servers.shader-retired = {
enable = true;
autoStart = true;
openFirewall = true;
package = pkgs.fabric-server;
symlinks = {
"mods" = "${modpack}/mods";
};
serverProperties = {
server-port = 25565;
difficulty = 3;
gamemode = "survival";
max-player = 20;
modt = "Bro!!!!";
accepts-flight = true;
accepts-transfers = true;
hardcore = false;
};
};
}

View file

@ -0,0 +1,119 @@
{ config, lib, ... }:
let
inherit (lib) mkForce;
domain = "dnywe.com";
# Virtual Domain
vDomain = "vnet.dn";
proxyIP = "10.10.0.1";
cfg = config.services.netbird;
srv = cfg.server;
# TODO: Change realm to master
realm = "netbird";
in
{
sops.secrets."netbird/wt0-setupKey" = {
owner = cfg.clients.wt0.user.name;
mode = "400";
};
systemConf.security.allowedDomains = [
"login.dnywe.com"
"pkgs.netbird.io"
"${srv.domain}"
];
imports = [
(import ../../../modules/netbird-server.nix {
inherit realm vDomain;
domain = "netbird.${domain}";
oidcURL = "https://${config.services.keycloak.settings.hostname}";
enableNginx = false;
oidcType = "keycloak";
})
];
services.netbird = {
ui.enable = mkForce false;
clients.wt0 = {
port = 51830;
openFirewall = true;
autoStart = true;
environment = {
NB_MANAGEMENT_URL = "https://${srv.domain}";
};
login = {
enable = true;
setupKeyFile = config.sops.secrets."netbird/wt0-setupKey".path;
};
};
server.management = {
disableSingleAccountMode = false;
singleAccountModeDomain = vDomain;
metricsPort = 32009;
turnDomain = mkForce "coturn.${domain}";
extraOptions = [ "--user-delete-from-idp" ];
};
server.coturn.enable = mkForce false;
};
networking.firewall.allowedTCPPorts = [ 32011 ];
# ==== Proxy By Caddy & CDN ==== #
services.nginx.appendHttpConfig = ''
set_real_ip_from ${proxyIP};
real_ip_header X-Forwarded-For;
real_ip_recursive on;
'';
services.nginx.virtualHosts."netbird.local" = {
locations = {
"/" = {
root = cfg.server.dashboard.finalDrv;
tryFiles = "$uri $uri.html $uri/ =404";
};
"/404.html".extraConfig = ''
internal;
'';
"/api" = {
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
'';
proxyPass = "http://127.0.0.1:${builtins.toString srv.management.port}";
};
"/management.ManagementService/".extraConfig = ''
client_body_timeout 1d;
grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
grpc_pass grpc://127.0.0.1:${builtins.toString srv.management.port};
grpc_read_timeout 1d;
grpc_send_timeout 1d;
grpc_socket_keepalive on;
'';
"/signalexchange.SignalExchange/".extraConfig = ''
client_body_timeout 1d;
grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
grpc_pass grpc://127.0.0.1:${builtins.toString srv.signal.port};
grpc_read_timeout 1d;
grpc_send_timeout 1d;
grpc_socket_keepalive on;
'';
};
extraConfig = ''
error_page 404 /404.html;
'';
};
}

View file

@ -1,19 +1,156 @@
{ config, ... }:
{ {
config,
pkgs,
lib,
...
}:
let
inherit (lib) mkIf mkDefault mkAfter;
inherit (config.sops) secrets;
spreedCfg = config.services.nextcloud-spreed-signaling;
nextcloudCfg = config.services.nextcloud;
turnDomain = "coturn.dnywe.com";
domain = "net.dn";
in
{
sops.secrets = {
"nextcloud/smtpPassword" = {
owner = "nextcloud";
group = "nextcloud";
};
"nextcloud/adminPassword" = { };
"nextcloud/whiteboard" = {
owner = "nextcloud";
};
"nextcloud/spreed/turnPassword" = {
key = "netbird/coturn/password";
owner = spreedCfg.user;
};
"nextcloud/spreed/turnSecret" = {
key = "netbird/oidc/secret";
owner = spreedCfg.user;
};
"nextcloud/spreed/hashkey" = {
owner = spreedCfg.user;
};
"nextcloud/spreed/blockkey" = {
owner = spreedCfg.user;
};
"nextcloud/spreed/internalsecret" = {
owner = spreedCfg.user;
};
"nextcloud/spreed/backendsecret" = {
owner = spreedCfg.user;
};
};
imports = [ imports = [
(import ../../../modules/nextcloud.nix { (import ../../../modules/nextcloud.nix {
hostname = "nextcloud.net.dn"; hostname = "nextcloud.${domain}";
adminpassFile = config.sops.secrets."nextcloud/adminPassword".path; adminpassFile = secrets."nextcloud/adminPassword".path;
trusted-proxies = [ "10.0.0.0/24" ]; trusted-proxies = [ "10.0.0.0/24" ];
whiteboardSecrets = [ whiteboardSecrets = [
config.sops.secrets."nextcloud/whiteboard".path secrets."nextcloud/whiteboard".path
]; ];
}) })
]; ];
services.nextcloud = { services.nextcloud = {
extraApps = { extraApps = {
inherit (config.services.nextcloud.package.packages.apps) music; inherit (config.services.nextcloud.package.packages.apps) music spreed;
user_migration = pkgs.fetchNextcloudApp {
url = "https://github.com/nextcloud-releases/user_migration/releases/download/v9.0.0/user_migration-v9.0.0.tar.gz";
sha256 = "sha256-WiEEAazuj8kh5o+URs22uoNWANXcXQYLTaoABMU6rFo=";
license = "agpl3Plus";
};
cospend = pkgs.fetchNextcloudApp {
url = "https://github.com/julien-nc/cospend-nc/releases/download/v3.2.0/cospend-3.2.0.tar.gz";
sha256 = "sha256-mclcZDNmvpYX/2q7azyiTLSCiTYvk7ILeqtb/8+0ADQ=";
license = "agpl3Plus";
};
};
appstoreEnable = false;
settings = {
mail_smtpauth = true;
mail_smtphost = "mx1.${domain}";
mail_smtpname = "nextcloud";
mail_smtpmode = "smtp";
mail_smtpauthtype = "LOGIN";
mail_domain = "net.dn";
mail_smtpport = 465;
mail_smtpsecure = "ssl";
mail_from_address = "nextcloud";
};
secrets = {
mail_smtppassword = secrets."nextcloud/smtpPassword".path;
}; };
}; };
# ==== Nextcloud Talk ==== #
services.nextcloud-spreed-signaling = {
enable = true;
configureNginx = true;
hostName = "talk.${domain}";
backends.default = {
urls = [ "https://${nextcloudCfg.hostName}" ];
secretFile = secrets."nextcloud/spreed/backendsecret".path;
};
settings = {
http.listen = "127.0.0.1:31008";
turn = {
servers = [ "turn:${turnDomain}:3478?transport=udp" ];
secretFile = secrets."nextcloud/spreed/turnPassword".path;
apikeyFile = secrets."nextcloud/spreed/turnSecret".path;
};
clients.internalsecretFile = secrets."nextcloud/spreed/internalsecret".path;
sessions = {
hashkeyFile = secrets."nextcloud/spreed/hashkey".path;
blockkeyFile = secrets."nextcloud/spreed/blockkey".path;
};
nats.url = [ "nats://127.0.0.1:4222" ];
};
};
services.nats = mkIf nextcloudCfg.enable {
enable = true;
settings = {
host = "127.0.0.1";
};
};
services.nginx.virtualHosts.${spreedCfg.hostName} = {
enableACME = true;
forceSSL = true;
};
# ==== Secruity ==== #
services.fail2ban = {
jails = {
nextcloud.settings = {
backend = "systemd";
journalmatch = "SYSLOG_IDENTIFIER=Nextcloud";
enabled = true;
port = 443;
protocol = "tcp";
filter = "nextcloud";
maxretry = 3;
bantime = 86400;
findtime = 43200;
};
};
};
environment.etc = {
"fail2ban/filter.d/nextcloud.local".text = mkDefault (mkAfter ''
[Definition]
failregex = ^.*"remoteAddr":"(?P<host><HOST>)".*"message":"Login failed:
^.*"remoteAddr":"(?P<host><HOST>)".*"message":"Two-factor challenge failed:
^.*"remoteAddr":"(?P<host><HOST>)".*"message":"Trusted domain error
'');
};
} }

File diff suppressed because one or more lines are too long

View file

@ -5,10 +5,6 @@ in
{ {
sops.secrets = { sops.secrets = {
"wireguard/privateKey" = { }; "wireguard/privateKey" = { };
"nextcloud/adminPassword" = { };
"nextcloud/whiteboard" = {
owner = "nextcloud";
};
"step_ca/password" = { }; "step_ca/password" = { };
vaultwarden = { }; vaultwarden = { };
"oauth/password" = { }; "oauth/password" = { };

View file

@ -10,11 +10,11 @@ in
systemConf = { systemConf = {
inherit hostname username; inherit hostname username;
domain = "net.dn"; domain = "net.dn";
hyprland.enable = true; # hyprland.enable = true;
niri.enable = true;
face = pkgs.fetchurl { face = pkgs.fetchurl {
url = "https://files.net.dn/skydrive.jpg"; url = "https://git.dnywe.com/dachxy/skydrive-avatar/raw/branch/main/skydrive.jpg";
hash = "sha256-aMjl6VL1Zy+r3ElfFyhFOlJKWn42JOnAFfBXF+GPB/Q="; hash = "sha256-aMjl6VL1Zy+r3ElfFyhFOlJKWn42JOnAFfBXF+GPB/Q=";
curlOpts = "-k";
}; };
}; };
@ -22,9 +22,9 @@ in
../../modules/presets/basic.nix ../../modules/presets/basic.nix
./common ./common
./games ./games
./services
./sops ./sops
./utility ./utility
./network
]; ];
users.users.root.openssh.authorizedKeys.keys = [ users.users.root.openssh.authorizedKeys.keys = [

View file

@ -0,0 +1,6 @@
{ ... }:
{
imports = [
./netbird.nix
];
}

View file

@ -0,0 +1,17 @@
{ self, ... }:
let
serverCfg = self.nixosConfigurations.dn-server.config;
domain = serverCfg.services.netbird.server.domain;
in
{
services.netbird = {
clients.wt0 = {
openFirewall = true;
autoStart = true;
port = 51820;
environment = {
NB_MANAGEMENT_URL = "https://${domain}";
};
};
};
}

View file

@ -1,5 +0,0 @@
{
imports = [
./wireguard.nix
];
}

View file

@ -1,5 +0,0 @@
{
imports = [
../../../modules/wireguard.nix
];
}

View file

@ -39,7 +39,7 @@ in
forceSSL = true; forceSSL = true;
locations."/api/".proxyPass = locations."/api/".proxyPass =
"http://localhost:${toString config.services.actual-budget-api.listenPort}/"; "http://127.0.0.1:${toString config.services.actual-budget-api.listenPort}/";
locations."/".proxyPass = "http://localhost:${toString config.services.actual.settings.port}"; locations."/".proxyPass = "http://127.0.0.1:${toString config.services.actual.settings.port}";
}; };
} }

View file

@ -28,6 +28,6 @@ in
services.nginx.virtualHosts."${domain}" = mkIf enableNginx { services.nginx.virtualHosts."${domain}" = mkIf enableNginx {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/".proxyPass = "http://localhost:${toString config.services.cockpit.port}"; locations."/".proxyPass = "http://127.0.0.1:${toString config.services.cockpit.port}";
}; };
} }

View file

@ -46,10 +46,10 @@ in
if (fqdn != null) then if (fqdn != null) then
"${if https then "https" else "http"}://${fqdn}" "${if https then "https" else "http"}://${fqdn}"
else else
"http://localhost:${toString port}" "http://127.0.0.1:${toString port}"
}"; }";
DATABASE_URL = "postgresql://docmost@docmost?schema=public&host=/var/run/postgresql"; DATABASE_URL = "postgresql://docmost@docmost?schema=public&host=/var/run/postgresql";
REDIS_URL = "redis://localhost:${toString config.services.redis.servers.docmost.port}"; REDIS_URL = "redis://127.0.0.1:${toString config.services.redis.servers.docmost.port}";
} }
// extraConf // extraConf
); );
@ -77,7 +77,7 @@ in
enableACME = lib.mkIf https true; enableACME = lib.mkIf https true;
forceSSL = lib.mkIf https true; forceSSL = lib.mkIf https true;
locations."/" = { locations."/" = {
proxyPass = "http://localhost:${toString port}"; proxyPass = "http://127.0.0.1:${toString port}";
proxyWebsockets = true; proxyWebsockets = true;
}; };
}; };

View file

@ -1,5 +1,5 @@
{ {
extreAllowList ? [ ], extraAllowList ? [ ],
... ...
}: }:
{ {
@ -9,7 +9,7 @@
ignoreIP = [ ignoreIP = [
"192.168.0.0/16" "192.168.0.0/16"
] ]
++ extreAllowList; ++ extraAllowList;
bantime = "24h"; bantime = "24h";
bantime-increment = { bantime-increment = {
enable = true; enable = true;

View file

@ -11,7 +11,7 @@
optimise.automatic = true; optimise.automatic = true;
gc = { gc = {
automatic = true; automatic = true;
dates = [ "03:15" ]; dates = "weekly";
options = "--delete-older-than 7d"; options = "--delete-older-than 7d";
}; };
}; };

View file

@ -0,0 +1,31 @@
{
self,
config,
...
}:
let
serverCfg = self.nixosConfigurations.dn-server.config;
cfg = config.services.netbird;
domain = serverCfg.services.netbird.server.domain;
in
{
sops.secrets."netbird/wt0-setupKey" = {
owner = cfg.clients.wt0.user.name;
mode = "400";
};
services.netbird = {
clients.wt0 = {
openFirewall = true;
autoStart = true;
port = 51820;
environment = {
NB_MANAGEMENT_URL = "https://${domain}";
};
login = {
enable = true;
setupKeyFile = config.sops.secrets."netbird/wt0-setupKey".path;
};
};
};
}

View file

@ -0,0 +1,123 @@
{
domain,
oidcURL,
vDomain ? null,
enableNginx ? false,
oidcType ? "keycloak",
realm ? "netbird",
}:
{
lib,
config,
...
}:
let
inherit (lib) mkIf mkForce;
inherit (config.sops) secrets;
cfg = config.services.netbird;
srv = cfg.server;
dnsDomain = if vDomain == null then domain else vDomain;
in
{
sops.secrets = {
"netbird/oidc/secret" = { };
"netbird/turn/secret" = {
key = "netbird/oidc/secret";
};
"netbird/turn/password" = {
key = "netbird/coturn/password";
};
"netbird/coturn/password" = mkIf config.services.netbird.server.coturn.enable {
owner = "turnserver";
};
"netbird/dataStoreKey" = { };
};
services.postgresql = {
enable = true;
ensureDatabases = [ "netbird" ];
ensureUsers = [
{
name = "netbird";
ensureDBOwnership = true;
}
];
};
systemd.services.netbird-management.environment = {
NETBIRD_STORE_ENGINE_POSTGRES_DSN = "host=/var/run/postgresql user=netbird dbname=netbird";
};
services.netbird = {
ui.enable = true;
server = {
inherit domain enableNginx;
enable = true;
# ==== Signal ==== #
signal.enable = true;
# ==== Management ==== #
management = {
inherit dnsDomain;
# === turn === #
oidcConfigEndpoint = "${oidcURL}/realms/${realm}/.well-known/openid-configuration";
settings = {
StoreConfig.Engine = "postgres";
DataStoreEncryptionKey = {
_secret = secrets."netbird/dataStoreKey".path;
};
TURNConfig = {
Secret._secret = secrets."netbird/turn/secret".path;
Turns = mkForce [
{
Proto = "udp";
URI = "turn:${srv.management.turnDomain}:3478";
Username = "netbird";
Password._secret = secrets."netbird/turn/password".path;
}
];
};
IdpManagerConfig = {
ManagerType = oidcType;
ClientConfig = {
TokenEndpoint = "${oidcURL}/realms/${realm}/protocol/openid-connect/token";
ClientID = "netbird-backend";
ClientSecret = {
_secret = secrets."netbird/oidc/secret".path;
};
};
ExtraConfig = {
AdminEndpoint = "${oidcURL}/admin/realms/${realm}";
};
};
DeviceAuthorizationFlow.ProviderConfig = {
Audience = "netbird-client";
ClientID = "netbird-client";
};
PKCEAuthorizationFlow.ProviderConfig = {
Audience = "netbird-client";
ClientID = "netbird-client";
};
};
};
# ==== Dashboard ==== #
dashboard.settings = {
AUTH_AUTHORITY = "${oidcURL}/realms/${realm}";
AUTH_CLIENT_ID = "netbird-client";
AUTH_AUDIENCE = "netbird-client";
AUTH_SUPPORTED_SCOPES = "openid profile email offline_access api";
};
# ==== Coturn (STUN/TURN) ==== #
coturn = {
enable = true;
passwordFile = secrets."netbird/coturn/password".path;
useAcmeCertificates = enableNginx;
};
};
};
}

View file

@ -47,10 +47,42 @@ in
]; ];
}; };
systemd.services."phpfpm-nextcloud".postStart = mkIf config.services.nextcloud.enable '' systemd.services.nextcloud-config-recognize =
${config.services.nextcloud.occ}/bin/nextcloud-occ config:app:set recognize node_binary --value '${lib.getExe pkgs.nodejs_22}' let
${config.services.nextcloud.occ}/bin/nextcloud-occ config:app:set recognize tensorflow.purejs --value 'true' inherit (config.services.nextcloud) occ;
''; in
{
wantedBy = [ "multi-user.target" ];
after = [
"nextcloud-setup.service"
];
script = ''
${occ}/bin/nextcloud-occ config:app:set recognize node_binary --value '${lib.getExe pkgs.nodejs_22}'
${occ}/bin/nextcloud-occ config:app:set recognize tensorflow.purejs --value 'true'
'';
serviceConfig = {
Type = "oneshot";
};
};
# Disable Other login method for nextcloud
# Admin can login through adding `?direct=1` to url param
systemd.services.nextcloud-config-oidc =
let
inherit (config.services.nextcloud) occ;
in
{
wantedBy = [ "multi-user.target" ];
after = [
"nextcloud-setup.service"
];
script = ''
${occ}/bin/nextcloud-occ config:app:set --type=string --value=0 user_oidc allow_multiple_user_backends
'';
serviceConfig = {
Type = "oneshot";
};
};
services.nextcloud = { services.nextcloud = {
enable = true; enable = true;

View file

@ -31,6 +31,6 @@ in
services.nginx.virtualHosts."${domain}" = mkIf configureNginx { services.nginx.virtualHosts."${domain}" = mkIf configureNginx {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/".proxyPass = "http://localhost:${toString config.services.paperless.port}"; locations."/".proxyPass = "http://127.0.0.1:${toString config.services.paperless.port}";
}; };
} }

View file

@ -1,4 +1,7 @@
{ ... }: { lib, ... }:
let
inherit (lib) mkForce;
in
{ {
imports = [ imports = [
../environment.nix ../environment.nix
@ -18,5 +21,9 @@
../sops-nix.nix ../sops-nix.nix
../gc.nix ../gc.nix
../security.nix ../security.nix
../systemd-resolv.nix
]; ];
# Disable man cache
documentation.man.generateCaches = mkForce false;
} }

View file

@ -33,7 +33,7 @@ in
job_name = "master-server"; job_name = "master-server";
static_configs = [ static_configs = [
(optionalAttrs selfMonitor { (optionalAttrs selfMonitor {
targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ]; targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
}) })
]; ];
} }
@ -47,7 +47,7 @@ in
forceSSL = true; forceSSL = true;
locations."/" = { locations."/" = {
proxyPass = "http://localhost:${toString config.services.prometheus.port}"; proxyPass = "http://127.0.0.1:${toString config.services.prometheus.port}";
}; };
}; };
} }

View file

@ -8,7 +8,8 @@
loader.systemd-boot.enable = lib.mkForce false; loader.systemd-boot.enable = lib.mkForce false;
lanzaboote = { lanzaboote = {
enable = true; enable = true;
pkiBundle = "/var/lib/sbctl/"; autoGenerateKeys.enable = true;
pkiBundle = "/var/lib/sbctl";
}; };
}; };
} }

View file

@ -27,7 +27,7 @@ in
ports = [ 22 ]; ports = [ 22 ];
settings = { settings = {
PasswordAuthentication = lib.mkDefault false; PasswordAuthentication = lib.mkDefault false;
AllowUsers = lib.mkDefault [ username ]; AllowUsers = [ username ];
UseDns = lib.mkDefault false; UseDns = lib.mkDefault false;
PermitRootLogin = lib.mkDefault "no"; PermitRootLogin = lib.mkDefault "no";
}; };

View file

@ -65,6 +65,14 @@ in
}; };
calendar = { calendar = {
cards = [ cards = [
{
enabled = true;
id = "banner-card";
}
{
enabled = true;
id = "calendar-card";
}
{ {
enabled = true; enabled = true;
id = "timer-card"; id = "timer-card";
@ -73,14 +81,6 @@ in
enabled = true; enabled = true;
id = "weather-card"; id = "weather-card";
} }
{
enabled = true;
id = "calendar-header-card";
}
{
enabled = true;
id = "calendar-month-card";
}
]; ];
}; };
changelog = { changelog = {

View file

@ -0,0 +1,17 @@
{ ... }:
{
networking.nameservers = [
"1.1.1.1#one.one.one.one"
"1.0.0.1#one.one.one.one"
];
services.resolved = {
enable = true;
llmnr = "false";
fallbackDns = [
"1.1.1.1#one.one.one.one"
"1.0.0.1#one.one.one.one"
];
domains = [ "~." ];
};
}

View file

@ -34,7 +34,7 @@
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/" = { locations."/" = {
proxyPass = "http://localhost:${toString config.services.vaultwarden.config.ROCKET_PORT}/"; proxyPass = "http://127.0.0.1:${toString config.services.vaultwarden.config.ROCKET_PORT}/";
proxyWebsockets = true; proxyWebsockets = true;
}; };
}; };

View file

@ -22,8 +22,8 @@ let
watchDog = pkgs.writeShellScriptBin "wg0-watchdog" '' watchDog = pkgs.writeShellScriptBin "wg0-watchdog" ''
TARGET_CONF="$1" TARGET_CONF="$1"
PING_INTERVAL=1 PING_INTERVAL=10
PING_TIMEOUT=1 PING_TIMEOUT=10
PING_COUNT=1 PING_COUNT=1
set -euo pipefail set -euo pipefail
@ -37,7 +37,7 @@ let
notify() { notify() {
users=$(loginctl list-users --json=short | jq -r '.[].user') users=$(loginctl list-users --json=short | jq -r '.[].user')
for user in $users; do for user in $users; do
systemctl --machine=danny@.host --user start wg0-notify-user systemctl --machine="$user@.host" --user start wg0-notify-user
done done
} }
@ -46,13 +46,11 @@ let
} }
check_health() { check_health() {
ping -c "$PING_COUNT" -W "$PING_TIMEOUT" $1 >/dev/null 2>&1 ping -c "$PING_COUNT" -W "$PING_TIMEOUT" "$1" >/dev/null 2>&1
return $?
} }
is_wg_active() { is_wg_active() {
systemctl is-active wg-quick-wg0.service >/dev/null 2>&1 systemctl is-active wg-quick-wg0.service >/dev/null 2>&1
return $?
} }
start_wg() { start_wg() {
@ -105,15 +103,17 @@ in
}; };
systemd.services.wg0-watchdog = { systemd.services.wg0-watchdog = {
wantedBy = [ "wg-quick-wg0.service" ]; wantedBy = [ "multi-user.target" ];
after = [ "wg-quick-wg0.service" ];
path = with pkgs; [ path = with pkgs; [
jq jq
iputils
]; ];
serviceConfig = { serviceConfig = {
ExecStart = "${getExe watchDog} \"${config.sops.secrets."wireguard/wg0.conf".path}\""; ExecStart = "${getExe watchDog} \"${config.sops.secrets."wireguard/wg0.conf".path}\"";
RestartSec = 5; RestartSec = 5;
TimeoutStopSec = 0; TimeoutStopSec = 0;
CapabilityBoundingSet = "CAP_NET_RAW";
AmbientCapabilities = "CAP_NET_RAW";
}; };
}; };