chore: maintain

This commit is contained in:
danny 2026-01-20 13:41:53 +08:00
parent 2378a66114
commit 25482857d4
58 changed files with 1095 additions and 747 deletions

View file

@ -0,0 +1,59 @@
{
config,
pkgs,
...
}:
let
inherit (config.sops) secrets;
in
{
users.users.nginx.extraGroups = [ "acme" ];
sops.secrets = {
"acme/pdns" = {
mode = "0660";
owner = "acme";
group = "acme";
};
"acme/cloudflare" = {
mode = "0640";
};
};
systemConf.security.allowedDomains = [
"acme-v02.api.letsencrypt.org"
"api.cloudflare.com"
];
security.acme = {
acceptTerms = true;
defaults = {
server = "https://10.0.0.1:${toString config.services.step-ca.port}/acme/acme/directory";
validMinDays = 2;
renewInterval = "daily";
email = "danny@net.dn";
dnsProvider = "pdns";
dnsPropagationCheck = false;
environmentFile = secrets."acme/pdns".path;
};
certs."dnywe.com" = {
domain = "*.dnywe.com";
extraDomainNames = [
"*.stalwart.dnywe.com"
];
server = "https://acme-v02.api.letsencrypt.org/directory";
dnsProvider = "cloudflare";
dnsResolver = "1.1.1.1:53";
email = "postmaster@dnywe.com";
dnsPropagationCheck = true;
environmentFile = pkgs.writeText "lego-config" ''
LEGO_CA_CERTIFICATES=${config.security.pki.caBundle}
'';
credentialFiles = {
"CLOUDFLARE_DNS_API_TOKEN_FILE" = secrets."acme/cloudflare".path;
};
};
};
}

View file

@ -1,7 +1,37 @@
{ config, ... }:
let
inherit (config.networking) domain;
inherit (config.sops) secrets;
hostname = "actual.${domain}";
oidcURL = "https://${config.services.keycloak.settings.hostname}/realms/master";
in
{
sops.secrets."actual/clientSecret" = {
owner = "actual";
group = "actual";
mode = "640";
};
imports = [
(import ../../../modules/actual {
fqdn = "actual.net.dn";
fqdn = hostname;
})
];
services.nginx.virtualHosts."${hostname}" = {
useACMEHost = domain;
};
services.actual.settings = {
loginMethod = "openid";
allowedLoginMethods = [ "openid" ];
openId = {
discoveryURL = "${oidcURL}/.well-known/openid-configuration";
client_id = "actual";
client_secret._secret = secrets."actual/clientSecret".path;
server_hostname = "https://${hostname}";
authMethod = "openid";
};
};
}

View file

@ -1,7 +1,16 @@
{ config, ... }:
let
inherit (config.networking) domain;
hostname = "bitwarden.${domain}";
in
{
imports = [
(import ../../../modules/vaultwarden.nix {
domain = "bitwarden.net.dn";
domain = hostname;
})
];
services.nginx.virtualHosts."${hostname}" = {
useACMEHost = domain;
};
}

View file

@ -12,10 +12,8 @@
./keycloak.nix
./netbird.nix
./hideTTY.nix
# (import ../../../modules/opencloud.nix {
# fqdn = "opencloud.net.dn";
# envFile = config.sops.secrets."opencloud".path;
# })
(import ./ntfy.nix { fqdn = "ntfy.net.dn"; })
./dns.nix
./acme.nix
./ntfy.nix
];
}

View file

