{ config, pkgs, modulesPath, lib, system, ... }: { config = { homelab.virtualisation.guest.enable = true; networking = { hostName = "Ingress"; hostId = "aaaa1000"; domain = "depeuter.dev"; enableIPv6 = true; useDHCP = false; defaultGateway = { address = "192.168.0.1"; interface = "ens18"; }; interfaces.ens18 = { ipv4.addresses = [ { address = "192.168.0.10"; prefixLength = 24; } ]; }; nameservers = [ "1.1.1.1" # Cloudflare "1.0.0.1" # Cloudflare ]; firewall = { enable = true; allowedTCPPorts = [ 80 # HTTP 443 # HTTPS ]; }; }; security.acme = { acceptTerms = true; defaults = { inherit (config.services.nginx) group; dnsPropagationCheck = true; dnsProvider = "cloudflare"; dnsResolver = "1.1.1.1:53"; email = "tibo.depeuter@telenet.be"; credentialFiles = { CLOUDFLARE_DNS_API_TOKEN_FILE = "/var/lib/secrets/depeuter-dev-cloudflare-api-token"; }; reloadServices = [ "nginx" ]; }; certs = { "depeuter.dev" = { domain = "depeuter.dev"; extraDomainNames = [ "*.depeuter.dev" ]; }; "cloud.depeuter.dev" = { }; "git.depeuter.dev" = { }; "home.depeuter.dev" = { }; "jelly.depeuter.dev" = { }; "vault.depeuter.dev" = { }; }; }; # List services that you want to enable. services = { # Enable Nginx as a reverse proxy nginx = { enable = true; # Use recommended settings # recommendedGzipSettings = true; # recommendedOptimisation = true; # recommendedProxySettings = true; # recommendedTlsSettings = true; # Only allow PFS-enabled ciphers with AES256 sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; upstreams.docservice.servers."192.168.0.14:8080" = {}; appendHttpConfig = '' map $http_x_forwarded_proto $the_scheme { default $http_x_forwarded_proto; "" $scheme; } map $http_x_forwarded_host $the_host { default $http_x_forwarded_host; "" $host; } map $http_upgrade $proxy_connection { default upgrade; "" close; } ''; # Define hosts virtualHosts = { # Disable automatic routing. "default" = { locations."/".return = "301 https://youtu.be/dQw4w9WgXcQ"; default = true; }; "cloud.depeuter.dev" = { enableACME = true; forceSSL = true; locations = { "/" = { proxyPass = "http://192.168.0.14"; extraConfig = '' add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; fastcgi_request_buffering off; ''; }; "/office/" = { proxyPass = "http://192.168.0.14:8080/"; priority = 500; recommendedProxySettings = false; extraConfig = '' proxy_http_version 1.1; ''; }; }; extraConfig = '' client_max_body_size 10G; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection; proxy_set_header X-Forwarded-Host $the_host/office; proxy_set_header X-Forwarded-Proto $the_scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ''; }; "calendar.depeuter.dev" = { useACMEHost = "depeuter.dev"; locations."/".return = "301 https://cloud.depeuter.dev/apps/calendar"; }; "tasks.depeuter.dev".locations."/".return = "301 https://cloud.depeuter.dev/apps/tasks"; "notes.depeuter.dev".locations."/".return = "301 https://cloud.depeuter.dev/apps/notes"; "home.depeuter.dev" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://192.168.0.21:8123"; extraConfig = '' proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; ''; }; }; "jelly.depeuter.dev" = { enableACME = true; forceSSL = true; locations = { "/" = { proxyPass = "http://192.168.0.94:8096"; extraConfig = '' # Proxy main Jellyfin traffic 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; proxy_set_header X-Forwarded-Protocol $scheme; proxy_set_header X-Forwarded-Host $http_host; # Disable buffering when the nginx proxy gets very resource heavy upon streaming proxy_buffering off; ''; }; "/socket" = { proxyPass = "http://192.168.0.91:8096"; extraConfig = '' # Proxy Jellyfin Websockets traffic 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; proxy_set_header X-Forwarded-Protocol $scheme; proxy_set_header X-Forwarded-Host $http_host; ''; }; }; extraConfig = '' client_max_body_size 512M; # Security / XSS Mitigation Headers # NOTE: X-Frame-Options may cause issues with the webOS app add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; # Permissions policy. May cause issues with some clients add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; # Content Security Policy # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP # Enforces https content and restricts JS/CSS to origin # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. # NOTE: The default CSP headers may cause issues with the webOS app add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'"; ''; }; "git.depeuter.dev" = { enableACME = true; forceSSL = true; locations."/".proxyPass = "http://192.168.0.24:3000"; extraConfig = '' proxy_set_header Connection $http_connection; proxy_set_header Upgrade $http_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; client_max_body_size 10G; keepalive_timeout 600s; proxy_buffers 4 256k; # Number and size of buffers for reading response proxy_buffer_size 256k; # Buffer for the first part of the response proxy_busy_buffers_size 256k; # Max size of busy buffers proxy_http_version 1.1; proxy_read_timeout 600s; proxy_temp_file_write_size 256k; # Size of temp file for large responses ''; }; "vault.depeuter.dev" = { enableACME = true; forceSSL = true; locations = { "/" = { proxyPass = "http://192.168.0.22:10102"; proxyWebSockets = true; }; "~ ^/admin".return = 403; }; }; "rss.depeuter.dev" = { enableACME = true; forceSSL = true; locations."/".proxyPass = "http://192.168.92:${toString config.homelab.apps.freshrss.port}"; }; }; }; }; system.stateVersion = "24.05"; }; }