Compare commits

...

6 commits

25 changed files with 350 additions and 319 deletions

View file

@ -1,5 +1,11 @@
# Nix based CCCB infra # Nix based CCCB infra
## Folder structure
- `./services` holds generic service configuration that is shared between hosts
- `./hosts` holds host specific configuration
- `./secrets` holds age encrypted secrets using [agenix](https://github.com/ryantm/agenix)
## Admin handbook ## Admin handbook
### Update a container ### Update a container
@ -7,7 +13,7 @@
```shell ```shell
ssh <container> ssh <container>
cd /etc/nixos cd /etc/nixos
nix run .#apps.nixos-diff # Show what changes would be applied nix run .#apps.nixos-diff # git pull + build + diff wth running config
nixos-rebuild switch # Apply changes nixos-rebuild switch # Apply changes
``` ```
@ -15,12 +21,13 @@ nixos-rebuild switch # Apply changes
Production: Production:
- [Matrix](./README.matrix.md) - [Matrix (matrix.berlin.ccc.de)](./README.matrix.md)
Testing: Testing:
- [Hedgedoc](./README.hedgedoc.md) - [Hedgedoc (md.berlin.ccc.de)](./README.hedgedoc.md)
- [Postgres](./README.postgres.md) - [Postgres (sql.berlin.ccc.de)](./README.postgres.md)
- [Grafana/Prometheus (monitoring.berlin.ccc.de)](./README.monitoring.md)
--- ---

10
README.monitoring.md Normal file
View file

@ -0,0 +1,10 @@
# Monitoring
## Grafana
## Prometheus
---
Build with ❤️ and ❄️.

View file

@ -100,6 +100,16 @@
modules = [ modules = [
agenix.nixosModules.default agenix.nixosModules.default
{ environment.systemPackages = [ (agenix.packages.${system}.default) ]; } { environment.systemPackages = [ (agenix.packages.${system}.default) ]; }
{
age.secrets = {
hedgedoc-env = {
file = ./secrets/hedgedoc-env.age;
mode = "440";
owner = "hedgedoc";
group = "hedgedoc";
};
};
}
./hosts/md ./hosts/md
]; ];
}; };
@ -124,11 +134,53 @@
group = "postgres"; group = "postgres";
mode = "0400"; mode = "0400";
}; };
postgres-grafana = {
file = ./secrets/postgres-grafana.age;
owner = "postgres";
group = "postgres";
mode = "0400";
};
}; };
} }
./hosts/sql ./hosts/sql
]; ];
}; };
nixosConfigurations."monitoring" = nixpkgs.lib.nixosSystem {
#system = "x86_64-linux";
#pkgs = import nixpkgs { inherit system; };
inherit system;
modules = [
agenix.nixosModules.default
{ environment.systemPackages = [ (agenix.packages.${system}.default) ]; }
{
age.secrets = {
postgres-grafana = {
file = ./secrets/postgres-grafana.age;
owner = "postgres";
group = "postgres";
mode = "0400";
};
};
}
./hosts/monitoring
];
};
nixosConfigurations."www" = nixpkgs.lib.nixosSystem {
#system = "x86_64-linux";
#pkgs = import nixpkgs { inherit system; };
inherit system;
modules = [
./hosts/www
];
};
nixosConfigurations."git-run" = nixpkgs.lib.nixosSystem {
#system = "x86_64-linux";
#pkgs = import nixpkgs { inherit system; };
inherit system;
modules = [
./hosts/git-run
];
};
}; };
#); #);
} }

View file

