{ config, lib, ... }: { # Catch-all default server: drop connections from bots/scanners hitting # by IP or unknown Host header. Without this, the alphabetically first # vhost (audiobooks) becomes the implicit default — and its @nas_wake # error handler wakes the NAS on every random internet probe. services.nginx.virtualHosts."_" = { default = true; rejectSSL = true; extraConfig = '' return 444; ''; }; services.nginx.virtualHosts."git.cloonar.com" = { forceSSL = true; enableACME = true; acmeRoot = null; locations."/" = { proxyPass = "http://${config.networkPrefix}.97.55:3001/"; proxyWebsockets = true; }; }; services.nginx.virtualHosts."foundry-vtt.cloonar.com" = { forceSSL = true; enableACME = true; acmeRoot = null; locations."/" = { proxyPass = "http://${config.networkPrefix}.97.21:30000"; proxyWebsockets = true; }; }; services.nginx.virtualHosts."sync.cloonar.com" = { forceSSL = true; enableACME = true; acmeRoot = null; locations."/" = { proxyPass = "http://${config.networkPrefix}.97.6:5000"; recommendedProxySettings = true; }; }; services.nginx.virtualHosts."fivefilters.cloonar.com" = { forceSSL = true; enableACME = true; acmeRoot = null; locations."/" = { proxyPass = "http://${config.networkPrefix}.97.10"; }; }; services.nginx.virtualHosts."dl.cloonar.com" = { forceSSL = true; enableACME = true; acmeRoot = null; # Restrict to internal LAN only extraConfig = '' allow ${config.networkPrefix}.96.0/24; allow ${config.networkPrefix}.97.0/24; allow ${config.networkPrefix}.98.0/24; deny all; proxy_connect_timeout 3s; error_page 502 504 = @nas_wake; ''; locations."/" = { proxyPass = "http://${config.networkPrefix}.97.11:8000"; proxyWebsockets = true; }; locations."@nas_wake" = { proxyPass = "http://${config.networkPrefix}.97.1:9800"; }; }; services.nginx.virtualHosts."jellyfin.cloonar.com" = { forceSSL = true; enableACME = true; acmeRoot = null; extraConfig = '' proxy_connect_timeout 3s; error_page 502 504 = @nas_wake; ''; locations."/" = { proxyPass = "http://${config.networkPrefix}.97.11:8096"; proxyWebsockets = true; extraConfig = '' # Jellyfin-specific headers for proper streaming proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $http_host; # Disable buffering for better streaming performance proxy_buffering off; ''; }; locations."@nas_wake" = { proxyPass = "http://${config.networkPrefix}.97.1:9800"; }; }; services.nginx.virtualHosts."audiobooks.cloonar.com" = { forceSSL = true; enableACME = true; acmeRoot = null; extraConfig = '' proxy_connect_timeout 3s; error_page 502 504 = @nas_wake; ''; locations."/" = { proxyPass = "http://${config.networkPrefix}.97.11:13378"; proxyWebsockets = true; extraConfig = '' proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $http_host; # Disable buffering for better streaming performance proxy_buffering off; ''; }; locations."@nas_wake" = { proxyPass = "http://${config.networkPrefix}.97.1:9800"; }; }; services.nginx.virtualHosts."moltbot.cloonar.com" = { forceSSL = true; enableACME = true; acmeRoot = null; # Restrict to internal networks only (LAN + VPN) extraConfig = '' allow ${config.networkPrefix}.96.0/24; allow ${config.networkPrefix}.97.0/24; allow ${config.networkPrefix}.98.0/24; deny all; ''; locations."/" = { proxyPass = "http://${config.networkPrefix}.97.60:18789"; extraConfig = '' proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; ''; }; }; }