Compare commits
6 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c10e99502 | ||
|
|
26d56a1dfe | ||
|
|
e3a9a391c2 | ||
|
|
2fa576a302 | ||
|
|
43cfebcec6 | ||
|
|
e6442b2442 |
17 changed files with 687 additions and 868 deletions
59
.sops.yaml
59
.sops.yaml
|
|
@ -1,38 +1,29 @@
|
||||||
# SOPS configuration for StuRa HTW Dresden infrastructure
|
|
||||||
#
|
|
||||||
# This file defines which keys can decrypt which secrets.
|
|
||||||
# Add GPG public keys (.asc files) or age keys to keys/hosts/ and keys/users/
|
|
||||||
# to grant decryption access to hosts and users respectively.
|
|
||||||
|
|
||||||
keys:
|
keys:
|
||||||
# Admin/user keys - add GPG public keys here
|
- &goeranh age1qp7w80k3qtj79xsl0gwsfrkm037xrlnhm6th7tcyrvufh3szzp6s2pe7ra
|
||||||
# Example:
|
- &mail age156ak7kc79tuwpv0hk9atl5dg27jqs6ddfqxvr9m4twqgsr23lgvsdmyfpr
|
||||||
# - &user_admin_key age1... or pgp fingerprint
|
- &auth age1njnkkr489hfmpn337zna2k3z66y9086t7cpcmz2vn68p4x43aujs6wh0g5
|
||||||
|
- &v6proxy age1gl8zmw86jkrkr7kaqugdyhvdhdrnfd72smndz2kfh4a6ec6s9yxsyrecu6
|
||||||
|
- &proxy age1g9fnxzalnqtse29xjdrvcsrnrknp8t2s7xrle73fce0jcg7r3czsj524p4
|
||||||
|
|
||||||
# Host keys - add host-specific keys here
|
|
||||||
# Example:
|
|
||||||
# - &host_proxy_key age1... or pgp fingerprint
|
|
||||||
# - &host_git_key age1... or pgp fingerprint
|
|
||||||
|
|
||||||
# Define which keys can access which files
|
|
||||||
creation_rules:
|
creation_rules:
|
||||||
# Default rule: all secrets can be decrypted by admin keys
|
- path_regex: hosts/mail/secrets.sops.yml$
|
||||||
- path_regex: secrets/.*\.yaml$
|
key_groups:
|
||||||
# key_groups:
|
- age:
|
||||||
# - pgp:
|
- *mail
|
||||||
# - *user_admin_key
|
- *goeranh
|
||||||
# - age:
|
- path_regex: hosts/auth/secrets.sops.yml$
|
||||||
# - *user_admin_key
|
key_groups:
|
||||||
|
- age:
|
||||||
# Host-specific secrets (example)
|
- *auth
|
||||||
# - path_regex: secrets/proxy/.*\.yaml$
|
- *goeranh
|
||||||
# key_groups:
|
- path_regex: hosts/v6proxy/secrets.sops.yml$
|
||||||
# - pgp:
|
key_groups:
|
||||||
# - *user_admin_key
|
- age:
|
||||||
# - *host_proxy_key
|
- *v6proxy
|
||||||
|
- *goeranh
|
||||||
# - path_regex: secrets/git/.*\.yaml$
|
- path_regex: hosts/proxy/secrets.sops.yml$
|
||||||
# key_groups:
|
key_groups:
|
||||||
# - pgp:
|
- age:
|
||||||
# - *user_admin_key
|
- *proxy
|
||||||
# - *host_git_key
|
- *goeranh
|
||||||
|
|
|
||||||
58
flake.lock
generated
58
flake.lock
generated
|
|
@ -15,11 +15,11 @@
|
||||||
"uv2nix": "uv2nix"
|
"uv2nix": "uv2nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776085803,
|
"lastModified": 1772909021,
|
||||||
"narHash": "sha256-JvvWVbXJYSY8qOReMbAOD4lxcN2cjKV6lg/jLz8CEuY=",
|
"narHash": "sha256-hcstQ1Z9aQSJM3AVCLb0/OPTicbME9nhP01GiPrOjZM=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "authentik-nix",
|
"repo": "authentik-nix",
|
||||||
"rev": "4370b561c8bafb59773ce3a518506bcf1161dbdb",
|
"rev": "7e4730351fb6df479c46a1bf7e23d46a0b0c5d46",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -47,16 +47,16 @@
|
||||||
"authentik-src": {
|
"authentik-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775573258,
|
"lastModified": 1772567399,
|
||||||
"narHash": "sha256-Xq7JGI/8ppIydIuWd9KRJKUrh7UpeniwvZ4NAtXbYJ4=",
|
"narHash": "sha256-0Vpf1hj9C8r+rhrCgwoNazpQ+mwgjdjDhuoKCxYQFWw=",
|
||||||
"owner": "goauthentik",
|
"owner": "goauthentik",
|
||||||
"repo": "authentik",
|
"repo": "authentik",
|
||||||
"rev": "5249546862986202b901c2afd860992ec48c6ef6",
|
"rev": "0dccbd4193c45c581e9fb7cd89df0c1487510f1f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "goauthentik",
|
"owner": "goauthentik",
|
||||||
"ref": "version/2026.2.2",
|
"ref": "version/2026.2.1",
|
||||||
"repo": "authentik",
|
"repo": "authentik",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
@ -84,11 +84,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776613567,
|
"lastModified": 1773025010,
|
||||||
"narHash": "sha256-gC9Cp5ibBmGD5awCA9z7xy6MW6iJufhazTYJOiGlCUI=",
|
"narHash": "sha256-khlHllTsovXgT2GZ0WxT4+RvuMjNeR5OW0UYeEHPYQo=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "32f4236bfc141ae930b5ba2fb604f561fed5219d",
|
"rev": "7b9f7f88ab3b339f8142dc246445abb3c370d3d3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -116,11 +116,11 @@
|
||||||
"flake-compat_2": {
|
"flake-compat_2": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767039857,
|
"lastModified": 1761588595,
|
||||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -181,11 +181,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772893680,
|
"lastModified": 1763319842,
|
||||||
"narHash": "sha256-JDqZMgxUTCq85ObSaFw0HhE+lvdOre1lx9iI6vYyOEs=",
|
"narHash": "sha256-YG19IyrTdnVn0l3DvcUYm85u3PaqBt6tI6VvolcuHnA=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "git-hooks.nix",
|
"repo": "git-hooks.nix",
|
||||||
"rev": "8baab586afc9c9b57645a734c820e4ac0a604af9",
|
"rev": "7275fa67fbbb75891c16d9dee7d88e58aea2d761",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -224,11 +224,11 @@
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773912645,
|
"lastModified": 1773313890,
|
||||||
"narHash": "sha256-QHzRqq6gh+t3F/QU9DkP7X63dDDcuIQmaDz12p7ANTg=",
|
"narHash": "sha256-NXm/kOAk7HLziH1uWaUbNb9MhDS8yxFfQ8fMK5eN8/A=",
|
||||||
"ref": "nixos-25.11",
|
"ref": "nixos-25.11",
|
||||||
"rev": "25e6dbb8fca3b6e779c5a46fd03bd760b2165bb5",
|
"rev": "9cdd6869e513df8153db4b920c8f15d394e150f7",
|
||||||
"revCount": 843,
|
"revCount": 842,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver"
|
"url": "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver"
|
||||||
},
|
},
|
||||||
|
|
@ -297,11 +297,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773831496,
|
"lastModified": 1764020296,
|
||||||
"narHash": "sha256-JW2/QPyCVzmouqEp1H9kNa8JXd7xEhlam9sy3TYfhDY=",
|
"narHash": "sha256-6zddwDs2n+n01l+1TG6PlyokDdXzu/oBmEejcH5L5+A=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "826430a188181a750ffa5948daff334039c5d741",
|
"rev": "a320ce8e6e2cc6b4397eef214d202a50a4583829",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -313,11 +313,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
"nixpkgs_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776734388,
|
"lastModified": 1773222311,
|
||||||
"narHash": "sha256-vl3dkhlE5gzsItuHoEMVe+DlonsK+0836LIRDnm6MXQ=",
|
"narHash": "sha256-BHoB/XpbqoZkVYZCfXJXfkR+GXFqwb/4zbWnOr2cRcU=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "10e7ad5bbcb421fe07e3a4ad53a634b0cd57ffac",
|
"rev": "0590cd39f728e129122770c029970378a79d076a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -393,11 +393,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776771786,
|
"lastModified": 1773096132,
|
||||||
"narHash": "sha256-DRFGPfFV6hbrfO9a1PH1FkCi7qR5FgjSqsQGGvk1rdI=",
|
"narHash": "sha256-M3zEnq9OElB7zqc+mjgPlByPm1O5t2fbUrH3t/Hm5Ag=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "bef289e2248991f7afeb95965c82fbcd8ff72598",
|
"rev": "d1ff3b1034d5bab5d7d8086a7803c5a5968cd784",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -193,10 +193,10 @@
|
||||||
[
|
[
|
||||||
./hosts/${input}
|
./hosts/${input}
|
||||||
./default.nix
|
./default.nix
|
||||||
./modules/monitoring.nix
|
|
||||||
disko.nixosModules.disko
|
disko.nixosModules.disko
|
||||||
authentik.nixosModules.default
|
authentik.nixosModules.default
|
||||||
mailserver.nixosModules.mailserver
|
mailserver.nixosModules.mailserver
|
||||||
|
sops.nixosModules.default
|
||||||
{
|
{
|
||||||
_module.args = { inherit self modulesPath; };
|
_module.args = { inherit self modulesPath; };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
84
hosts/auth/authentik.nix
Normal file
84
hosts/auth/authentik.nix
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
users.groups.authentik = { };
|
||||||
|
users.users.authentik = {
|
||||||
|
isSystemUser = true;
|
||||||
|
extraGroups = [ "docker" ];
|
||||||
|
group = "authentik";
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
|
||||||
|
systemd.services = {
|
||||||
|
authentik-secrets-setup = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
users.groups.authentik-ldap = {};
|
||||||
|
users.users.authentik-ldap = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "authentik-ldap";
|
||||||
|
};
|
||||||
|
systemd.services.authentik-ldap.serviceConfig = {
|
||||||
|
DynamicUser = lib.mkForce false;
|
||||||
|
User = "authentik-ldap";
|
||||||
|
};
|
||||||
|
services.authentik-ldap = {
|
||||||
|
enable = true;
|
||||||
|
environmentFile = config.sops.secrets."auth/ldap-env-file".path;
|
||||||
|
# environmentFile = "/var/lib/authentik-ldap-env";
|
||||||
|
};
|
||||||
|
services.authentik = {
|
||||||
|
enable = true;
|
||||||
|
# environmentFile = "/var/lib/authentik_secret";
|
||||||
|
environmentFile = config.sops.secrets."auth/env-file".path;
|
||||||
|
settings = {
|
||||||
|
email = {
|
||||||
|
host = "mail.${config.networking.domain}";
|
||||||
|
port = 25;
|
||||||
|
username = "authentik@${config.networking.domain}";
|
||||||
|
use_tls = false;
|
||||||
|
use_ssl = false;
|
||||||
|
from = "authentik@${config.networking.domain}";
|
||||||
|
};
|
||||||
|
disable_startup_analytics = true;
|
||||||
|
avatars = "initials";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.authentik-secrets-generator = {
|
||||||
|
enable = true;
|
||||||
|
requiredBy = [
|
||||||
|
"authentik-secrets-setup.service"
|
||||||
|
"authentik-worker.service"
|
||||||
|
];
|
||||||
|
script = ''
|
||||||
|
echo "AUTHENTIK_SECRET_KEY=$(${pkgs.openssl}/bin/openssl rand -hex 32)" > /var/lib/authentik_secret
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
"auth.${config.networking.domain}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:9000";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
45
hosts/auth/default.nix
Normal file
45
hosts/auth/default.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
sops = {
|
||||||
|
defaultSopsFile = ./secrets.sops.yml;
|
||||||
|
secrets = {
|
||||||
|
"auth/env-file".owner = "authentik";
|
||||||
|
"auth/ldap-env-file".owner = "authentik";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
imports = [
|
||||||
|
"${modulesPath}/virtualisation/proxmox-lxc.nix"
|
||||||
|
./authentik.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
hostName = "auth";
|
||||||
|
domain = lib.mkForce "test.htw.stura-dresden.de";
|
||||||
|
useDHCP = false;
|
||||||
|
interfaces.eth0.ipv4.addresses = [
|
||||||
|
{
|
||||||
|
address = "141.56.51.96";
|
||||||
|
prefixLength = 24;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
defaultGateway = {
|
||||||
|
address = "141.56.51.254";
|
||||||
|
interface = "eth0";
|
||||||
|
};
|
||||||
|
|
||||||
|
firewall.allowedTCPPorts = [
|
||||||
|
80
|
||||||
|
443
|
||||||
|
3389
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "25.05";
|
||||||
|
}
|
||||||
27
hosts/auth/secrets.sops.yml
Normal file
27
hosts/auth/secrets.sops.yml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
auth:
|
||||||
|
env-file: ENC[AES256_GCM,data:WDJ3daYCxybublm8VWO8W5HHmYYWKOcw81f+fQ0Vz78EOvbYI+SgEwnuAd/0/eeGkTPEJPSCfbymArs+YRTdibgO5y/34jdN0DOVQetZLPXrDbcZ/Sg=,iv:bykKdvkgmxwgptkGHKH4rnFknPA0PTrW+mEqIzIYERk=,tag:8UKhLz/VoPiXckcIEBfrLg==,type:str]
|
||||||
|
ldap-env-file: ENC[AES256_GCM,data:CpgiiUin3hj8+aykcSU2rasaCFt/CAC5lK3Ek7zxzw6hYCkhwxIc9a4Xfy9SxSQtASJ5dOOrOaa8gA1ahf4Z1g/1981fhxlQPeJd9PlJFgdL4CP5P6ZrPBKZKgygnreUo6HC7Rfc9x2CRmnDhQvMVUmQL9akZRNYasX+9IlRyKmLSFmi35IuryFhVLwfjfECmq51/Xo2WYzjWrayfFuOpS0jHWicQxXvXq6QcLvqmbk5euXiHDkFXOXcwMRr6mAompDAKa9BKXqcRDbxOWqzJ1gflEJvOJi249PeYFo+poTK1CUtBCTejFo=,iv:P1xN6wq5oeba1LSEn6UiArOka37alV/PhI5kOmpfDG0=,tag:Xisd5elHQ8mhvE6YEbCuLg==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age1njnkkr489hfmpn337zna2k3z66y9086t7cpcmz2vn68p4x43aujs6wh0g5
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHRmV2dGt1UXZ3M2RKd24y
|
||||||
|
V0x4MzZyYUh0aDVwQ1NmOCtyOHR6Z1c0R1ZNCi80Nk9PZFVTcVFIQjlZVXJNeXBN
|
||||||
|
TC9td05ZeWVVTCtFSWhqazN6bFF3akkKLS0tIEV3YzdRUDA5Q2dBd2JWUWNqOTU4
|
||||||
|
SnZtdVd4Q3lCaStJTnV4U2cvZUZEMlkK85XYSh6VbDFPKPIhKBKtkErGtgsHjXxy
|
||||||
|
kq14EXwfZnnBlR76JMQgPvSLrDLdj+4tDIVcuE4JplCoSvbGKckGww==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1qp7w80k3qtj79xsl0gwsfrkm037xrlnhm6th7tcyrvufh3szzp6s2pe7ra
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkQm5nUHkzZExKOXNzNjk4
|
||||||
|
Y1JURVJwNXhFUGZJak8vbEtCNnE2dHFuNVVNClJHQ3E2RGJkbUtlMDNwcy9Ib01Q
|
||||||
|
dG9nRTVJejkySTdlb2IrbHF4Z3ZMTmcKLS0tIHUwNndGdW9EaWwyNmRUb2NQU2Vs
|
||||||
|
MC9VSmVqVlVHRlJ4NXozUkQ4ZDVEVlkKbfVoBNsral3n7rG7ujUgdQXF68EVB+4G
|
||||||
|
MKMuOiY05QGBViLYyKh1jioHv6nds1hCuc2vpLNB3J0KT3I2q/a0VQ==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2026-03-21T16:42:34Z"
|
||||||
|
mac: ENC[AES256_GCM,data:i9hTUqbrmc2mD8PAbCe2gWern4ArMIkTQWN7eaJcsjZ9m6LZjOQFpnrpgPg6fj3hazgnFn86veNvQGe/J50NLnwj2FCyF3jKG3xkc7rKa9fyD0Yz0XnpbNKtDb2YGxwyBmLsnnyl6sdpyvPipZYCfwM+bhB8OERIXVXKwbZOn1A=,iv:dKI/NsMcVBNBOw0kYEQqrgfdvLKDg4NM/yRBYDqXIxU=,tag:xkg0z7IUy2m4ivosB925vQ==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.12.1
|
||||||
233
hosts/mail/default.nix
Normal file
233
hosts/mail/default.nix
Normal file
|
|
@ -0,0 +1,233 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
generatedAliases = pkgs.writeText "generated-aliases" (
|
||||||
|
lib.concatStringsSep "\n" (
|
||||||
|
lib.mapCartesianProduct
|
||||||
|
({ aliases, domain }: "${aliases}@${domain} root@test.htw.stura-dresden.de")
|
||||||
|
{
|
||||||
|
aliases = [
|
||||||
|
"abuse"
|
||||||
|
"hostmaster"
|
||||||
|
"noreply"
|
||||||
|
"postmaster"
|
||||||
|
"webmaster"
|
||||||
|
];
|
||||||
|
domain = config.mailserver.domains;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sops = {
|
||||||
|
defaultSopsFile = ./secrets.sops.yml;
|
||||||
|
secrets = {
|
||||||
|
"ldap_passwd".owner = "dovecot2";
|
||||||
|
"wireguard-key".owner = "systemd-network";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
imports = [
|
||||||
|
"${modulesPath}/virtualisation/proxmox-lxc.nix"
|
||||||
|
];
|
||||||
|
|
||||||
|
security.pam.loginLimits = [
|
||||||
|
{
|
||||||
|
domain = "*";
|
||||||
|
type = "soft";
|
||||||
|
item = "nofile";
|
||||||
|
value = "8192";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
hostName = "mail";
|
||||||
|
domain = lib.mkForce "test.htw.stura-dresden.de";
|
||||||
|
useDHCP = false;
|
||||||
|
interfaces.ens18.ipv4.addresses = [
|
||||||
|
{
|
||||||
|
address = "141.56.51.95";
|
||||||
|
prefixLength = 24;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
defaultGateway = {
|
||||||
|
address = "141.56.51.254";
|
||||||
|
interface = "eth0";
|
||||||
|
};
|
||||||
|
wireguard = {
|
||||||
|
enable = true;
|
||||||
|
interfaces = {
|
||||||
|
sturauplink = {
|
||||||
|
privateKeyFile = config.sops.secrets."wireguard-key".path;
|
||||||
|
ips = [
|
||||||
|
"10.100.0.20/24"
|
||||||
|
"fd28:6691:1921:6299::20/64"
|
||||||
|
];
|
||||||
|
peers = [
|
||||||
|
# mail.test.htw.stura-dresden.de
|
||||||
|
{
|
||||||
|
endpoint = "hetzner.test.htw.stura-dresden.de:51820";
|
||||||
|
allowedIPs = [
|
||||||
|
"10.100.0.1/24"
|
||||||
|
];
|
||||||
|
publicKey = "Tg/SNniezzF4DUnvUl1/JxQwS18POrUR20UmkQDt+X0=";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"lists.${config.networking.domain}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
# locations."/" = {
|
||||||
|
# proxyPass = "http://127.0.0.1:18507";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.automx2 = {
|
||||||
|
enable = true;
|
||||||
|
domain = "${config.networking.domain}";
|
||||||
|
settings = {
|
||||||
|
automx2 = {
|
||||||
|
db_uri = "sqlite:////var/lib/automx2/db.sqlite";
|
||||||
|
proxy_count = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.mailman = {
|
||||||
|
enable = true;
|
||||||
|
hyperkitty = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
serve.enable = true;
|
||||||
|
webHosts = [
|
||||||
|
"lists.${config.networking.domain}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.mailman.siteOwner = "mailman@${config.networking.domain}";
|
||||||
|
mailserver = {
|
||||||
|
enable = true;
|
||||||
|
fqdn = "mail.${config.networking.domain}";
|
||||||
|
domains = [
|
||||||
|
"${config.networking.domain}"
|
||||||
|
"lists.${config.networking.domain}"
|
||||||
|
];
|
||||||
|
ldap = {
|
||||||
|
enable = true;
|
||||||
|
bind = {
|
||||||
|
# dn = "cn=dovecot,ou=users,DC=test,DC=htw,DC=stura-dresden,DC=de";
|
||||||
|
dn = "cn=dovecot,ou=users,dc=mail,dc=htw,dc=stura-dresden,dc=de";
|
||||||
|
# passwordFile = "/var/lib/dovecot_ldap_passwd";
|
||||||
|
passwordFile = config.sops.secrets.ldap_passwd.path;
|
||||||
|
};
|
||||||
|
dovecot = {
|
||||||
|
userFilter = "(&(objectClass=posixAccount)(mail=%u))";
|
||||||
|
passFilter = "(&(objectClass=posixAccount)(mail=%u))";
|
||||||
|
userAttrs = "cn";
|
||||||
|
};
|
||||||
|
postfix = {
|
||||||
|
filter = "(|(&(objectClass=posixAccount)(mail=%s))(&(objectClass=posixAccount)(cn=%s)))";
|
||||||
|
mailAttribute = "mail";
|
||||||
|
uidAttribute = "cn";
|
||||||
|
};
|
||||||
|
#searchBase = "DC=test,DC=htw,DC=stura-dresden,DC=de";
|
||||||
|
searchBase = "dc=mail,dc=htw,dc=stura-dresden,dc=de";
|
||||||
|
uris = [
|
||||||
|
"ldap://auth.test.htw.stura-dresden.de:3389"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
certificateScheme = "acme-nginx";
|
||||||
|
enableImap = true;
|
||||||
|
enableImapSsl = true;
|
||||||
|
enableManageSieve = true;
|
||||||
|
enableSubmission = true;
|
||||||
|
enableSubmissionSsl = true;
|
||||||
|
extraVirtualAliases = { };
|
||||||
|
lmtpSaveToDetailMailbox = "no"; # DOS potential
|
||||||
|
mailboxes = {
|
||||||
|
Drafts = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Drafts";
|
||||||
|
};
|
||||||
|
Sent = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Sent";
|
||||||
|
};
|
||||||
|
Spam = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Junk";
|
||||||
|
};
|
||||||
|
Trash = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Trash";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
maxConnectionsPerUser = 10;
|
||||||
|
messageSizeLimit = 10 * 1000 * 1024; # 10 MiB
|
||||||
|
|
||||||
|
stateVersion = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
# services.dovecot2.mailLocation = lib.mkForce "maildir:/var/vmail/%n";
|
||||||
|
services.postfix =
|
||||||
|
let
|
||||||
|
submissionOptions = {
|
||||||
|
# hash:/etc/postfix/virtual,
|
||||||
|
smtpd_sender_login_maps = lib.mkForce "ldap:/run/postfix/ldap-sender-login-map.cf";
|
||||||
|
smtpd_client_restrictions = "permit_sasl_authenticated,reject";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
masterConfig = {
|
||||||
|
submission = {
|
||||||
|
args = [ "-v" ];
|
||||||
|
};
|
||||||
|
submissions = {
|
||||||
|
args = [ "-v" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
settings.main = {
|
||||||
|
unknown_local_recipient_reject_code = 550;
|
||||||
|
relay_domains = [
|
||||||
|
"hash:/var/lib/mailman/data/postfix_domains"
|
||||||
|
];
|
||||||
|
transport_maps = [
|
||||||
|
"hash:/var/lib/mailman/data/postfix_lmtp"
|
||||||
|
];
|
||||||
|
local_recipient_maps = [
|
||||||
|
"hash:/var/lib/mailman/data/postfix_lmtp"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# mapFiles = {
|
||||||
|
# "valias" = lib.mkForce "/var/lib/postfix/valias";
|
||||||
|
# "virtual" = lib.mkForce "/var/lib/postfix/virtual";
|
||||||
|
# };
|
||||||
|
submissionOptions = submissionOptions;
|
||||||
|
submissionsOptions = submissionOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme.acceptTerms = true;
|
||||||
|
security.acme.defaults.email = "cert@stura.htw-dresden.de";
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
25
|
||||||
|
80
|
||||||
|
443
|
||||||
|
597
|
||||||
|
];
|
||||||
|
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
26
hosts/mail/secrets.sops.yml
Normal file
26
hosts/mail/secrets.sops.yml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
ldap_passwd: ENC[AES256_GCM,data:adUZCZcYfoxBQm3e4YeeXcQJSZjB3+v2zSNy7q0Ao39aDQMH5H0w4o9MXTREkPHW53JejC2ivo8Zl3yUhkeYRw==,iv:XB25CmtUGf+PeSsHtr+CA/HIfZq1IrOBPPQD3/r6Kc4=,tag:A/WGViM/Ix7n6mhjnbCtZg==,type:str]
|
||||||
|
wireguard-key: ENC[AES256_GCM,data:5EWg5yF1CDKIusFwONVSzxSMM0cfOzyUYcWQ0f8xTHZ7bViAw8HbjJpRI4o=,iv:UNTv+994Q5VscsjgWS4ppkHX0gPy7vc/qmRCYKvR8CE=,tag:i8ydlyJSfIUj81j78EX5Fg==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age156ak7kc79tuwpv0hk9atl5dg27jqs6ddfqxvr9m4twqgsr23lgvsdmyfpr
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsenVrS0tkTWZRY2xDZklO
|
||||||
|
WTcwaENIY2I1bTFGMEZZVzBoeUNrT2RESmhFCnZXU2M1SjlGQWo0OEp0TzI0c21u
|
||||||
|
UkNuNEdQQldQdy9uSzhveEM2eFZrRUkKLS0tIGV4S3lreHJPVS96VUZ6SXRaSklW
|
||||||
|
MUE4eXN0bkNkU0dCckppdldvV2V4dHcKdKh6ekq6hB5pCUAEPdASqsxqAKZDwzCv
|
||||||
|
NyS2jitHo9XBtMQVJg4PmNcoRs5XLdqy2tP8upnGelj0B/Q9D+dhag==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1qp7w80k3qtj79xsl0gwsfrkm037xrlnhm6th7tcyrvufh3szzp6s2pe7ra
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRVlVrdXhGMDRxMjhPb3Nv
|
||||||
|
c3lBS25OKzJIaWhHWHpKQXo0N1dFTnZLaHdnClVFVTFPVE1rNFVEclFVc3VjQVhu
|
||||||
|
SjF6Nnp6dE9oRUJYUVVnOWVpVE11WVkKLS0tIEJ0aVJzejROMHFPK1JQbkJjbUdi
|
||||||
|
bGU3WWhVMGJ2LzI4N2E1Zy9RNnJ2V2MK4UQPwE5GUVTGvnuZ9knQ+BHmzmRLA1V5
|
||||||
|
SinlJfHcs+9B7haHzAekDdNqZgEUh2tblabHqq/vNWzd0rWpK31Dww==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2026-03-21T18:05:57Z"
|
||||||
|
mac: ENC[AES256_GCM,data:NJM8uwSGIrjy4t+3AwNxp2e569ArH/cnRDipsHnTTQYV5NJLOTtwoFnTqVHBSREc2Sh38gXKye1ncwS3IG5CMsF1nsLOL/+Y9mUqQkLeWeld6Kal8c99yIr2oz8Hk4JTJt4j2C8/aNFhqu62VF7F6JNElWq2F3J5TPKPHRbE9yY=,iv:mj18t2s9hqNV4ore9T4R4jOgUGPuXGqwW91M9Uoh6aQ=,tag:v6T7LXjLQGoc9leFI5zY0g==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.12.1
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
"${modulesPath}/virtualisation/proxmox-lxc.nix"
|
|
||||||
];
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
hostName = "monitoring";
|
|
||||||
fqdn = "monitoring.adm.htw.stura-dresden.de";
|
|
||||||
interfaces.eth0.ipv4.addresses = [
|
|
||||||
{
|
|
||||||
address = "141.56.51.20";
|
|
||||||
prefixLength = 24;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
defaultGateway = {
|
|
||||||
address = "141.56.51.254";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
firewall = {
|
|
||||||
enable = true;
|
|
||||||
allowedTCPPorts = [
|
|
||||||
80
|
|
||||||
443
|
|
||||||
4317 # OTLP gRPC (Proxmox)
|
|
||||||
4318 # OTLP HTTP (Proxmox)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Loki - Log aggregation system
|
|
||||||
services.loki = {
|
|
||||||
enable = true;
|
|
||||||
configuration = {
|
|
||||||
auth_enabled = false;
|
|
||||||
server = {
|
|
||||||
http_listen_port = 3100;
|
|
||||||
grpc_listen_port = 9096;
|
|
||||||
};
|
|
||||||
common = {
|
|
||||||
path_prefix = "/var/lib/loki";
|
|
||||||
storage.filesystem = {
|
|
||||||
chunks_directory = "/var/lib/loki/chunks";
|
|
||||||
rules_directory = "/var/lib/loki/rules";
|
|
||||||
};
|
|
||||||
replication_factor = 1;
|
|
||||||
ring = {
|
|
||||||
instance_addr = "127.0.0.1";
|
|
||||||
kvstore.store = "inmemory";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
limits_config = {
|
|
||||||
ingestion_rate_mb = 32;
|
|
||||||
ingestion_burst_size_mb = 64;
|
|
||||||
per_stream_rate_limit = "32MB";
|
|
||||||
per_stream_rate_limit_burst = "64MB";
|
|
||||||
max_query_series = 100000;
|
|
||||||
retention_period = "672h"; # 28 days
|
|
||||||
};
|
|
||||||
compactor = {
|
|
||||||
retention_enabled = true;
|
|
||||||
working_directory = "/var/lib/loki/compactor";
|
|
||||||
delete_request_store = "filesystem";
|
|
||||||
};
|
|
||||||
schema_config = {
|
|
||||||
configs = [
|
|
||||||
{
|
|
||||||
from = "2024-01-01";
|
|
||||||
store = "tsdb";
|
|
||||||
object_store = "filesystem";
|
|
||||||
schema = "v13";
|
|
||||||
index = {
|
|
||||||
prefix = "index_";
|
|
||||||
period = "24h";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Mimir - Scalable metrics storage
|
|
||||||
services.mimir = {
|
|
||||||
enable = true;
|
|
||||||
configuration = {
|
|
||||||
multitenancy_enabled = false;
|
|
||||||
memberlist = {
|
|
||||||
bind_addr = [ "0.0.0.0" ];
|
|
||||||
bind_port = 7946;
|
|
||||||
advertise_addr = "141.56.51.20";
|
|
||||||
join_members = [ "141.56.51.20:7946" ];
|
|
||||||
};
|
|
||||||
blocks_storage = {
|
|
||||||
backend = "filesystem";
|
|
||||||
filesystem = {
|
|
||||||
dir = "/var/lib/mimir/data";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
compactor = {
|
|
||||||
data_dir = "/var/lib/mimir/compactor";
|
|
||||||
};
|
|
||||||
distributor = {
|
|
||||||
ring = {
|
|
||||||
kvstore.store = "memberlist";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
ingester = {
|
|
||||||
ring = {
|
|
||||||
kvstore.store = "memberlist";
|
|
||||||
replication_factor = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
ruler_storage = {
|
|
||||||
backend = "filesystem";
|
|
||||||
filesystem = {
|
|
||||||
dir = "/var/lib/mimir/rules";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
server = {
|
|
||||||
http_listen_port = 9009;
|
|
||||||
grpc_listen_port = 9095;
|
|
||||||
};
|
|
||||||
limits = {
|
|
||||||
ingestion_rate = 100000;
|
|
||||||
ingestion_burst_size = 200000;
|
|
||||||
max_global_series_per_user = 0;
|
|
||||||
compactor_blocks_retention_period = "672h"; # 28 days
|
|
||||||
};
|
|
||||||
store_gateway = {
|
|
||||||
sharding_ring = {
|
|
||||||
replication_factor = 1;
|
|
||||||
kvstore.store = "memberlist";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Grafana - Visualization and dashboarding
|
|
||||||
services.grafana = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
http_addr = "127.0.0.1";
|
|
||||||
http_port = 3000;
|
|
||||||
domain = "mon.adm.htw.stura-dresden.de";
|
|
||||||
root_url = "https://mon.adm.htw.stura-dresden.de";
|
|
||||||
};
|
|
||||||
security = {
|
|
||||||
admin_user = "admin";
|
|
||||||
admin_password = "$__file{/var/lib/grafana/admin_password}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
provision = {
|
|
||||||
enable = true;
|
|
||||||
datasources.settings.datasources = [
|
|
||||||
{
|
|
||||||
name = "Mimir";
|
|
||||||
type = "prometheus";
|
|
||||||
url = "http://localhost:9009/prometheus";
|
|
||||||
isDefault = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "Loki";
|
|
||||||
type = "loki";
|
|
||||||
url = "http://localhost:3100";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Nginx reverse proxy with ACME certificates
|
|
||||||
services.nginx = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
virtualHosts."log.adm.htw.stura-dresden.de" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:3100";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
recommendedProxySettings = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualHosts."met.adm.htw.stura-dresden.de" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:9009";
|
|
||||||
recommendedProxySettings = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualHosts."mon.adm.htw.stura-dresden.de" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:3000";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
recommendedProxySettings = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Vector - receive OpenTelemetry data from Proxmox and forward to Loki/Mimir
|
|
||||||
services.vector.settings = {
|
|
||||||
sources.proxmox_otlp = {
|
|
||||||
type = "opentelemetry";
|
|
||||||
grpc.address = "0.0.0.0:4317";
|
|
||||||
http.address = "0.0.0.0:4318";
|
|
||||||
};
|
|
||||||
|
|
||||||
transforms.proxmox_normalize_logs = {
|
|
||||||
type = "remap";
|
|
||||||
inputs = [ "proxmox_otlp.logs" ];
|
|
||||||
source = ''
|
|
||||||
.host = string(.resources."host.name") ?? "proxmox"
|
|
||||||
.unit = string(.attributes."service.name") ?? "proxmox"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
transforms.proxmox_normalize_metrics = {
|
|
||||||
type = "remap";
|
|
||||||
inputs = [ "proxmox_otlp.metrics" ];
|
|
||||||
source = ''
|
|
||||||
.tags.host = string(.resources."host.name") ?? "proxmox"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
stura.monitoring = {
|
|
||||||
extraMetricInputs = [ "proxmox_normalize_metrics" ];
|
|
||||||
extraLogInputs = [ "proxmox_normalize_logs" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh.enable = true;
|
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
|
||||||
}
|
|
||||||
|
|
@ -87,11 +87,6 @@
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
recommendedTlsSettings = true;
|
recommendedTlsSettings = true;
|
||||||
|
|
||||||
commonHttpConfig = ''
|
|
||||||
real_ip_header proxy_protocol;
|
|
||||||
set_real_ip_from 141.56.51.1/32;
|
|
||||||
'';
|
|
||||||
|
|
||||||
logError = ''
|
logError = ''
|
||||||
/dev/null emerg
|
/dev/null emerg
|
||||||
'';
|
'';
|
||||||
|
|
@ -99,21 +94,9 @@
|
||||||
virtualHosts.${config.networking.fqdn} = {
|
virtualHosts.${config.networking.fqdn} = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
listen = [
|
extraConfig = ''
|
||||||
{
|
access_log off;
|
||||||
port = 80;
|
'';
|
||||||
addr = "0.0.0.0";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
port = 443;
|
|
||||||
addr = "0.0.0.0";
|
|
||||||
ssl = true;
|
|
||||||
proxyProtocol = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
# extraConfig = ''
|
|
||||||
# access_log off;
|
|
||||||
# '';
|
|
||||||
};
|
};
|
||||||
# virtualHosts."cloud.htw.stura-dresden.de" = {
|
# virtualHosts."cloud.htw.stura-dresden.de" = {
|
||||||
# forceSSL = true;
|
# forceSSL = true;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,12 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
sops = {
|
||||||
|
defaultSopsFile = ./secrets.sops.yml;
|
||||||
|
secrets = {
|
||||||
|
"wireguard-key".owner = "systemd-network";
|
||||||
|
};
|
||||||
|
};
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
./hetzner-disk.nix
|
./hetzner-disk.nix
|
||||||
|
|
@ -13,6 +19,7 @@
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
hostName = "proxy";
|
hostName = "proxy";
|
||||||
|
nameservers = [ "141.56.51.1" ];
|
||||||
interfaces.ens18.ipv4.addresses = [
|
interfaces.ens18.ipv4.addresses = [
|
||||||
{
|
{
|
||||||
address = "141.56.51.1";
|
address = "141.56.51.1";
|
||||||
|
|
@ -20,98 +27,48 @@
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
defaultGateway.address = "141.56.51.254";
|
defaultGateway.address = "141.56.51.254";
|
||||||
firewall.enable = false;
|
firewall = {
|
||||||
|
allowedTCPPorts = [
|
||||||
|
22
|
||||||
|
53 # DNS
|
||||||
|
80
|
||||||
|
443
|
||||||
|
1005
|
||||||
|
2142
|
||||||
|
];
|
||||||
|
allowedUDPPorts = [
|
||||||
|
53 # DNS
|
||||||
|
123 # NTP
|
||||||
|
];
|
||||||
|
};
|
||||||
nftables = {
|
nftables = {
|
||||||
enable = true;
|
enable = true;
|
||||||
ruleset = ''
|
};
|
||||||
table inet filter {
|
wireguard = {
|
||||||
set blacklist4 {
|
enable = true;
|
||||||
type ipv4_addr
|
interfaces = {
|
||||||
flags interval
|
sturauplink = {
|
||||||
# manage: nft add element inet filter blacklist4 { 1.2.3.0/24 }
|
privateKeyFile = config.sops.secrets."wireguard-key".path;
|
||||||
|
ips = [
|
||||||
|
"10.100.0.2/24"
|
||||||
|
"fd28:6691:1921:6299::2/64"
|
||||||
|
];
|
||||||
|
listenPort = 51820;
|
||||||
|
peers = [
|
||||||
|
# mail.test.htw.stura-dresden.de
|
||||||
|
{
|
||||||
|
endpoint = "hetzner.test.htw.stura-dresden.de:51820";
|
||||||
|
allowedIPs = [
|
||||||
|
"10.100.0.0/24"
|
||||||
|
];
|
||||||
|
persistentKeepalive = 30;
|
||||||
|
publicKey = "Tg/SNniezzF4DUnvUl1/JxQwS18POrUR20UmkQDt+X0=";
|
||||||
}
|
}
|
||||||
|
];
|
||||||
set blacklist6 {
|
};
|
||||||
type ipv6_addr
|
|
||||||
flags interval
|
|
||||||
# manage: nft add element inet filter blacklist6 { 2001:db8::/32 }
|
|
||||||
}
|
|
||||||
|
|
||||||
chain input {
|
|
||||||
type filter hook input priority filter; policy drop;
|
|
||||||
|
|
||||||
iif "lo" accept
|
|
||||||
ct state established,related accept
|
|
||||||
|
|
||||||
ip saddr 141.56.51.0/24 accept
|
|
||||||
ip saddr @blacklist4 drop
|
|
||||||
ip6 saddr @blacklist6 drop
|
|
||||||
|
|
||||||
# public ports
|
|
||||||
tcp dport { 80, 443, 1005, 2142 } accept
|
|
||||||
|
|
||||||
# lan-only: dns and ntp
|
|
||||||
ip saddr 141.56.51.0/24 tcp dport 53 accept
|
|
||||||
ip saddr 141.56.51.0/24 udp dport { 53, 123 } accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain forward {
|
|
||||||
type filter hook forward priority filter; policy drop;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain output {
|
|
||||||
type filter hook output priority filter; policy accept;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Phase 1: Kernel-Level TCP Tuning
|
|
||||||
boot.kernel.sysctl = {
|
|
||||||
# Connection tracking - prevents "table full" errors
|
|
||||||
"net.netfilter.nf_conntrack_max" = 262144; # Conservative limit matching current kernel
|
|
||||||
"net.netfilter.nf_conntrack_buckets" = 65536; # 4:1 ratio
|
|
||||||
|
|
||||||
# Reduce connection tracking timeouts (defaults are excessive)
|
|
||||||
"net.netfilter.nf_conntrack_tcp_timeout_established" = 600; # 10 min (down from 5 days)
|
|
||||||
"net.netfilter.nf_conntrack_tcp_timeout_time_wait" = 30; # 30s
|
|
||||||
"net.netfilter.nf_conntrack_tcp_timeout_close_wait" = 15; # 15s
|
|
||||||
"net.netfilter.nf_conntrack_tcp_timeout_fin_wait" = 30; # 30s
|
|
||||||
|
|
||||||
# TCP connection handling
|
|
||||||
"net.core.somaxconn" = 65535; # Must be >= HAProxy maxconn
|
|
||||||
"net.core.netdev_max_backlog" = 16384;
|
|
||||||
"net.ipv4.tcp_max_syn_backlog" = 8192;
|
|
||||||
|
|
||||||
# TCP buffer auto-tuning (16MB max)
|
|
||||||
"net.ipv4.tcp_rmem" = "4096 87380 16777216";
|
|
||||||
"net.ipv4.tcp_wmem" = "4096 65536 16777216";
|
|
||||||
"net.core.rmem_max" = 16777216;
|
|
||||||
"net.core.wmem_max" = 16777216;
|
|
||||||
|
|
||||||
# TCP optimization
|
|
||||||
"net.ipv4.tcp_fin_timeout" = 15;
|
|
||||||
"net.ipv4.tcp_keepalive_time" = 300; # 5 min
|
|
||||||
"net.ipv4.tcp_keepalive_probes" = 3;
|
|
||||||
"net.ipv4.tcp_keepalive_intvl" = 15;
|
|
||||||
|
|
||||||
# TCP Fast Open
|
|
||||||
"net.ipv4.tcp_fastopen" = 3;
|
|
||||||
|
|
||||||
# BBR congestion control for better throughput
|
|
||||||
"net.ipv4.tcp_congestion_control" = "bbr";
|
|
||||||
"net.core.default_qdisc" = "fq";
|
|
||||||
|
|
||||||
# Ephemeral port range
|
|
||||||
"net.ipv4.ip_local_port_range" = "10000 65535";
|
|
||||||
|
|
||||||
# TIME_WAIT socket reuse
|
|
||||||
"net.ipv4.tcp_tw_reuse" = 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Enable BBR kernel module
|
|
||||||
boot.kernelModules = [ "tcp_bbr" ];
|
|
||||||
|
|
||||||
# wenn instanzen in die flake migriert sind könnte man das autogenerierien
|
# wenn instanzen in die flake migriert sind könnte man das autogenerierien
|
||||||
services =
|
services =
|
||||||
|
|
@ -126,112 +83,108 @@
|
||||||
domain = "docs.adm.htw.stura-dresden.de";
|
domain = "docs.adm.htw.stura-dresden.de";
|
||||||
httpPort = 8080;
|
httpPort = 8080;
|
||||||
httpsPort = 8443;
|
httpsPort = 8443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
plone = {
|
plone = {
|
||||||
dest = "141.56.51.3";
|
dest = "141.56.51.3";
|
||||||
domain = "stura.htw-dresden.de";
|
domain = "stura.htw-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = true;
|
|
||||||
};
|
};
|
||||||
plone_alt = {
|
plone_alt = {
|
||||||
dest = "141.56.51.3";
|
dest = "141.56.51.3";
|
||||||
domain = "www.stura.htw-dresden.de";
|
domain = "www.stura.htw-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = true;
|
|
||||||
};
|
};
|
||||||
plone_neu = {
|
plone_neu = {
|
||||||
dest = "141.56.51.3";
|
dest = "141.56.51.3";
|
||||||
domain = "www.htw.stura-dresden.de";
|
domain = "www.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = true;
|
|
||||||
};
|
};
|
||||||
plone_neu2 = {
|
plone_neu2 = {
|
||||||
dest = "141.56.51.3";
|
dest = "141.56.51.3";
|
||||||
domain = "htw.stura-dresden.de";
|
domain = "htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = true;
|
|
||||||
};
|
};
|
||||||
tix = {
|
tix = {
|
||||||
dest = "141.56.51.220";
|
dest = "141.56.51.220";
|
||||||
domain = "tix.htw.stura-dresden.de";
|
domain = "tix.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
post = {
|
post = {
|
||||||
dest = "141.56.51.56";
|
dest = "141.56.51.56";
|
||||||
domain = "post.htw.stura-dresden.de";
|
domain = "post.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
vot = {
|
vot = {
|
||||||
dest = "141.56.51.57";
|
dest = "141.56.51.57";
|
||||||
domain = "vot.htw.stura-dresden.de";
|
domain = "vot.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
mail = {
|
mail = {
|
||||||
dest = "141.56.51.14";
|
dest = "141.56.51.14";
|
||||||
domain = "mail.htw.stura-dresden.de";
|
domain = "mail.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
lists = {
|
lists = {
|
||||||
dest = "141.56.51.14";
|
dest = "141.56.51.14";
|
||||||
domain = "lists.htw.stura-dresden.de";
|
domain = "lists.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
dat = {
|
dat = {
|
||||||
dest = "141.56.51.17";
|
dest = "141.56.51.17";
|
||||||
domain = "dat.stu.htw.stura-dresden.de";
|
domain = "dat.stu.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
};
|
||||||
|
pro = {
|
||||||
|
dest = "141.56.51.15";
|
||||||
|
domain = "pro.htw.stura-dresden.de";
|
||||||
|
httpPort = 80;
|
||||||
|
httpsPort = 443;
|
||||||
|
};
|
||||||
|
cloud = {
|
||||||
|
dest = "141.56.51.16";
|
||||||
|
domain = "cloud.htw.stura-dresden.de";
|
||||||
|
httpPort = 80;
|
||||||
|
httpsPort = 443;
|
||||||
};
|
};
|
||||||
wiki = {
|
wiki = {
|
||||||
dest = "141.56.51.13";
|
dest = "141.56.51.13";
|
||||||
domain = "wiki.htw.stura-dresden.de";
|
domain = "wiki.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = true;
|
|
||||||
};
|
};
|
||||||
beach = {
|
beach = {
|
||||||
dest = "141.56.51.51";
|
dest = "141.56.51.51";
|
||||||
domain = "beach.htw.stura-dresden.de";
|
domain = "beach.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
studicloud = {
|
studicloud = {
|
||||||
dest = "141.56.51.17";
|
dest = "141.56.51.17";
|
||||||
domain = "dat.stu.htw.stura-dresden.de";
|
domain = "dat.stu.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
bbb = {
|
bbb = {
|
||||||
dest = "141.56.51.94";
|
dest = "141.56.51.94";
|
||||||
domain = "bbb.htw.stura-dresden.de";
|
domain = "bbb.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
bbb-test = {
|
bbb-test = {
|
||||||
dest = "141.56.51.94";
|
dest = "141.56.51.94";
|
||||||
domain = "bbb.test.htw.stura-dresden.de";
|
domain = "bbb.test.htw.stura-dresden.de";
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
sendProxy = false;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
# zusätzlich zu den oben definierten wird hier noch ein redirect für jeden nginx virtualhost in diese flake generiert
|
# zusätzlich zu den oben definierten wird hier noch ein redirect für jeden nginx virtualhost in diese flake generiert
|
||||||
|
|
@ -250,15 +203,6 @@
|
||||||
prev
|
prev
|
||||||
// (builtins.foldl' (
|
// (builtins.foldl' (
|
||||||
val: vhost:
|
val: vhost:
|
||||||
let
|
|
||||||
proxyProtocol =
|
|
||||||
if
|
|
||||||
self.nixosConfigurations.${name}.config.services.nginx.virtualHosts.${vhost}.listen == [ ]
|
|
||||||
then
|
|
||||||
false
|
|
||||||
else
|
|
||||||
true;
|
|
||||||
in
|
|
||||||
val
|
val
|
||||||
// {
|
// {
|
||||||
"${vhost}" = {
|
"${vhost}" = {
|
||||||
|
|
@ -266,7 +210,6 @@
|
||||||
domain = vhost;
|
domain = vhost;
|
||||||
httpsPort = 443;
|
httpsPort = 443;
|
||||||
httpPort = 80;
|
httpPort = 80;
|
||||||
sendProxy = proxyProtocol;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
) { } vhosts)
|
) { } vhosts)
|
||||||
|
|
@ -323,43 +266,44 @@
|
||||||
"127.0.0.1"
|
"127.0.0.1"
|
||||||
];
|
];
|
||||||
listenOnIpv6 = [ ];
|
listenOnIpv6 = [ ];
|
||||||
# zones = {
|
zones = {
|
||||||
# "htw.stura-dresden.de" = {
|
"htw.stura-dresden.de" = {
|
||||||
# master = true;
|
master = true;
|
||||||
# file = pkgs.writeText "htw.stura-dresden.de.zone" ''
|
file = pkgs.writeText "htw.stura-dresden.de.zone" ''
|
||||||
# $TTL 3600
|
$TTL 3600
|
||||||
# @ IN SOA proxy.htw.stura-dresden.de. hostmaster.htw.stura-dresden.de. (
|
@ IN SOA proxy.htw.stura-dresden.de. hostmaster.htw.stura-dresden.de. (
|
||||||
# 2026031301 ; Serial (YYYYMMDDNN)
|
2026031301 ; Serial (YYYYMMDDNN)
|
||||||
# 3600 ; Refresh (1 hour)
|
3600 ; Refresh (1 hour)
|
||||||
# 1800 ; Retry (30 minutes)
|
1800 ; Retry (30 minutes)
|
||||||
# 604800 ; Expire (1 week)
|
604800 ; Expire (1 week)
|
||||||
# 86400 ) ; Minimum TTL (1 day)
|
86400 ) ; Minimum TTL (1 day)
|
||||||
#
|
|
||||||
# ; Name servers
|
; Name servers
|
||||||
# @ IN NS proxy.htw.stura-dresden.de.
|
@ IN NS proxy.htw.stura-dresden.de.
|
||||||
#
|
|
||||||
# ; Proxy host - main IPv4 gateway
|
; Proxy host - main IPv4 gateway
|
||||||
# proxy IN A 141.56.51.1
|
proxy IN A 141.56.51.1
|
||||||
# proxy IN AAAA 2a01:4f8:1c19:96f8::1
|
proxy IN AAAA 2a01:4f8:1c19:96f8::1
|
||||||
#
|
|
||||||
# ; Auto-generated CNAME records for all subdomains pointing to proxy
|
; Auto-generated CNAME records for all subdomains pointing to proxy
|
||||||
# ${lib.foldlAttrs (
|
hetzner.test IN A 178.104.18.93
|
||||||
# prev: name: value:
|
${lib.foldlAttrs (
|
||||||
# let
|
prev: name: value:
|
||||||
# zoneSuffix = ".htw.stura-dresden.de";
|
let
|
||||||
# # Check if this domain belongs to our zone
|
zoneSuffix = ".htw.stura-dresden.de";
|
||||||
# isInZone = lib.hasSuffix zoneSuffix value.domain;
|
# Check if this domain belongs to our zone
|
||||||
# # Extract subdomain by removing the zone suffix
|
isInZone = lib.hasSuffix zoneSuffix value.domain;
|
||||||
# subdomain = lib.removeSuffix zoneSuffix value.domain;
|
# Extract subdomain by removing the zone suffix
|
||||||
# in
|
subdomain = lib.removeSuffix zoneSuffix value.domain;
|
||||||
# if isInZone && subdomain != "" && subdomain != "htw.stura-dresden.de" then
|
in
|
||||||
# prev + "${subdomain}${" "}IN${" "}CNAME${" "}proxy.htw.stura-dresden.de.\n"
|
if isInZone && subdomain != "" && subdomain != "htw.stura-dresden.de" then
|
||||||
# else
|
prev + "${subdomain}${" "}IN${" "}CNAME${" "}proxy.htw.stura-dresden.de.\n"
|
||||||
# prev
|
else
|
||||||
# ) "" forwards}
|
prev
|
||||||
# '';
|
) "" forwards}
|
||||||
# };
|
'';
|
||||||
# };
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Chrony NTP server for the internal network
|
# Chrony NTP server for the internal network
|
||||||
|
|
@ -435,35 +379,18 @@
|
||||||
global
|
global
|
||||||
# schreibe globalen log ins journal ip -> app
|
# schreibe globalen log ins journal ip -> app
|
||||||
log /dev/log format raw local0
|
log /dev/log format raw local0
|
||||||
maxconn 60000 # Safe limit below kernel conntrack (262144)
|
maxconn 50000
|
||||||
|
# man könnte metriken über einen socket file statt einen lokalen port machen für user permission control
|
||||||
# Buffer optimizations (Phase 2)
|
# stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
|
||||||
tune.bufsize 32768 # Power of 2 (was 32762)
|
tune.bufsize 32762
|
||||||
tune.maxrewrite 8192
|
|
||||||
|
|
||||||
# Connection handling
|
|
||||||
tune.maxaccept 500 # Prevent accept starvation
|
|
||||||
tune.maxpollevents 300
|
|
||||||
|
|
||||||
# TCP buffer sizes (64KB)
|
|
||||||
tune.rcvbuf.client 65536
|
|
||||||
tune.rcvbuf.server 65536
|
|
||||||
tune.sndbuf.client 65536
|
|
||||||
tune.sndbuf.server 65536
|
|
||||||
|
|
||||||
defaults
|
defaults
|
||||||
log global
|
log global
|
||||||
mode tcp
|
mode tcp
|
||||||
option tcplog
|
option tcplog
|
||||||
|
timeout connect 5s
|
||||||
# Optimized timeouts (Phase 5)
|
timeout client 30s
|
||||||
timeout connect 3s # Reduce from 5s
|
timeout server 30s
|
||||||
timeout client 60s # Increase from 30s
|
|
||||||
timeout server 60s # Increase from 30s
|
|
||||||
timeout queue 5s # Prevent indefinite queueing
|
|
||||||
|
|
||||||
# Performance
|
|
||||||
option splice-auto # Zero-copy kernel splicing
|
|
||||||
|
|
||||||
# stats seite zeigt backend connection status, wenn check gesetzt ist
|
# stats seite zeigt backend connection status, wenn check gesetzt ist
|
||||||
frontend stats
|
frontend stats
|
||||||
|
|
@ -471,21 +398,13 @@
|
||||||
mode http
|
mode http
|
||||||
stats enable
|
stats enable
|
||||||
stats uri /stats
|
stats uri /stats
|
||||||
stats refresh 5s # Reduce from 10s for real-time monitoring
|
stats refresh 10s
|
||||||
stats show-legends
|
stats show-legends
|
||||||
stats show-node
|
stats show-node
|
||||||
stats show-modules
|
stats show-modules
|
||||||
stats admin if TRUE # Enable admin operations
|
|
||||||
http-request use-service prometheus-exporter if { path /metrics }
|
|
||||||
|
|
||||||
frontend http-in
|
frontend http-in
|
||||||
bind *:80
|
bind *:80
|
||||||
mode http
|
|
||||||
tcp-request connection expect-proxy layer4 if { src 178.104.18.93 }
|
|
||||||
maxconn 60000
|
|
||||||
backlog 8192
|
|
||||||
option dontlognull
|
|
||||||
option http-keep-alive # Reuse connections for redirects
|
|
||||||
|
|
||||||
# hier wird eine regel pro domain aus der forwarder liste generiert
|
# hier wird eine regel pro domain aus der forwarder liste generiert
|
||||||
${lib.foldlAttrs (
|
${lib.foldlAttrs (
|
||||||
|
|
@ -504,8 +423,8 @@
|
||||||
prev: name: value:
|
prev: name: value:
|
||||||
prev
|
prev
|
||||||
+ ''
|
+ ''
|
||||||
http-request redirect scheme https code 301 if !is_acme is_${name}
|
|
||||||
use_backend ${name}_80 if is_${name}
|
use_backend ${name}_80 if is_${name}
|
||||||
|
http-request redirect scheme https code 301 if !is_acme is_${name}
|
||||||
''
|
''
|
||||||
) "" forwards}
|
) "" forwards}
|
||||||
|
|
||||||
|
|
@ -526,18 +445,10 @@
|
||||||
frontend sni_router
|
frontend sni_router
|
||||||
bind *:443
|
bind *:443
|
||||||
mode tcp
|
mode tcp
|
||||||
tcp-request connection expect-proxy layer4 if { src 178.104.18.93 }
|
# mehrere pakete puffern und connection beenden wenn es kein ssl handshake sieht
|
||||||
|
tcp-request inspect-delay 1s
|
||||||
# Reduce inspection delay - SNI is in first packet (Phase 3)
|
|
||||||
tcp-request inspect-delay 500ms # Was 1s
|
|
||||||
tcp-request content accept if { req_ssl_hello_type 1 }
|
tcp-request content accept if { req_ssl_hello_type 1 }
|
||||||
|
|
||||||
# Connection handling
|
|
||||||
option clitcpka # Enable client TCP keep-alive
|
|
||||||
maxconn 60000
|
|
||||||
backlog 16384 # Increase from default 1024
|
|
||||||
option dontlognull # Skip logging of monitoring probes
|
|
||||||
|
|
||||||
# tcp redirect der anwendung basierend auf ssl_sni handshake parameter
|
# tcp redirect der anwendung basierend auf ssl_sni handshake parameter
|
||||||
${lib.foldlAttrs (
|
${lib.foldlAttrs (
|
||||||
prev: name: value:
|
prev: name: value:
|
||||||
|
|
@ -568,117 +479,13 @@
|
||||||
server ${name} ${value.dest}:${builtins.toString value.httpPort}
|
server ${name} ${value.dest}:${builtins.toString value.httpPort}
|
||||||
backend ${name}_443
|
backend ${name}_443
|
||||||
mode tcp
|
mode tcp
|
||||||
option tcpka # Enable server TCP keep-alive (Phase 4)
|
server ${name} ${value.dest}:${builtins.toString value.httpsPort} check
|
||||||
timeout server 60s # Increase from 30s for long-lived HTTPS
|
|
||||||
timeout connect 3s # Reduce from 5s (local network)
|
|
||||||
server ${name} ${value.dest}:${builtins.toString value.httpsPort} ${
|
|
||||||
if value.sendProxy == true then "send-proxy-v2" else ""
|
|
||||||
} check inter 3000 rise 2 fall 3 maxconn 5000
|
|
||||||
|
|
||||||
''
|
''
|
||||||
) "" forwards}
|
) "" forwards}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
vector.settings = {
|
|
||||||
enrichment_tables.geoip_table = {
|
|
||||||
type = "mmdb";
|
|
||||||
path = "/var/lib/GeoIP/GeoLite2-City.mmdb";
|
|
||||||
};
|
};
|
||||||
sources.haproxy_metrics = {
|
|
||||||
type = "prometheus_scrape";
|
|
||||||
endpoints = [ "http://127.0.0.1:8404/metrics" ];
|
|
||||||
scrape_interval_secs = 15;
|
|
||||||
};
|
|
||||||
transforms = {
|
|
||||||
add_host_label_haproxy = {
|
|
||||||
type = "remap";
|
|
||||||
inputs = [ "haproxy_metrics" ];
|
|
||||||
source = ''
|
|
||||||
.tags.host = get_hostname!()
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
haproxy_logs_filter = {
|
|
||||||
type = "filter";
|
|
||||||
inputs = [ "journald_logs" ];
|
|
||||||
condition = ''."_SYSTEMD_UNIT" == "haproxy.service"'';
|
|
||||||
};
|
|
||||||
haproxy_logs_parse = {
|
|
||||||
type = "remap";
|
|
||||||
inputs = [ "haproxy_logs_filter" ];
|
|
||||||
source = ''
|
|
||||||
.host = get_hostname!()
|
|
||||||
.unit = "haproxy"
|
|
||||||
# IPv4: "1.2.3.4:port" IPv6: "[2001:db8::1]:port"
|
|
||||||
parsed, err = parse_regex(.message, r'^(?:\[(?P<ipv6>[0-9a-fA-F:]+)\]|(?P<ipv4>[\d.]+)):\d+')
|
|
||||||
if err == null {
|
|
||||||
if is_null(parsed.ipv6) {
|
|
||||||
.client_ip = parsed.ipv4
|
|
||||||
} else {
|
|
||||||
.client_ip = parsed.ipv6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
haproxy_geoip = {
|
|
||||||
type = "remap";
|
|
||||||
inputs = [ "haproxy_logs_parse" ];
|
|
||||||
source = ''
|
|
||||||
if exists(.client_ip) && !is_null(.client_ip) {
|
|
||||||
.geoip = get_enrichment_table_record("geoip_table", {"ip": string!(.client_ip)}) ?? {}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
sinks.mimir.inputs = lib.mkForce [
|
|
||||||
"add_host_label_metrics"
|
|
||||||
"add_host_label_haproxy"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
stura.monitoring.extraLogInputs = [ "haproxy_geoip" ];
|
|
||||||
|
|
||||||
users.users.root.packages = [
|
|
||||||
(pkgs.writeShellScriptBin "nft-blacklist" ''
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo "Usage: nft-blacklist <add|del> <ip-or-cidr>"
|
|
||||||
echo " add - add entry to blacklist set"
|
|
||||||
echo " del - remove entry from blacklist set"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ $# -ne 2 ]] && usage
|
|
||||||
|
|
||||||
ACTION="$1"
|
|
||||||
ADDR="$2"
|
|
||||||
|
|
||||||
if [[ "$ADDR" == *:* ]]; then
|
|
||||||
SET="blacklist6"
|
|
||||||
elif [[ "$ADDR" == *.* ]]; then
|
|
||||||
SET="blacklist4"
|
|
||||||
else
|
|
||||||
echo "Error: cannot determine address family for '$ADDR'" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$ACTION" in
|
|
||||||
add)
|
|
||||||
${pkgs.nftables}/bin/nft add element inet filter "$SET" "{ $ADDR }"
|
|
||||||
echo "Added $ADDR to $SET"
|
|
||||||
;;
|
|
||||||
del)
|
|
||||||
${pkgs.nftables}/bin/nft delete element inet filter "$SET" "{ $ADDR }"
|
|
||||||
echo "Removed $ADDR from $SET"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
'')
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
];
|
];
|
||||||
|
|
|
||||||
25
hosts/proxy/secrets.sops.yml
Normal file
25
hosts/proxy/secrets.sops.yml
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
wireguard-key: ENC[AES256_GCM,data:tEKd+iwfyabTj/spqh08Um3FX4grLeffTxCvBivkXrNqIzOymBdcgQL4IJ4=,iv:Z2sr5yzxTKXgBgfcd3LWB9jT2fX3uRpX07r4yMplSNY=,tag:IWgiEjjbHbIUORhwKjTM6g==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age1g9fnxzalnqtse29xjdrvcsrnrknp8t2s7xrle73fce0jcg7r3czsj524p4
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXcUhhSlVQcHgvUEtDa0E2
|
||||||
|
UU1ON3NiUUlHTXFUOEdNeUdGVWNVTWRRNW0wCmhTVnJONlZSMmt2OVJiMys5bnM2
|
||||||
|
TDZPMExYaWlKSVFPVERnS1QvVTJlNXMKLS0tIElTYmxHNTFPSmNXYnkrY2RtRUVL
|
||||||
|
WHBCYWhtSWt1QW9hbEFwVmdqWUxjUmMKpqfV/bJVfyDI2Wa+jlwsXMx3tNV9G0S2
|
||||||
|
VhmmpDnEJn6UDWAMYxNv0g3rtfhBkb2HyCtANNVQ7QROua9WHzJjlg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1qp7w80k3qtj79xsl0gwsfrkm037xrlnhm6th7tcyrvufh3szzp6s2pe7ra
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVVUVkdDljcForNEJ2WmNm
|
||||||
|
N0QvTWhQWXQ1VHh5b0pCZFQ3aGxXSGY2bXprCmpEV2l6bkxnUDByNVZaVVR6N2lE
|
||||||
|
OG1sYkJrQmFVWW1vWXRZL1A2S29MejQKLS0tIEFKbkRmdWM0QW9vVlJWZElXSUcw
|
||||||
|
b1pCMjNIN1padE5JNVpZNFYwMnZGd00KM415cr6nuN6zfhDcfXFN2lMDWogLwDSE
|
||||||
|
Kq/ykUSuN9IU6AhslgBNRCmJRVHIzCmu5dU5NVZeqN1YT/EyAbEcyw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2026-03-21T18:56:03Z"
|
||||||
|
mac: ENC[AES256_GCM,data:v1RkpxjvgLHS3OOA2aEG+uJ3yWpOvJLwFA5jRBRtMoMvrBD8O8sikzWJUczQnpw85F/ieFqK6RdT8SBA9lIuPXYMRRS8icHI2a8P+zwySsWsnzc9UaJjjvKtkYo9nnPNCM36HAFOKHiAzBm7FWMt1Tl+WQMyVCWLXCN7ao0MjIo=,iv:8xCrY7QOhW5Mc/AWWXFocqwTUD9qvH4dLYYtnsU6PHw=,tag:09Nw7qFfjefrv0jBwaFINA==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.12.1
|
||||||
|
|
@ -90,9 +90,7 @@
|
||||||
services.redmine.settings.production.email_delivery = {
|
services.redmine.settings.production.email_delivery = {
|
||||||
delivery_method = ":smtp";
|
delivery_method = ":smtp";
|
||||||
smtp_settings = {
|
smtp_settings = {
|
||||||
# @tan 27-03-2026: muss an "alten" mailserver senden
|
address = "mail.${config.networking.domain}";
|
||||||
#address = "mail.${config.networking.domain}";
|
|
||||||
address = "mail.stura.htw-dresden.de";
|
|
||||||
port = 25;
|
port = 25;
|
||||||
};
|
};
|
||||||
#### Alternativ waere vielleicht auch das Versand von Mails durch das Programm sendmail (als lokale Installation) moeglich.
|
#### Alternativ waere vielleicht auch das Versand von Mails durch das Programm sendmail (als lokale Installation) moeglich.
|
||||||
|
|
@ -134,29 +132,13 @@
|
||||||
|
|
||||||
#### Der StuRa speichert nicht!
|
#### Der StuRa speichert nicht!
|
||||||
services.nginx.logError = ''/dev/null emerg'';
|
services.nginx.logError = ''/dev/null emerg'';
|
||||||
# services.nginx.appendHttpConfig = ''
|
services.nginx.appendHttpConfig = ''
|
||||||
# access_log off;
|
access_log off;
|
||||||
# '';
|
|
||||||
services.nginx.commonHttpConfig = ''
|
|
||||||
real_ip_header proxy_protocol;
|
|
||||||
set_real_ip_from 141.56.51.1/32;
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
#### Anscheinend kann mit nix nur die Konfiguration fuer eine konkrete (manuelle) Konfiguration fuer den Dienst web server.
|
#### Anscheinend kann mit nix nur die Konfiguration fuer eine konkrete (manuelle) Konfiguration fuer den Dienst web server.
|
||||||
services.nginx.virtualHosts."${config.networking.fqdn}" = {
|
services.nginx.virtualHosts."${config.networking.fqdn}" = {
|
||||||
#### https://search.nixos.org/options?show=services.nginx.virtualHosts.<name>.default
|
#### https://search.nixos.org/options?show=services.nginx.virtualHosts.<name>.default
|
||||||
listen = [
|
|
||||||
{
|
|
||||||
port = 80;
|
|
||||||
addr = "0.0.0.0";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
port = 443;
|
|
||||||
addr = "0.0.0.0";
|
|
||||||
ssl = true;
|
|
||||||
proxyProtocol = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
default = true;
|
default = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://127.0.0.1:${toString config.services.redmine.port}";
|
proxyPass = "http://127.0.0.1:${toString config.services.redmine.port}";
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,12 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
sops = {
|
||||||
|
defaultSopsFile = ./secrets.sops.yml;
|
||||||
|
secrets = {
|
||||||
|
"wireguard-key".owner = "systemd-network";
|
||||||
|
};
|
||||||
|
};
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
./hetzner-disk.nix
|
./hetzner-disk.nix
|
||||||
|
|
@ -38,44 +44,46 @@
|
||||||
"9.9.9.9"
|
"9.9.9.9"
|
||||||
"1.1.1.1"
|
"1.1.1.1"
|
||||||
];
|
];
|
||||||
firewall.enable = false;
|
firewall = {
|
||||||
|
allowedTCPPorts = [
|
||||||
|
22
|
||||||
|
80
|
||||||
|
443
|
||||||
|
];
|
||||||
|
};
|
||||||
nftables = {
|
nftables = {
|
||||||
enable = true;
|
enable = true;
|
||||||
ruleset = ''
|
};
|
||||||
table inet filter {
|
wireguard = {
|
||||||
set blacklist4 {
|
enable = true;
|
||||||
type ipv4_addr
|
interfaces = {
|
||||||
flags interval
|
sturauplink = {
|
||||||
# manage at runtime: nft add element inet filter blacklist4 { 1.2.3.0/24 }
|
listenPort = 51820;
|
||||||
|
privateKeyFile = config.sops.secrets."wireguard-key".path;
|
||||||
|
ips = [
|
||||||
|
"10.100.0.1/24"
|
||||||
|
"fd28:6691:1921:6299::1/64"
|
||||||
|
];
|
||||||
|
peers = [
|
||||||
|
# mail.test.htw.stura-dresden.de
|
||||||
|
{
|
||||||
|
allowedIPs = [
|
||||||
|
"10.100.0.20/32"
|
||||||
|
];
|
||||||
|
publicKey = "9Ep/YZLbnGEVWHgVmmwq2Sv/8awwGaHdwiSuIUkWtnk=";
|
||||||
}
|
}
|
||||||
|
# proxy.htw.stura-dresden.de
|
||||||
set blacklist6 {
|
{
|
||||||
type ipv6_addr
|
allowedIPs = [
|
||||||
flags interval
|
"10.100.0.2/32"
|
||||||
# manage at runtime: nft add element inet filter blacklist6 { 2001:db8::/32 }
|
"fd28:6691:1921:6299::2/64"
|
||||||
|
];
|
||||||
|
endpoint = "141.56.51.1:51820";
|
||||||
|
publicKey = "pUHtAHCDHVQBnqtlIgTkEMHbxXpQmVA0HhxiFUrUb0U=";
|
||||||
}
|
}
|
||||||
|
];
|
||||||
chain input {
|
};
|
||||||
type filter hook input priority filter; policy drop;
|
};
|
||||||
|
|
||||||
iif "lo" accept
|
|
||||||
ct state established,related accept
|
|
||||||
|
|
||||||
ip saddr @blacklist4 drop
|
|
||||||
ip6 saddr @blacklist6 drop
|
|
||||||
|
|
||||||
tcp dport { 22, 80, 443 } accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain forward {
|
|
||||||
type filter hook forward priority filter; policy drop;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain output {
|
|
||||||
type filter hook output priority filter; policy accept;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -125,50 +133,13 @@
|
||||||
server proxy 141.56.51.1:80
|
server proxy 141.56.51.1:80
|
||||||
backend http_443
|
backend http_443
|
||||||
mode tcp
|
mode tcp
|
||||||
server proxy 141.56.51.1:443 send-proxy-v2
|
server proxy 141.56.51.1:443
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.root.packages = [
|
environment.systemPackages = with pkgs; [
|
||||||
(pkgs.writeShellScriptBin "nft-blacklist" ''
|
wireguard-tools
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo "Usage: nft-blacklist <add|del> <ip-or-cidr>"
|
|
||||||
echo " add - add entry to blacklist set"
|
|
||||||
echo " del - remove entry from blacklist set"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ $# -ne 2 ]] && usage
|
|
||||||
|
|
||||||
ACTION="$1"
|
|
||||||
ADDR="$2"
|
|
||||||
|
|
||||||
if [[ "$ADDR" == *:* ]]; then
|
|
||||||
SET="blacklist6"
|
|
||||||
elif [[ "$ADDR" == *.* ]]; then
|
|
||||||
SET="blacklist4"
|
|
||||||
else
|
|
||||||
echo "Error: cannot determine address family for '$ADDR'" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$ACTION" in
|
|
||||||
add)
|
|
||||||
${pkgs.nftables}/bin/nft add element inet filter "$SET" "{ $ADDR }"
|
|
||||||
echo "Added $ADDR to $SET"
|
|
||||||
;;
|
|
||||||
del)
|
|
||||||
${pkgs.nftables}/bin/nft delete element inet filter "$SET" "{ $ADDR }"
|
|
||||||
echo "Removed $ADDR from $SET"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
'')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
system.stateVersion = "25.11";
|
||||||
|
|
|
||||||
25
hosts/v6proxy/secrets.sops.yml
Normal file
25
hosts/v6proxy/secrets.sops.yml
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
wireguard-key: ENC[AES256_GCM,data:K3UoCWtF2rL8uCzmu8yn4sHKHOrcKmnNBvRQdC9Ph3fWMdDqNqh0jwSByjQ=,iv:feFxNykRK1RJ6EPPVXqXtEVmXeGez4PwJ9h7m1KYUIE=,tag:hSTf/gAUVSjI1GburqRDVA==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age1gl8zmw86jkrkr7kaqugdyhvdhdrnfd72smndz2kfh4a6ec6s9yxsyrecu6
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsbVd3OUNCMUI3eUI2QlVa
|
||||||
|
WFNjVUpXYVlLdUxiSzhQdHhhRWRpWEhzV1IwCkdYMG5DOXBxTnMwNFpYM1FweDNp
|
||||||
|
ZXd2aXJaNWxOYXRnaW1nSjdNQVpQOU0KLS0tIEY4Q1JqV1FSekVwc0prNjRCUDdm
|
||||||
|
cmpLdW1abFR5SlhxZnpJdnBlNjJQOGMK+JcLyiSCfhVPnhqpqTzB7flFWTff3GcK
|
||||||
|
9779AvKVnhsDb5LDPOi4Ah5gAJfq+JZ/+IiTUqk0a4AWuN9PiyTMGA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1qp7w80k3qtj79xsl0gwsfrkm037xrlnhm6th7tcyrvufh3szzp6s2pe7ra
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBncnVRVi91OWsxejJiS0Y0
|
||||||
|
L2licWRJQ1pGTlZOMEM0VHdyOWlFbEgyRENVCmwxSndQamRZM2NKbW14TTI4aFBV
|
||||||
|
MHQ3YkJwNUhkWlJNSTB2RFBpZEswT28KLS0tIC9EVUxvYk04ek5xc1d4TXl5RFVD
|
||||||
|
MkFyQkxCWDdWQjUxQ0QwcjlScGxPWWMKtzYvXoSSPGhVFlwzdtZylu3eTE5EKxqO
|
||||||
|
OIq9IOOujV3K1dzj5uwmCI+EoEasOMLy7Sa4++1WZmRVmVxFa91/gw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2026-03-21T17:41:20Z"
|
||||||
|
mac: ENC[AES256_GCM,data:f94ubkkhUDMkvEPEYYGVg1mahaMmXqAdMcF9Vl16jj7FQTvJy9GCg+1F7eBOu0endpcTQo2a/apd2u7tnzA0IE3CfXo2U8d8aun6yTxxn9qopnxypP2v6mGDHsGbaUI3r+/ZgLXtGDDN+gS/zyu06CPFq/TdLnmcO9zuXAeBmWc=,iv:5VEsRV20A56FKNRQlgojY5TQLhW+kgotQBPgElZY+uQ=,tag:K13Owxl3MDwf5n9soXxiXA==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.12.1
|
||||||
|
|
@ -99,17 +99,6 @@
|
||||||
services.mediawiki.database.passwordFile = "/var/lib/mediawiki/mediawiki-dbpassword";
|
services.mediawiki.database.passwordFile = "/var/lib/mediawiki/mediawiki-dbpassword";
|
||||||
|
|
||||||
|
|
||||||
services.httpd = {
|
|
||||||
extraModules = [ "remoteip" ];
|
|
||||||
|
|
||||||
extraConfig = ''
|
|
||||||
# Trust HAProxy's address (adjust to your HAProxy IP/subnet)
|
|
||||||
RemoteIPProxyProtocol On
|
|
||||||
# RemoteIPProxyProtocolExceptions 127.0.0.1 ::1
|
|
||||||
|
|
||||||
RemoteIPTrustedProxy 141.56.51.1/32
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
#### 2024-02-17 vater:
|
#### 2024-02-17 vater:
|
||||||
#### trace: warning: The option `services.mediawiki.virtualHost' defined in `/etc/nixos/configuration.nix' has been renamed to `services.mediawiki.httpd.virtualHost'.
|
#### trace: warning: The option `services.mediawiki.virtualHost' defined in `/etc/nixos/configuration.nix' has been renamed to `services.mediawiki.httpd.virtualHost'.
|
||||||
# services.mediawiki.virtualHost.hostName = "wiki.stura.htw-dresden.de";
|
# services.mediawiki.virtualHost.hostName = "wiki.stura.htw-dresden.de";
|
||||||
|
|
@ -161,8 +150,8 @@
|
||||||
Lockdown = pkgs.fetchzip {
|
Lockdown = pkgs.fetchzip {
|
||||||
# url = "https://extdist.wmflabs.org/dist/extensions/Lockdown-REL1_43-7ac8966.tar.gz";
|
# url = "https://extdist.wmflabs.org/dist/extensions/Lockdown-REL1_43-7ac8966.tar.gz";
|
||||||
# url = "https://extdist.wmflabs.org/dist/extensions/Lockdown-REL1_44-af1f4df.tar.gz";
|
# url = "https://extdist.wmflabs.org/dist/extensions/Lockdown-REL1_44-af1f4df.tar.gz";
|
||||||
url = "https://extdist.wmflabs.org/dist/extensions/CategoryLockdown-REL1_45-a715472.tar.gz";
|
url = "https://extdist.wmflabs.org/dist/extensions/Lockdown-REL1_45-a46dbea.tar.gz";
|
||||||
sha256 = "sha256-1gl5m9xkmLrdjoR0M13gcQHLtZt4Bt0PUXDiDEqjpvk=";
|
sha256 = "sha256-zTTpbQiqudLILPSzmKGjKr6wZjh0YUttGmqwjPpAToc=";
|
||||||
};
|
};
|
||||||
|
|
||||||
#### Hinzufuegen der Erweiterung ConfirmEdit fuer eine zusaetzliche Bestaetigung bei Bearbeitungen, etwa um Herausforderungen (aka CAPTCHA) zu stellen
|
#### Hinzufuegen der Erweiterung ConfirmEdit fuer eine zusaetzliche Bestaetigung bei Bearbeitungen, etwa um Herausforderungen (aka CAPTCHA) zu stellen
|
||||||
|
|
@ -179,8 +168,8 @@
|
||||||
#### Hinzufuegen der Erweiterung ContributionScores fuer eine Statistik von Beitraegen nach Beitragenden
|
#### Hinzufuegen der Erweiterung ContributionScores fuer eine Statistik von Beitraegen nach Beitragenden
|
||||||
#### https://www.mediawiki.org/wiki/Extension:ContributionScores
|
#### https://www.mediawiki.org/wiki/Extension:ContributionScores
|
||||||
ContributionScores = pkgs.fetchzip {
|
ContributionScores = pkgs.fetchzip {
|
||||||
url = "https://extdist.wmflabs.org/dist/extensions/ContributionCredits-REL1_45-22c28de.tar.gz";
|
url = "https://extdist.wmflabs.org/dist/extensions/ContributionScores-REL1_45-cd4c94b.tar.gz";
|
||||||
sha256 = "sha256-9T67jCEYQyU7P9sN7tYbnevU5+FX6Y1nydXGEdzQS9k=";
|
sha256 = "sha256-8ClNtEQ66deKM1DsRYaaZ3KlRl4yCt6UhpXcozRQzQ8=";
|
||||||
};
|
};
|
||||||
|
|
||||||
#### Hinzufuegen der Erweiterung Interwiki fuer das Verwenden von Verweisen als eine Art Namensraum, wie beispielweise auf Wikipedia oder selbst festgelegte Verweise
|
#### Hinzufuegen der Erweiterung Interwiki fuer das Verwenden von Verweisen als eine Art Namensraum, wie beispielweise auf Wikipedia oder selbst festgelegte Verweise
|
||||||
|
|
@ -201,8 +190,8 @@
|
||||||
#### https://www.mediawiki.org/wiki/Extension:UserMerge
|
#### https://www.mediawiki.org/wiki/Extension:UserMerge
|
||||||
UserMerge = pkgs.fetchzip {
|
UserMerge = pkgs.fetchzip {
|
||||||
# url = "https://extdist.wmflabs.org/dist/extensions/UserMerge-REL1_43-ed4a689.tar.gz";
|
# url = "https://extdist.wmflabs.org/dist/extensions/UserMerge-REL1_43-ed4a689.tar.gz";
|
||||||
url = "https://extdist.wmflabs.org/dist/extensions/UserMerge-REL1_45-433f6c2.tar.gz";
|
url = "https://extdist.wmflabs.org/dist/extensions/UserMerge-REL1_45-446566b.tar.gz";
|
||||||
sha256 = "sha256-JyY4pJNBKQ9bOKrilPWCheZ5ihWwPM6ZJ0qHsZ3coPk=";
|
sha256 = "sha256-DTDKlzet3lThh/sRLucyb8b9lhK5FYZ+dMgwrThFFBM=";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
{ pkgs, lib, config, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.stura.monitoring;
|
|
||||||
in {
|
|
||||||
options.stura.monitoring = {
|
|
||||||
extraLogFiles = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [];
|
|
||||||
description = "Additional log file paths for vector to scrape and forward to Loki.";
|
|
||||||
example = [ "/var/log/nginx/access.log" "/var/log/nginx/error.log" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
extraGroups = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [];
|
|
||||||
description = "Supplementary groups added to the vector systemd service to allow reading protected log files.";
|
|
||||||
example = [ "nginx" "postfix" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
extraMetricInputs = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [];
|
|
||||||
description = "Additional vector component IDs to feed into the mimir sink alongside host_metrics.";
|
|
||||||
example = [ "proxmox_normalize_metrics" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
extraLogInputs = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [];
|
|
||||||
description = "Additional vector component IDs to feed into the loki sink alongside journald_logs.";
|
|
||||||
example = [ "proxmox_normalize_logs" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
networking.hosts = {
|
|
||||||
# rewrite these host entries on each system, this does not go through proxy
|
|
||||||
"141.56.51.20" = [
|
|
||||||
"mon.adm.htw.stura-dresden.de"
|
|
||||||
"log.adm.htw.stura-dresden.de"
|
|
||||||
"met.adm.htw.stura-dresden.de"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
services.vector = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
sources = {
|
|
||||||
host_metrics = {
|
|
||||||
type = "host_metrics";
|
|
||||||
collectors = [
|
|
||||||
"cpu"
|
|
||||||
"disk"
|
|
||||||
"filesystem"
|
|
||||||
"load"
|
|
||||||
"host"
|
|
||||||
"memory"
|
|
||||||
"network"
|
|
||||||
"process"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
journald_logs = {
|
|
||||||
type = "journald";
|
|
||||||
include_units = []; # empty = collect all units
|
|
||||||
};
|
|
||||||
} // lib.optionalAttrs (cfg.extraLogFiles != [] || config.services.nginx.enable) {
|
|
||||||
extra_log_files = {
|
|
||||||
type = "file";
|
|
||||||
include = lib.optional config.services.nginx.enable "/var/log/nginx/access.log"
|
|
||||||
++ cfg.extraLogFiles;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
transforms = {
|
|
||||||
add_host_label_metrics = {
|
|
||||||
type = "remap";
|
|
||||||
inputs = [ "host_metrics" ];
|
|
||||||
source = ''
|
|
||||||
.tags.host = get_hostname!()
|
|
||||||
del(.tags.command)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
add_host_label_logs = {
|
|
||||||
type = "remap";
|
|
||||||
inputs = [ "journald_logs" ] ++ lib.optional (cfg.extraLogFiles != [] || config.services.nginx.enable) "extra_log_files";
|
|
||||||
source = ''
|
|
||||||
.host = get_hostname!()
|
|
||||||
.unit = string(."_SYSTEMD_UNIT") ?? "file"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sinks = {
|
|
||||||
mimir = {
|
|
||||||
type = "prometheus_remote_write";
|
|
||||||
inputs = [ "add_host_label_metrics" ] ++ cfg.extraMetricInputs;
|
|
||||||
endpoint = "https://met.adm.htw.stura-dresden.de/api/v1/push";
|
|
||||||
tls.verify_certificate = false;
|
|
||||||
healthcheck.enabled = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
loki = {
|
|
||||||
type = "loki";
|
|
||||||
inputs = [ "add_host_label_logs" ] ++ cfg.extraLogInputs;
|
|
||||||
endpoint = "https://log.adm.htw.stura-dresden.de";
|
|
||||||
labels = {
|
|
||||||
host = "{{ host }}";
|
|
||||||
unit = "{{ unit }}";
|
|
||||||
};
|
|
||||||
tls.verify_certificate = false;
|
|
||||||
encoding.codec = "json";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.vector.serviceConfig.SupplementaryGroups =
|
|
||||||
[ "systemd-journal" ]
|
|
||||||
++ lib.optional config.services.nginx.enable "nginx"
|
|
||||||
++ cfg.extraGroups;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue