diff --git a/machines/moritz-server/configuration.nix b/machines/moritz-server/configuration.nix index b4b3136..a2e4b52 100644 --- a/machines/moritz-server/configuration.nix +++ b/machines/moritz-server/configuration.nix @@ -3,6 +3,8 @@ ../../modules/zfs_unencrypted.nix ../../modules/shared.nix ../../modules/moritz/shared.nix + ./reverse-proxy.nix + ./ddns.nix ]; time.timeZone = "Europe/Berlin"; diff --git a/machines/moritz-server/ddns.nix b/machines/moritz-server/ddns.nix new file mode 100644 index 0000000..c1ef44a --- /dev/null +++ b/machines/moritz-server/ddns.nix @@ -0,0 +1,32 @@ +{ + config, + pkgs, + inputs, + ... +}: { + services.ddns-updater = { + enable = true; + package = inputs.stable.legacyPackages.${pkgs.system}.ddns-updater; + environment = { + # LOG_LEVEL = "debug"; + CONFIG_FILEPATH = config.clan.core.vars.generators.ddns-updater-conf.files."config.json".path; + }; + }; + systemd.services.ddns-updater = { + serviceConfig = { + User = "ddns-updater"; + Group = "ddns-updater"; + }; + }; + users.users.ddns-updater = { + name = "ddns-updater"; + group = "ddns-updater"; + isSystemUser = true; + }; + users.groups.ddns-updater = {}; + clan.core.vars.generators.ddns-updater-conf.prompts."config.json" = { + persist = true; + type = "multiline"; + }; + clan.core.vars.generators.ddns-updater-conf.files."config.json".owner = "ddns-updater"; +} diff --git a/machines/moritz-server/reverse-proxy.nix b/machines/moritz-server/reverse-proxy.nix new file mode 100644 index 0000000..a265d2c --- /dev/null +++ b/machines/moritz-server/reverse-proxy.nix @@ -0,0 +1,125 @@ +{config, ...}: { + services.fail2ban = { + enable = true; + bantime-increment.enable = true; + jails = let + nginx_error_log = "/var/log/nginx/access.log"; + in { + nginx-botsearch.settings = { + enabled = true; + port = "http,https"; + filter = "nginx-botsearch"; + backend = "auto"; + logpath = nginx_error_log; + }; + nginx-forbidden.settings = { + enabled = true; + port = "http,https"; + filter = "nginx-forbidden"; + backend = "auto"; + logpath = nginx_error_log; + }; + nginx-http-auth.settings = { + enabled = true; + port = "http,https"; + filter = "nginx-http-auth"; + backend = "auto"; + logpath = nginx_error_log; + }; + nginx-4xx.settings = { + enabled = true; + port = "http,https"; + filter = "nginx-4xx"; + backend = "auto"; + logpath = nginx_error_log; + }; + }; + ignoreIP = [ + "192.168.0.0/24" + ]; + }; + environment.etc = { + "fail2ban/filter.d/nginx-4xx.conf".text = '' + [Definition] + failregex = ^.*"(GET|POST).*" (404|444|403|400) .*$ + + ignoreregex = .*(robots.txt|favicon.ico|jpg|png) + + journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx + ''; + }; + + networking.firewall.allowedTCPPorts = [80 1443 443]; + services.nginx = { + enable = true; + logError = "stderr info"; + recommendedProxySettings = true; + virtualHosts = { + "moritzboeh.me" = { + serverAliases = ["*.moritzboeh.me"]; + locations."/" = { + proxyPass = "http://192.168.0.6"; + }; + }; + "moritz.foo" = { + forceSSL = true; + useACMEHost = "moritz.foo"; + locations."/" = { + return = "301 https://www.moritz.foo"; + }; + }; + "www.moritz.foo" = { + forceSSL = true; + useACMEHost = "any.moritz.foo"; + locations."/" = { + extraConfig = '' + add_header Content-Type text/html; + ''; + return = "200 'Hello World'"; + }; + }; + }; + streamConfig = '' + upstream diskstation { + server 192.168.0.6:443; + } + + upstream self { + server 127.0.0.1:443; + } + + map $ssl_preread_server_name $name { + hostnames; + .moritz.foo self; + .moritzboeh.me diskstation; + } + + server { + listen 1443; + ssl_preread on; + proxy_pass $name; + } + ''; + }; + + security.acme = { + acceptTerms = true; + defaults.email = "acme@moritzboeh.me"; + defaults.dnsResolver = "1.1.1.1:53"; + certs."moritz.foo" = { + dnsProvider = "cloudflare"; + group = "nginx"; + environmentFile = config.clan.core.vars.generators.acme.files.vars.path; + }; + certs."any.moritz.foo" = { + domain = "*.moritz.foo"; + dnsProvider = "cloudflare"; + group = "nginx"; + environmentFile = config.clan.core.vars.generators.acme.files.vars.path; + }; + }; + clan.core.vars.generators.acme.prompts.vars = { + persist = true; + type = "multiline"; + }; +} diff --git a/vars/per-machine/moritz-server/acme/vars/machines/moritz-server b/vars/per-machine/moritz-server/acme/vars/machines/moritz-server new file mode 120000 index 0000000..f18ca49 --- /dev/null +++ b/vars/per-machine/moritz-server/acme/vars/machines/moritz-server @@ -0,0 +1 @@ +../../../../../../sops/machines/moritz-server \ No newline at end of file diff --git a/vars/per-machine/moritz-server/acme/vars/secret b/vars/per-machine/moritz-server/acme/vars/secret new file mode 100644 index 0000000..5484887 --- /dev/null +++ b/vars/per-machine/moritz-server/acme/vars/secret @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data:nXGv5y5uiqtGFTEz2m0J0uY61xC+rHV+rygJi7IEM9IYjBSdl1BBuvStNMhBJQ+6pKzJrj+H4eplEA==,iv:kz93P9IDxwRlF7eJAoJ/f90H7+FWYW9KeCsUYvwpB/w=,tag:zZphQDNof82LRTWUgJPDlw==,type:str]", + "sops": { + "age": [ + { + "recipient": "age12jlzcjwwhtgws4ku4nemwknsps3a6um74kdpxfv9pzvgdlhufp8q08c0j7", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5cUxHVUY3N2NBNUFhTjVQ\nL2Q0YjVBNlY0WnovUUpzZmp2Q1h4WGFaMUI0Cm5nZlJocGs2VkNoZzVMc245bXVD\nQ1l1QzNHZHFKMjQ2UzlzYjhLbkNVQWsKLS0tIEVya3dpOTlRNDRIRVdOSTN0V3dS\nVWVMN0JBdmh0d25NNHBDVEQyeFpTMEkKY2BE6JZ+4IAfUl1FamH3W9EfXwfCFi+U\nbg1UJpMqw6pii+XbnLb3WUYZck6JRtyDLvdEPdoI+wTFD08463p83g==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1wwlwwv9gscl9z6k59z6pp8hcay7vehvqp6y5f85pjyd9seqe8s0q5dkmr4", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtbGxvK2lFSnFLM2RoSG9K\nekZ5VjdmYmwyUWtFK241WVF6YjhWZEZJdGxZCnpXMnp6YndvdlF2RzJManVXbjZV\nR3g3KytUUU9kdmIxRU5LSVZPaHYwMlkKLS0tIDhmejhEcit2YmVrNFp5eFgrbDls\nV2pNZUg3U293Z0hMRytyRExQRmE0aUkKNqaT6R5IDw6I9IXGsKcUsem04XQSTmCU\nW8iAehs524XzGE4+6SERDM1qrfKno1vJpmS2qG8/s1HicycjmMfQRw==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-05-14T11:49:53Z", + "mac": "ENC[AES256_GCM,data:9faPbY2mUIp/A1oDqan4cpadJah30PpGZ2feFPohCn9Gy/xYYjqhqEwIpjvwf+MRCvqdC6n4jvOT8AVUHiwrtr19/In2CWpPMrFsw08nCzO9L9TJAfDnqYLdqtdHF3DgEFIzy0wi5iSRe5/lo79GW8uMdS7ULf4T26WKfGzsk6o=,iv:w2OXdQH1mB+NvAJedYmtkDU2m0HywnCEP1MMhHh8lW8=,tag:XYitYG0iDpPbWjShOW+icg==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/vars/per-machine/moritz-server/acme/vars/users/moritz b/vars/per-machine/moritz-server/acme/vars/users/moritz new file mode 120000 index 0000000..1b45802 --- /dev/null +++ b/vars/per-machine/moritz-server/acme/vars/users/moritz @@ -0,0 +1 @@ +../../../../../../sops/users/moritz \ No newline at end of file diff --git a/vars/per-machine/moritz-server/ddns-updater-conf/config.json/machines/moritz-server b/vars/per-machine/moritz-server/ddns-updater-conf/config.json/machines/moritz-server new file mode 120000 index 0000000..f18ca49 --- /dev/null +++ b/vars/per-machine/moritz-server/ddns-updater-conf/config.json/machines/moritz-server @@ -0,0 +1 @@ +../../../../../../sops/machines/moritz-server \ No newline at end of file diff --git a/vars/per-machine/moritz-server/ddns-updater-conf/config.json/secret b/vars/per-machine/moritz-server/ddns-updater-conf/config.json/secret new file mode 100644 index 0000000..1245742 --- /dev/null +++ b/vars/per-machine/moritz-server/ddns-updater-conf/config.json/secret @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data:xAfwazWdkDc86yIcFWuuBoyrGA/lFHzT6AKAGy691zM5Um6QAREZo7gCyuGLmRs5zu5mDkg4M5xAYwja0PYOfWvBiOLcYdFwzeeYqfFv7B9FSwGCn45EIRhFZOJH4VXaZDUDTsNN5RgwJbjl9d4exveJr8a0XBVZzIn/OK6tT2VnBcTRFw3Wd7LoVwXl/gXaHD9G8DTgJLmH16zRnvFw2o33ykRItHo5mfpkRJiX1Wv432ir9WOmUN5DOVYAXQrBdk9llId3hURqhWfPcysJzpESJBK8EdnkSq0PBJRTmRo+kMxXhVKCph0r9Pzg1zJxzChr28ZNWD2aumF0O59uNc7+XE7o4dd3eMK1sQ21VkRScgeJTTGtYxbMXEMplO2+yPw=,iv:x0ALrHu5i9UAn2nA2WcckOqBVBcOmLzIgvwS5ZADXSA=,tag:Y5agVeJwMFrikJrXZ3UtiQ==,type:str]", + "sops": { + "age": [ + { + "recipient": "age12jlzcjwwhtgws4ku4nemwknsps3a6um74kdpxfv9pzvgdlhufp8q08c0j7", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDbTBrRzFxeDBLaWFHcWpa\nRUl2d1l3OTVhVkZvKzd2NW9lb0c5UjI1ZkJRCm5oSVV2TXdya0NhOG5qUm04NXdH\nek9nYjdtTVhHTHhuTjJGZk9jOWhUQlkKLS0tIEV2NFNCdEFuWCtONmMyYnYxdE5n\nTDJlSnlUY3g2WkxWWXBBZXZudWJnd1UKKYHj7q6Vto5+fSfZyi4Gw4kTBcP+aMzX\nmGbYPi5Gik9EU8AIrB0tD5H3D/ZSD2N0I3AfIgLlC69wcYxlf8XtnA==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1wwlwwv9gscl9z6k59z6pp8hcay7vehvqp6y5f85pjyd9seqe8s0q5dkmr4", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWZHdKb0MzdHA1MzNJVFhs\nNU44a0tGYTlCbXI4bU5wTDAwcEF6RThXb1ZBCk9iWnFQRFpqK3J1ZEMxd1Z2Ymdt\nNGVidjE3OWl6Nm4rL01SVi90NjlyVHMKLS0tIG9RUURLSVd6bUhNbE1kNFVRanFV\nQzZMUmNkNTlHNmtwR2xzL2laZzZVMFEKYTj14fT03nW+RGKlCdKtffA31tRBMnuo\nY/6SAAWGm0pqUP0mGT4hKr/5bSmFcMoTEy64LVBkWU0dd2dIn5urCA==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-05-14T11:53:23Z", + "mac": "ENC[AES256_GCM,data:Eq8h9tW+T8Fcl4/jYKC52xGZAGs5DR9vsYBYdCAfTmoz4HfowA/zfn7QY8Yqn3Mf3ifh7uUZD2GyEq3E3v18VZe6yTRlTsVsC1pm1Jl6lN1OXOOV/kowcsLE8o7mRMrGqSozjRYVZUwzaR49B1vPYwX44rpNLQmie+BCZBCNI8M=,iv:Y8BMtJzQryO3tepaAPgWI7ngdKKGLF0rrlyQWLF3n4E=,tag:r9nmFgzDmaxJaF8gOuZhKA==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/vars/per-machine/moritz-server/ddns-updater-conf/config.json/users/moritz b/vars/per-machine/moritz-server/ddns-updater-conf/config.json/users/moritz new file mode 120000 index 0000000..1b45802 --- /dev/null +++ b/vars/per-machine/moritz-server/ddns-updater-conf/config.json/users/moritz @@ -0,0 +1 @@ +../../../../../../sops/users/moritz \ No newline at end of file