@ -8,6 +8,7 @@
{ {
imports = [ imports = [
(modulesPath + "/virtualisation/proxmox-lxc.nix") (modulesPath + "/virtualisation/proxmox-lxc.nix")
../services/node-exporter.nix
]; ];
systemd.suppressedSystemUnits = [ systemd.suppressedSystemUnits = [

View file

@ -5,11 +5,9 @@
../common.nix ../common.nix
../../services/openssh.nix ../../services/openssh.nix
../../services/nginx.nix ../../services/nginx.nix
../../services/postgres.nix ./nginx.nix
../../services/synapse.nix ./synapse.nix
../../services/draupnir.nix ./draupnir.nix
../../services/prometheus.nix
../../services/grafana.nix
]; ];
networking = { networking = {

24
hosts/matrix/nginx.nix Normal file
View file

@ -0,0 +1,24 @@
{ config, pkgs, ... }:
{
services.nginx.virtualHosts."matrix.berlin.ccc.de" = {
default = true;
quic = true;
kTLS = true;
forceSSL = true;
enableACME = true;
locations = {
#"/.well-known/acme-challenge".root = config.security.acme.defaults.webroot;
"/".return = "418 \"🫖\"";
"~ ^(/_matrix|/_synapse/client)" = {
recommendedProxySettings = true;
proxyPass = "http://[::1]:8008";
extraConfig = ''
client_max_body_size 64M;
proxy_set_header X-Request-ID $request_id;
proxy_http_version 1.1;
'';
};
};
};
}

View file

@ -1,16 +1,18 @@
{ config, ... }: { config, ... }:
let
domain = "berlin.ccc.de";
in
{ {
networking.firewall.extraInputRules = ''
ip saddr 195.160.173.14 tcp dport 9009 accept
ip6 saddr 2001:678:760:cccb::14 tcp dport 9009 accept
'';
services = { services = {
matrix-synapse = { matrix-synapse = {
enable = true; enable = true;
settings = { settings = {
server_name = domain; server_name = config.networking.domain;
public_baseurl = "https://matrix.${domain}:443/"; public_baseurl = "https://${config.networking.hostName}.${config.networking.domain}:443/";
# "/var/lib/matrix-synapse/homeserver.signing.key" # Creates "/var/lib/matrix-synapse/homeserver.signing.key" on first launch
signing_key_path = config.age.secrets.matrix_signing_key.path; signing_key_path = config.age.secrets.matrix_signing_key.path;
registration_shared_secret_path = config.age.secrets.matrix_registration_shared_secret.path; registration_shared_secret_path = config.age.secrets.matrix_registration_shared_secret.path;
database = { database = {
@ -42,7 +44,7 @@ in
type = "metrics"; type = "metrics";
tls = false; tls = false;
port = 9009; port = 9009;
bind_addresses = [ "::1" ]; bind_addresses = ["::" "0.0.0.0"];
resources = [ resources = [
{ {
compress = false; compress = false;
@ -68,17 +70,5 @@ in
}; };
enableRegistrationScript = true; enableRegistrationScript = true;
}; };
postgresql = {
ensureUsers = [
{
name = config.services.matrix-synapse.settings.database.args.user;
ensureDBOwnership = true;
}
];
ensureDatabases = [
config.services.matrix-synapse.settings.database.args.database
];
};
}; };
} }

View file

@ -4,7 +4,7 @@
imports = [ imports = [
../common.nix ../common.nix
../../services/openssh.nix ../../services/openssh.nix
../../services/hedgedoc.nix ./hedgedoc.nix
]; ];
networking = { networking = {

24
hosts/md/hedgedoc.nix Normal file
View file

@ -0,0 +1,24 @@
{ config, pkgs, ... }:
let
db = {
host = "sql.berlin.ccc.de";
port = 5432;
username = "hedgedoc";
database = "hedgedoc";
};
in
{
services.hedgedoc = {
enable = true;
settings = {
domain = "${config.networking.hostName}.${config.networking.domain}";
dbURL = "postgres://${db.username}:\${DB_PASSWORD}@${db.host}:${toString db.port}/${db.name}";
# sync with config.age.secrets.postgres-hedgedoc.path
environmentFile = config.age.secrets.hedgedoc-env.path;
protocolUseSSL = true;
enableStatsApi = true;
};
};
}

44
hosts/md/nginx.nix Normal file
View file

@ -0,0 +1,44 @@
{ config, pkgs, ... }:
let
cfg = config.services.hedgedoc.settings;
in
{
services.nginx.virtualHosts."${config.networking.hostName}.${config.networking.domain}" = {
default = true;
quic = true;
kTLS = true;
forceSSL = true;
enableACME = true;
locations = {
"/" = {
recommendedProxySettings = true;
proxyPass = "http://${cfg.host}:${toString cfg.port}";
};
"/socket.io/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
proxyPass = "http://${cfg.host}:${toString cfg.port}";
};
"/metrics" = {
recommendedProxySettings = true;
proxyPass = "http://${cfg.host}:${toString cfg.port}";
extraConfig = ''
allow 195.160.173.14;
allow 2001:678:760:cccb::14;
deny all;
'';
};
"/status" = {
recommendedProxySettings = true;
proxyPass = "http://${cfg.host}:${toString cfg.port}";
extraConfig = ''
allow 195.160.173.14;
allow 2001:678:760:cccb::14;
deny all;
'';
};
};
};
}

View file

@ -0,0 +1,41 @@
{ ... }:
{
imports = [
../common.nix
../../services/openssh.nix
../../services/nginx.nix
./nginx.nix
./prometheus.nix
./grafana.nix
];
networking = {
hostName = "monitoring";
firewall = {
allowedTCPPorts = [
80 # HTTP/1
443 # HTTP/2
];
allowedUDPPorts = [
443 # HTTP/3
];
};
};
services = {
openssh.banner = ''
__
__/\ \__ __
___ ___ ___ ___ /\_\ \ ,_\ ___ _ __ /\_\ ___ __
/' __` __`\ / __`\ /' _ `\/\ \ \ \/ / __`\/\`'__\/\ \ /' _ `\ /'_ `\
/\ \/\ \/\ \/\ \L\ \/\ \/\ \ \ \ \ \_/\ \L\ \ \ \/ \ \ \/\ \/\ \/\ \L\ \
\ \_\ \_\ \_\ \____/\ \_\ \_\ \_\ \__\ \____/\ \_\ \ \_\ \_\ \_\ \____ \
\/_/\/_/\/_/\/___/ \/_/\/_/\/_/\/__/\/___/ \/_/ \/_/\/_/\/_/\/___L\ \
/\____/
\_/__/
'';
};
system.stateVersion = "25.11";
}

View file

@ -11,9 +11,10 @@
server.http_addr = "::1"; server.http_addr = "::1";
database = { database = {
type = "postgres"; type = "postgres";
host = "sql.berlin.ccc.de";
name = "grafana"; name = "grafana";
user = "grafana"; user = "grafana";
host = "/run/postgresql"; password = "$__file{${config.age.secrets.postgres_grafana.path}}";
}; };
security = { security = {
secret_key = "$__file{${config.age.secrets.grafana_secret_key.path}}"; secret_key = "$__file{${config.age.secrets.grafana_secret_key.path}}";
@ -42,17 +43,5 @@
]; ];
}; };
}; };
postgresql = {
ensureUsers = [
{
name = config.services.grafana.settings.database.user;
ensureDBOwnership = true;
}
];
ensureDatabases = [
config.services.grafana.settings.database.name
];
};
}; };
} }

View file

@ -0,0 +1,29 @@
{ config, pkgs, ... }:
{
services.nginx = {
upstreams.grafana.servers."localhost:3000" = {};
virtualHosts."${config.networking.hostName}.${config.networking.domain}" = {
default = true;
quic = true;
kTLS = true;
forceSSL = true;
enableACME = true;
#auth_basic "Administrators Area";
#auth_basic_user_file ${config.age.secrets.grafana-basic-auth.path};
locations = {
#"/.well-known/acme-challenge".root = config.security.acme.defaults.webroot;
"/" = {
recommendedProxySettings = true;
proxyPass = "http://grafana";
};
"/api/live/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
proxyPass = "http://grafana";
};
};
};
};
}

View file

@ -5,43 +5,42 @@
enable = true; enable = true;
retentionTime = "14d"; retentionTime = "14d";
listenAddress = "[::1]"; listenAddress = "[::1]";
exporters = {
node = {
enable = true;
listenAddress = config.services.prometheus.listenAddress;
};
nginx = {
enable = true;
listenAddress = config.services.prometheus.listenAddress;
};
#postgres = {};
};
scrapeConfigs = [ scrapeConfigs = [
{
job_name = "hedgedoc";
scrape_interval = "15s";
scheme = "https";
static_configs = [{ targets = ["md.berlin.ccc.de:443"]; }];
}
{ {
job_name = "synapse"; job_name = "synapse";
scrape_interval = "15s"; scrape_interval = "15s";
static_configs = [ static_configs = [{ targets = ["matrix.berlin.ccc.de:9009"]; }];
{
targets = lib.pipe config.services.matrix-synapse.settings.listeners [
(lib.filter (l: l.type == "metrics"))
builtins.head
(l: [ "[${builtins.head l.bind_addresses}]:${toString l.port}" ])
];
}
];
} }
{ {
job_name = "node"; job_name = "node";
scrape_interval = "15s"; scrape_interval = "15s";
static_configs = [ static_configs = [
{ targets = [ "${config.services.prometheus.exporters.node.listenAddress}:${toString config.services.prometheus.exporters.node.port}" ]; } {
targets = [
"matrix.${config.networking.domain}:${toString config.services.prometheus.exporters.node.port}"
"md.${config.networking.domain}:${toString config.services.prometheus.exporters.node.port}"
"postgres.${config.networking.domain}:${toString config.services.prometheus.exporters.node.port}"
"monitoring:${toString config.services.prometheus.exporters.node.port}"
];
}
]; ];
} }
{ {
job_name = "nginx"; job_name = "nginx";
scrape_interval = "15s"; scrape_interval = "15s";
static_configs = [ static_configs = [
{ targets = [ "${config.services.prometheus.exporters.nginx.listenAddress}:${toString config.services.prometheus.exporters.nginx.port}" ]; } {
targets = [
"monitoring:${toString config.services.prometheus.exporters.nginx.port}"
"matrix:${toString config.services.prometheus.exporters.nginx.port}"
];
}
]; ];
} }
]; ];

View file

@ -1,35 +0,0 @@
{ ... }:
{
imports = [
../common.nix
../../services/openssh.nix
../../services/powerdns.nix
];
networking = {
hostName = "powerdns";
firewall = {
allowedTCPPorts = [
53 # DNS
];
allowedUDPPorts = [
53 # DNS
];
};
};
services = {
openssh.banner = ''
__ __
/\ \__ /\ \
___ ____ ___ ____\ \ ,_\ ___ ___ ___\ \ \____
/' _ `\ /',__\ / __`\ /',__\\ \ \/ /'___\ /'___\ /'___\ \ '__`\
/\ \/\ \/\__, `\__/\ \L\ \/\__, `\\ \ \_ __/\ \__//\ \__//\ \__/\ \ \L\ \
\ \_\ \_\/\____/\_\ \____/\/\____/ \ \__\/\_\ \____\ \____\ \____\\ \_,__/
\/_/\/_/\/___/\/_/\/___/ \/___/ \/__/\/_/\/____/\/____/\/____/ \/___/
'';
};
system.stateVersion = "25.11";
}

View file

@ -7,6 +7,7 @@ let
entries = [ entries = [
(mkEntry "matrix-synapse" 25) # matrix.berlin.ccc.de (mkEntry "matrix-synapse" 25) # matrix.berlin.ccc.de
(mkEntry "hedgedoc" 26) # md.berlin.ccc.de (mkEntry "hedgedoc" 26) # md.berlin.ccc.de
(mkEntry "grafana" 255) # mon.berlin.ccc.de
]; ];
mkEntry = name: octet: { mkEntry = name: octet: {
user = { user = {
@ -47,6 +48,14 @@ in
# }; # };
#}; #};
postgresql = { postgresql = {
enable = true;
package = pkgs.postgresql_18;
enableJIT = true;
initdbArgs = [
"--locale=C"
"--encoding=UTF8"
];
settings.listen_addresses = "*";
enableTCPIP = true; enableTCPIP = true;
#settings = { #settings = {
# ssl = "on"; # ssl = "on";
@ -58,6 +67,16 @@ in
ensureDatabases = map (e: e.database) entries; ensureDatabases = map (e: e.database) entries;
authentication = "${builtins.concatStringsSep "\n" (map (e: e.auth) entries)}"; authentication = "${builtins.concatStringsSep "\n" (map (e: e.auth) entries)}";
}; };
postgresqlBackup = {
enable = true;
startAt = "@daily";
compression = "zstd";
};
prometheus.exporters.postgres = {
enable = true;
openFirewall = true;
firewallRules = services.prometheus.exporters.node.firewallRules;
}:
}; };
systemd.services.postgresql.postStart = '' systemd.services.postgresql.postStart = ''
${config.services.postgresql.package}/bin/psql \ ${config.services.postgresql.package}/bin/psql \

19
secrets/hedgedoc-env.age Normal file
View file

@ -0,0 +1,19 @@
age-encryption.org/v1
-> ssh-ed25519 uH+n1w Hl5GuG/K5bKRhYLwG3z1pUfRPPs/O0T9ELWTAMT/DG8
9nX8jNHmCQXa5Wv7huCTEk5kz3Me9QVSxJYPdrH5udw
-> ssh-ed25519 EvLbWw T+0rljpwVOktHR21v5JvBPe1nog0TVN1erGtIyRMbQ4
tpNz5eRC8vFFbdtXA6Vp+7X1VDq5doJi4hM1K/FOyVE
-> ssh-ed25519 dM+fLQ R9t+cS4ye0jOaubNcMaqu8/APLkzAopkZh76tM0jQgM
DL4DykdFXXQONPqDGv5LKTrlg9+4BPHdXNPMGwPF7a4
-> ssh-ed25519 jxWM2Q PTEewNsybqn/4gejSGy5BNucQ5izKtqUGp6mGroYizg
HEaBhzmp+0ymUUbzCgb4KpyZJ2lKYKNlaI9zMY58CJg
-> ssh-ed25519 /yCUCg 6wdCIPRGgPnPxzCdUDnDOl5lI2Fsl9DoA4QmM3DWfEs
ZdQ1sHtAsYrlaWNDZmf2+Gu9vIIp7adD6MI1oJyPPdU
-> ssh-ed25519 FGp51g 1Lvo3hKE72UUKJaN4U1XlXoP8j7EAHN0UPIP11FurCI
csB1x/PYsQgQ0gPHJAD8EcHHVo1JJ8NCtx45KpreqaE
-> ssh-ed25519 fEJY/A LlmksK8HR5YNpMwcqJUN5sgAM8jXCuanTNU+A53UMhY
kntfp+IUE1OLq03WLyuynyqSeUlrhy5piYKcqg9/DAg
--- NxH5yKP69Pq4DQx2Ziad7ECw6BdlbSfo7+vm9V3YWm8
•–
ЧµiŽmßÈñ¬ð²åè<>®v0Šêà_d§’$Z#[.vÿÒØ£Xæä×<10>•jý±³ZH's€Òy4Q§ƒ·<C692>³²<>
—ZÂö]^ÂŒ¥ nEÊ>w ¥f7ˆ<37><CB86>%~¿äD¼Þ

Binary file not shown.

View file

@ -17,17 +17,22 @@ let
_matrix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIApAkkhHLj918co/wUGuyW8WCPYHxsNM4uo32XDEu7VV root@matrix"; _matrix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIApAkkhHLj918co/wUGuyW8WCPYHxsNM4uo32XDEu7VV root@matrix";
_md = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdFkdEEDXo8+k5YZpI1O2GqZlxcpCDtxqVun35duITm root@md"; _md = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdFkdEEDXo8+k5YZpI1O2GqZlxcpCDtxqVun35duITm root@md";
_sql = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPcSXjDSyVVVdJbpheOhT0fIuOGFk+jsHhjrAVnBNLQV root@sql"; _sql = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPcSXjDSyVVVdJbpheOhT0fIuOGFk+jsHhjrAVnBNLQV root@sql";
_mon = "";
in in
{ {
"pushover_app_token.age".publicKeys = users ++ [ _matrix ];
"pushover_user_key.age".publicKeys = users ++ [ _matrix ];
"matrix_admin_password.age".publicKeys = users; "matrix_admin_password.age".publicKeys = users;
"draupnir_access_token.age".publicKeys = users ++ [ _matrix ]; "draupnir_access_token.age".publicKeys = users ++ [ _matrix ];
"matrix_signing_key.age".publicKeys = users ++ [ _matrix ]; "matrix_signing_key.age".publicKeys = users ++ [ _matrix ];
"matrix_registration_shared_secret.age".publicKeys = users ++ [ _matrix ]; "matrix_registration_shared_secret.age".publicKeys = users ++ [ _matrix ];
"pushover_app_token.age".publicKeys = users ++ [ _matrix ];
"pushover_user_key.age".publicKeys = users ++ [ _matrix ];
"grafana_admin_password.age".publicKeys = users ++ [ _matrix ]; "grafana_admin_password.age".publicKeys = users ++ [ _matrix ];
"grafana_secret_key.age".publicKeys = users ++ [ _matrix ]; "grafana_secret_key.age".publicKeys = users ++ [ _matrix ];
"hedgedoc-env.age".publicKeys = users ++ [ _md ];
"postgres-matrix-synapse.age".publicKeys = users ++ [ _sql _matrix ]; "postgres-matrix-synapse.age".publicKeys = users ++ [ _sql _matrix ];
"postgres-hedgedoc.age".publicKeys = users ++ [ _sql _md ]; "postgres-hedgedoc.age".publicKeys = users ++ [ _sql _md ];
"postgres-grafana.age".publicKeys = users ++ [ _sql _mon ];
} }

View file

@ -1,89 +0,0 @@
{ config, pkgs, ... }:
let
fqdn = "hedgedoc.berlin.ccc.de";
cfg = config.services.hedgedoc.settings;
in
{
services = {
hedgedoc = {
enable = true;
settings = {
domain = fqdn;
#environmentFile = config.age.secrets.hedgedoc_settings.path;
protocolUseSSL = true;
db = {
dialect = "postgresql";
host = "/run/postgresql";
username = "hedgedoc";
database = "hedgedoc";
};
enableStatsApi = true;
};
};
nginx = {
enable = true;
resolver.addresses = [
"[2606:4700:4700::1111]"
"[2620:fe::fe]"
"1.1.1.1"
"9.9.9.9"
];
statusPage = true; # http://127.0.0.1/nginx_status
sslProtocols = "TLSv1.3";
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedBrotliSettings = true;
virtualHosts."${fqdn}" = {
default = true;
quic = true;
kTLS = true;
forceSSL = true;
enableACME = true;
locations = {
"/" = {
proxyPass = "http://${cfg.host}:${toString cfg.port}";
recommendedProxySettings = true;
};
"/socket.io/" = {
proxyPass = "http://${cfg.host}:${toString cfg.port}";
proxyWebsockets = true;
recommendedProxySettings = true;
};
"/metrics" = {
proxyPass = "http://${cfg.host}:${toString cfg.port}";
recommendedProxySettings = true;
#allow 195.160.173.255;
#allow 2001:678:760:cccb::ffff;
#deny all;
};
"/status" = {
proxyPass = "http://${cfg.host}:${toString cfg.port}";
recommendedProxySettings = true;
#allow 195.160.173.255;
#allow 2001:678:760:cccb::ffff;
#deny all;
};
};
};
};
postgresql = {
enable = true;
package = pkgs.postgresql_18;
enableJIT = true;
initdbArgs = [
"--locale=C"
"--encoding=UTF8"
];
ensureUsers = [{ name = cfg.db.username; ensureDBOwnership = true; }];
ensureDatabases = [ cfg.db.database ];
};
postgresqlBackup = {
enable = true;
startAt = "*-*-* 09:00:00";
compression = "zstd";
};
};
}

View file

@ -1,12 +1,10 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
let
fqdn = "matrix.berlin.ccc.de";
in
{ {
users.users.nginx.extraGroups = [ "acme" ]; users.users.nginx.extraGroups = [ "acme" ];
services.nginx = { services = {
nginx = {
enable = true; enable = true;
resolver.addresses = [ resolver.addresses = [
"[2606:4700:4700::1111]" "[2606:4700:4700::1111]"
@ -20,25 +18,11 @@ in
recommendedOptimisation = true; recommendedOptimisation = true;
recommendedGzipSettings = true; recommendedGzipSettings = true;
recommendedBrotliSettings = true; recommendedBrotliSettings = true;
virtualHosts."${fqdn}" = {
default = true;
quic = true;
kTLS = true;
forceSSL = true;
enableACME = true;
locations = {
#"/.well-known/acme-challenge".root = config.security.acme.defaults.webroot;
"/".return = "418 \"🫖\"";
"~ ^(/_matrix|/_synapse/client)" = {
recommendedProxySettings = true;
proxyPass = "http://[::1]:8008";
extraConfig = ''
client_max_body_size 64M;
proxy_set_header X-Request-ID $request_id;
proxy_http_version 1.1;
'';
};
}; };
prometheus.exporters.nginx = {
enable = true;
firewallRules = config.services.prometheus.exporters.node.firewallRules;
openFirewall = true;
}; };
}; };
} }

View file

@ -0,0 +1,13 @@
{ ... }:
{
services.prometheus.exporters.node = {
enable = true;
openFirewall = true;
firewallRules = ''
ip saddr 195.160.173.14 tcp dport 9187 counter accept
ip6 saddr 2001:678:760:cccb::14 tcp dport 9187 counter accept
'';
};
}

View file

@ -1,21 +0,0 @@
{ pkgs, ... }:
{
services = {
postgresql = {
enable = true;
package = pkgs.postgresql_18;
enableJIT = true;
initdbArgs = [
"--locale=C"
"--encoding=UTF8"
];
settings.listen_addresses = "*";
};
postgresqlBackup = {
enable = true;
startAt = "@daily";
compression = "zstd";
};
};
}

View file

@ -1,72 +0,0 @@
{ config, ... }:
{
# exposes prometheus metrics at http://127.0.0.1:8081/metrics
services = {
powerdns = {
enable = true;
secretFile = config.age.secrets.powerdns.path;
# API_KEY=supersecret123!
# WEBSERVER_PASSWORD=supersecre123!
extraConfig = ''
api=yes
api-key=$API_KEY
local-address=0.0.0.0, ::
local-port=53
log-timestamp=no # journald already does this
resolver=127.0.0.54:5300 # Used for ALIAS lookup
secondary=yes
version-string=anonymous
webserver-password=$WEBSERVER_PASSWORD
webserver-port=8081
launch=bind
'';
};
powerdns-admin = {
enable = true;
secretKeyFile = config.age.secrets.powerdns-admin-cookie-secret.path;
saltFile = config.age.secrets.powerdns-admin-salt.path;
extraArgs = [];
config = ''
# PDA
SIGNUP_ENABLED = True
LOCAL_DB_ENABLED = True
# Flask
BIND_ADDRESS = '127.0.0.1'
PORT = 8000
#SESSION_COOKIE_SECURE = True
# Flask-Session
import cachelib
SESSION_TYPE = 'cachelib'
SESSION_CACHELIB = cachelib.simple.SimpleCache()
# Flask-SQLAlchemy
SQLALCHEMY_DATABASE_URI = 'postgresql://powerdnsadmin@/powerdnsadmin?host=/run/postgresql'
SQLALCHEMY_TRACK_MODIFICATIONS = True
# FLask-SeaSurf
#CSRF_COOKIE_SECURE = True
'';
};
postgresql = {
enable = true;
package = pkgs.postgresql_18;
ensureUsers = [
{
name = "pda";
ensureDBOwnership = true;
}
];
ensureDatabases = [ "pda" ];
};
postgresqlBackup = {
enable = true;
compression = "zstd";
startAt = "@midnight";
};
};
}