@ -0,0 +1,164 @@
{ config, lib, ... }:
let
inherit (builtins) listToAttrs;
inherit (lib) nameValuePair mkForce;
inherit (config.sops) secrets;
inherit (config.networking) domain;
splitDNS = listToAttrs (
map (x: nameValuePair x "127.0.0.1:5359") [
"${domain}."
]
);
in
{
services.resolved.enable = mkForce false;
sops.secrets = {
"powerdns-admin/secret" = {
mode = "0660";
owner = "powerdnsadmin";
group = "powerdnsadmin";
};
"powerdns-admin/salt" = {
mode = "0660";
owner = "powerdnsadmin";
group = "powerdnsadmin";
};
powerdns = {
mode = "0660";
owner = "pdns";
group = "pdns";
};
};
services.postgresql = {
enable = true;
authentication = ''
host powerdnsadmin powerdnsadmin 127.0.0.1/32 trust
'';
ensureUsers = [
{
name = "powerdnsadmin";
ensureDBOwnership = true;
}
{
name = "pdns";
ensureDBOwnership = true;
}
];
ensureDatabases = [
"powerdnsadmin"
"pdns"
];
};
services.powerdns = {
enable = true;
extraConfig = ''
launch=gpgsql
loglevel=6
webserver-password=$WEB_PASSWORD
api=yes
api-key=$WEB_PASSWORD
gpgsql-host=/var/run/postgresql
gpgsql-dbname=pdns
gpgsql-user=pdns
gpgsql-dnssec=yes
webserver=yes
webserver-port=8081
local-port=5359
dnsupdate=yes
primary=yes
secondary=no
allow-dnsupdate-from=10.0.0.0/24
allow-axfr-ips=10.0.0.0/24
also-notify=10.0.0.148:53
'';
secretFile = secrets.powerdns.path;
};
services.pdns-recursor = {
enable = true;
forwardZones = {
"dn." = "127.0.0.1:5359";
}
// splitDNS;
forwardZonesRecurse = {
# ==== Rspamd DNS ==== #
"multi.uribl.com." = "168.95.1.1";
"score.senderscore.com." = "168.95.1.1";
"list.dnswl.org." = "168.95.1.1";
"dwl.dnswl.org." = "168.95.1.1";
# ==== Others ==== #
"tw." = "168.95.1.1";
"." = "1.1.1.1";
};
dnssecValidation = "off";
dns.allowFrom = [
"127.0.0.0/8"
"10.0.0.0/24"
"192.168.100.0/24"
];
dns.port = 5300;
yaml-settings = {
webservice.webserver = true;
recordcache.max_negative_ttl = 60;
};
};
services.dnsdist = {
enable = true;
extraConfig = ''
newServer("127.0.0.1:${toString config.services.pdns-recursor.dns.port}")
addDOHLocal("0.0.0.0:8053", nil, nil, "/", { reusePort = true })
getPool(""):setCache(newPacketCache(65535, {maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false}))
'';
};
services.powerdns-admin = {
enable = true;
secretKeyFile = config.sops.secrets."powerdns-admin/secret".path;
saltFile = config.sops.secrets."powerdns-admin/salt".path;
config =
# python
''
import cachelib
BIND_ADDRESS = "127.0.0.1"
PORT = 8081
SESSION_TYPE = 'cachelib'
SESSION_CACHELIB = cachelib.simple.SimpleCache()
SQLALCHEMY_DATABASE_URI = 'postgresql://powerdnsadmin@/powerdnsadmin?host=localhost'
'';
};
services.nginx.virtualHosts = {
"dns.${domain}" = {
useACMEHost = domain;
forceSSL = true;
locations."/dns-query" = {
extraConfig = ''
grpc_pass grpc://127.0.0.1:${toString 8053};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
'';
};
};
"powerdns.${domain}" = {
useACMEHost = domain;
forceSSL = true;
locations."/api".proxyPass = "http://127.0.0.1:8081";
locations."/".proxyPass = "http://127.0.0.1:8000";
};
};
systemd.services.pdns-recursor.before = [ "acme-setup.service" ];
systemd.services.pdns.before = [ "acme-setup.service" ];
}

View file

@ -1,8 +1,10 @@
{ lib, config, ... }:
let
inherit (config.networking) domain;
cfg = config.services.forgejo;
srv = cfg.settings.server;
domain = "git.dnywe.com";
hostname = "git.${domain}";
mailServer = "mx1.net.dn";
forgejoOwner = {
@ -39,7 +41,7 @@ in
settings = {
server = {
DOMAIN = domain;
DOMAIN = hostname;
ROOT_URL = "https://${srv.DOMAIN}";
HTTP_PORT = 32006;
SSH_PORT = lib.head config.services.openssh.ports;
@ -69,4 +71,10 @@ in
server.SECRET_KEY = config.sops.secrets."forgejo/server/secretKey".path;
};
};
services.nginx.virtualHosts.${hostname} = {
useACMEHost = domain;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:${toString srv.HTTP_PORT}";
};
}

View file

@ -2,7 +2,7 @@
{ lib, config, ... }:
let
inherit (lib) mkForce;
domain = "dnywe.com";
inherit (config.networking) domain;
cfg = config.services.keycloak;
in
{
@ -12,6 +12,9 @@ in
};
};
# Disable nginx reverse proxy
services.nginx.virtualHosts."${cfg.settings.hostname}" = mkForce { };
services.nginx.virtualHosts."${cfg.settings.hostname}" = {
useACMEHost = domain;
forceSSL = true;
enableACME = mkForce false;
};
}

View file

