{ config, ... }: let rootDomain = config.networking.domain; ports = import ./Ports.nix; in { imports = [ ./Gmnisrv.nix ]; networking.firewall = { allowedTCPPorts = [ ports.ssh ports.git ports.http ports.https ports.sabten ports.gemini ports.radicale ports.znc ports.gerrit-ssh ]; }; services = { libreddit = { enable = true; address = "127.0.0.1"; openFirewall = true; port = ports.libreddit; }; invidious = { enable = true; database.createLocally = true; domain = "youtube.${rootDomain}"; nginx.enable = false; # do this myself, below port = ports.invidious; }; radicale = { enable = true; rights = { # Allow reading root collection for authenticated users root = { user = ".+"; collection = ""; permissions = "R"; }; # Allow reading and writing principal collection (same as username) principal = { user = ".+"; collection = "{user}"; permissions = "RW"; }; # Allow reading and writing calendars and address books that are direct # children of the principal collection calendars = { user = ".+"; collection = "{user}/[^/]+"; permissions = "rw"; }; # Allow any authenticated user to modify the public collection public = { user = ".*"; collection = "public/.*"; permissions = "rw"; }; }; settings = { server = { hosts = [ "0.0.0.0:${toString ports.radicale}" "[::]:${toString ports.radicale}" ]; }; auth = { type = "htpasswd"; htpasswd_filename = "/etc/radicale/users"; htpasswd_encryption = "plain"; }; }; }; gmnisrv = { enable = false; listen = "0.0.0.0:${toString ports.gemini} [::]:${toString ports.gemini}"; settings = { ":tls" = { store = "/var/lib/gmnisrv"; }; "bsima.me" = { "root" = "/var/web/ben"; }; "${rootDomain}" = { "root" = "/var/web/simatime.com"; "cgi" = "on"; }; }; }; nginx = { enable = true; recommendedGzipSettings = true; recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; statusPage = true; user = "nginx"; group = "nginx"; virtualHosts = { ${rootDomain} = { forceSSL = true; enableACME = true; locations = { # the nginx/cgit module puts a '/' at the end of 'location', so we need to # redirect '/git' to '/git/' "/git".return = "301 https://$host/git/"; # nostr nip-5 verification "/.well-known/nostr.json".return = "200 '${ builtins.toJSON { names.bensima = "2fa4b9ba71b6dab17c4723745bb7850dfdafcb6ae1a8642f76f9c64fa5f43436"; } }'"; # disabled for nixpert test "/" = { root = "/var/web/simatime.com"; extraConfig = '' autoindex on; ''; }; # serve /~$USER paths "~ ^/~(.+?)(/.*)?$" = { alias = "/var/web/$1$2"; index = "index.html index.htm"; extraConfig = '' autoindex on; ''; }; }; }; "bsima.me" = { locations."/" = { root = "/var/web/ben"; index = "index.html index.htm"; extraConfig = '' autoindex on; ''; }; serverAliases = [ "www.bsima.me" ]; forceSSL = true; useACMEHost = rootDomain; }; "hoogle.${rootDomain}" = { locations."/".proxyPass = "http://${ports.bensIp}:${toString ports.hoogle}"; forceSSL = true; useACMEHost = rootDomain; }; "tv.${rootDomain}" = { locations."/".proxyPass = "http://${ports.bensIp}:${toString ports.jellyfin}"; forceSSL = true; useACMEHost = rootDomain; }; "cal.${rootDomain}" = { locations."/".proxyPass = "http://localhost:${toString ports.radicale}"; forceSSL = true; useACMEHost = rootDomain; extraConfig = '' proxy_set_header X-Script-Name /radicale; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_pass_header Authorization; ''; }; "reddit.${rootDomain}" = { locations."/".proxyPass = "http://localhost:${toString ports.libreddit}"; forceSSL = true; useACMEHost = rootDomain; }; "www.reddit.${rootDomain}" = { forceSSL = true; useACMEHost = rootDomain; globalRedirect = "reddit.${rootDomain}"; }; "old.reddit.${rootDomain}" = { forceSSL = true; useACMEHost = rootDomain; globalRedirect = "reddit.${rootDomain}"; }; "youtube.${rootDomain}" = { locations."/".proxyPass = "http://localhost:${toString ports.invidious}"; forceSSL = true; useACMEHost = rootDomain; }; "www.youtube.${rootDomain}" = { forceSSL = true; useACMEHost = rootDomain; globalRedirect = "youtube.${rootDomain}"; }; "m.youtube.${rootDomain}" = { forceSSL = true; useACMEHost = rootDomain; globalRedirect = "youtube.${rootDomain}"; }; "dragons.dev" = { locations."/".proxyPass = "http://${ports.bensIp}:${toString ports.dragons}"; forceSSL = true; useACMEHost = rootDomain; }; "dandel-rovbur.${rootDomain}" = { locations."/".proxyPass = "http://${ports.bensIp}:${toString ports.dandel-rovbur}"; forceSSL = true; useACMEHost = rootDomain; }; "sabten.${rootDomain}" = { locations."/".proxyPass = "http://localhost:${toString ports.sabten}"; forceSSL = true; useACMEHost = rootDomain; }; "sd.${rootDomain}" = { forceSSL = true; useACMEHost = rootDomain; locations."/" = { proxyPass = "http://${ports.bensIp}:${toString ports.stableDiffusion}"; proxyWebsockets = true; }; }; "music.${rootDomain}" = { forceSSL = true; useACMEHost = rootDomain; locations."/".proxyPass = "http://localhost:${toString ports.botamusique}"; }; "nostr.${rootDomain}" = { forceSSL = true; useACMEHost = rootDomain; locations."/" = { proxyPass = "http://localhost:${toString ports.nostr-relay}"; extraConfig = '' proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; ''; }; }; "notebook.${rootDomain}" = { forceSSL = true; useACMEHost = rootDomain; locations = { "/" = { proxyPass = "http://${ports.bensIp}:${toString ports.jupyter}"; proxyWebsockets = true; extraConfig = '' proxy_buffering off; proxy_read_timeout 86400; ''; }; "/(api/kernels/[^/]+/channels|terminals/websocket)/" = { proxyPass = "http://${ports.bensIp}:${toString ports.jupyter}"; proxyWebsockets = true; }; }; }; }; }; }; # This must contain all of the other domains we host security.acme.certs.${rootDomain}.extraDomainNames = [ "bsima.me" "www.bsima.me" "dragons.dev" ] ++ map (sub: "${sub}.${rootDomain}") [ "music" "tv" "matrix" "chat" "hoogle" "dandel-rovbur" "sabten" "cal" "notebook" "nostr" "reddit" "old.reddit" "www.reddit" "youtube" "www.youtube" "m.youtube" "sd" "gerrit" ]; }