@ -46,7 +46,7 @@ in
'';
webmail = {
enable = true;
hostname = "mail.${domain}";
hostname = "mail.dnywe.com";
};
keycloak = {
dbSecretFile = config.sops.secrets."oauth/password".path;

View file

@ -8,7 +8,10 @@
let
inherit (helper.grafana) mkDashboard;
inherit (lib) optionalAttrs optional;
inherit (config.networking) hostName;
inherit (config.networking) hostName domain;
grafanaHostname = "grafana.${domain}";
prometheusHostname = "metrics.${domain}";
datasourceTemplate = [
{
@ -55,7 +58,7 @@ in
{
imports = [
(import ../../../modules/prometheus.nix {
fqdn = "metrics.net.dn";
fqdn = prometheusHostname;
selfMonitor = true;
configureNginx = true;
scrapes = [
@ -108,7 +111,7 @@ in
})
(import ../../../modules/grafana.nix {
domain = "grafana.net.dn";
domain = grafanaHostname;
passFile = config.sops.secrets."grafana/password".path;
smtpHost = "${config.mail-server.hostname}.${config.mail-server.domain}:465";
smtpDomain = config.mail-server.domain;
@ -194,4 +197,13 @@ in
};
enable = true;
};
services.nginx.virtualHosts = {
"${grafanaHostname}" = {
useACMEHost = domain;
};
"${prometheusHostname}" = {
useACMEHost = domain;
};
};
}

View file

@ -1,9 +1,32 @@
{ pkgs, ... }:
{
pkgs,
config,
lib,
inputs,
...
}:
let
modpack = pkgs.fetchPackwizModpack {
inherit (config.sops) secrets;
inherit (inputs.nix-minecraft.lib) collectFilesAt;
modpack-shaderRetired = pkgs.fetchPackwizModpack {
url = "https://git.dnywe.com/dachxy/shader-retired-modpack/raw/branch/main/pack.toml";
packHash = "sha256-NPMS8j5NXbtbsso8R4s4lhx5L7rQJdek62G2Im3JdmM=";
};
modpack-landscape = pkgs.fetchPackwizModpack {
url = "https://git.dnywe.com/dachxy/landscape-modpack/raw/branch/main/pack.toml";
packHash = "sha256-mQSE4PMrOupARpEIzdzg+gOD0VQGII4MrBUyr8VevKk=";
};
fabricProxy = pkgs.fetchurl rec {
pname = "FabricProxy-Lite";
version = "2.11.0";
url = "https://cdn.modrinth.com/data/8dI2tmqs/versions/nR8AIdvx/${pname}-${version}.jar";
hash = "sha256-68er6vbAOsYZxwHrszLeaWbG2D7fq/AkNHIMj8PQPNw=";
};
velocityCfg = config.services.velocity;
in
{
systemConf.security.allowedDomains = [
@ -13,29 +36,110 @@ in
"login.microsoftonline.com"
];
sops.secrets."velocity" = {
owner = velocityCfg.user;
};
sops.secrets."fabricProxy" = {
owner = "minecraft";
};
services.velocity = {
enable = true;
openFirewall = true;
host = "0.0.0.0";
port = 25565;
settings = {
motd = "<#09add3>POG, MC server!";
player-info-forwarding-mode = "modern";
forwarding-secret-file = "${secrets."velocity".path}";
servers = {
shader-retired = "127.0.0.1:30066";
landscape = "127.0.0.1:30067";
try = [
"shader-retired"
];
};
forced-hosts = {
"server.vnet.dn" = [
"shader-retired"
];
"retired.mc.dnywe.com" = [
"shader-retired"
];
"landscape.mc.dnywe.com" = [
"landscape"
];
};
};
};
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 = {
services.minecraft-servers.servers = {
shader-retired =
let
mcVersion = modpack-shaderRetired.manifest.versions.minecraft;
fabricVersion = modpack-shaderRetired.manifest.versions.fabric;
serverVersion = lib.replaceStrings [ "." ] [ "_" ] "fabric-${mcVersion}";
in
{
enable = true;
autoStart = true;
jvmOpts = "-Xms2144M -Xmx8240M";
package = pkgs.fabricServers.${serverVersion}.override { loaderVersion = fabricVersion; };
symlinks = collectFilesAt modpack-shaderRetired "mods" // {
"mods/FabricProxy-Lite.jar" = fabricProxy;
};
files = {
"config/FabricProxy-Lite.toml" = "${secrets."fabricProxy".path}";
};
serverProperties = {
server-port = 30066;
difficulty = 3;
gamemode = "survival";
max-player = 20;
motd = "Bro!!!!";
accepts-flight = true;
accepts-transfers = true;
hardcore = false;
};
};
server-port = 25565;
difficulty = 3;
gamemode = "survival";
max-player = 20;
modt = "Bro!!!!";
accepts-flight = true;
accepts-transfers = true;
hardcore = false;
};
landscape =
let
mcVersion = modpack-landscape.manifest.versions.minecraft;
fabricVersion = modpack-landscape.manifest.versions.fabric;
serverVersion = lib.replaceStrings [ "." ] [ "_" ] "fabric-${mcVersion}";
in
{
enable = true;
autoStart = true;
enableReload = true;
jvmOpts = "-Xms2144M -Xmx8240M";
package = pkgs.fabricServers.${serverVersion}.override { loaderVersion = fabricVersion; };
symlinks = collectFilesAt modpack-landscape "mods" // {
"mods/FabricProxy-Lite.jar" = fabricProxy;
};
files = {
"config/FabricProxy-Lite.toml" = "${secrets."fabricProxy".path}";
};
serverProperties = {
server-port = 30067;
difficulty = 3;
gamemode = "survival";
max-player = 20;
motd = "Landscape, daug!";
accepts-flight = true;
accepts-transfers = true;
hardcore = false;
};
};
};
}

View file

@ -1,7 +1,7 @@
{ config, lib, ... }:
let
inherit (lib) mkForce;
domain = "dnywe.com";
inherit (config.networking) domain;
# Virtual Domain
vDomain = "vnet.dn";
@ -19,9 +19,9 @@ in
};
systemConf.security.allowedDomains = [
"login.dnywe.com"
"pkgs.netbird.io"
config.services.keycloak.settings.hostname
"${srv.domain}"
"pkgs.netbird.io"
];
imports = [
@ -71,6 +71,8 @@ in
'';
services.nginx.virtualHosts."${srv.domain}" = {
useACMEHost = domain;
addSSL = true;
locations."/api" = {
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

View file

@ -7,10 +7,10 @@
let
inherit (lib) mkIf mkDefault mkAfter;
inherit (config.sops) secrets;
inherit (config.networking) domain;
spreedCfg = config.services.nextcloud-spreed-signaling;
nextcloudCfg = config.services.nextcloud;
turnDomain = "coturn.dnywe.com";
domain = "net.dn";
turnDomain = "coturn.${domain}";
in
{
sops.secrets = {
@ -79,7 +79,7 @@ in
mail_smtpname = "nextcloud";
mail_smtpmode = "smtp";
mail_smtpauthtype = "LOGIN";
mail_domain = "net.dn";
mail_domain = "${domain}";
mail_smtpport = 465;
mail_smtpsecure = "ssl";
mail_from_address = "nextcloud";
@ -123,8 +123,13 @@ in
};
};
services.nginx.virtualHosts.${nextcloudCfg.hostName} = {
useACMEHost = domain;
forceSSL = true;
};
services.nginx.virtualHosts.${spreedCfg.hostName} = {
enableACME = true;
useACMEHost = domain;
forceSSL = true;
};

View file

@ -1,22 +1,19 @@
{
fqdn ? null,
}:
{ config, ... }:
let
inherit (config.networking) domain;
port = 31004;
finalFqdn = if fqdn == null then config.networking.fqdn else fqdn;
hostname = "ntfy.${domain}";
in
{
systemConf.security.allowedDomains = [
"ntfy.sh"
"web.push.apple.com"
];
services.ntfy-sh = {
enable = true;
settings = {
listen-http = ":${toString port}";
base-url = "https://${finalFqdn}";
base-url = "https://${hostname}";
upstream-base-url = "https://ntfy.sh";
behind-proxy = true;
proxy-trusted-hosts = "127.0.0.1";
@ -30,8 +27,8 @@ in
};
services.nginx.virtualHosts = {
"${finalFqdn}" = {
enableACME = true;
"${hostname}" = {
useACMEHost = domain;
forceSSL = true;
locations."/" = {
proxyWebsockets = true;

View file

@ -1,9 +1,18 @@
{ config, ... }:
{ config, lib, ... }:
let
inherit (config.networking) domain;
hostname = "paperless.${domain}";
in
{
imports = [
(import ../../../modules/paperless-ngx.nix {
domain = "paperless.net.dn";
domain = hostname;
passwordFile = config.sops.secrets."paperless/adminPassword".path;
})
];
services.nginx.virtualHosts."${hostname}" = {
useACMEHost = domain;
};
}