summaryrefslogtreecommitdiff
path: root/Omni/Cloud/Web.nix
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2024-11-15 14:55:37 -0500
committerBen Sima <ben@bsima.me>2024-12-21 10:06:49 -0500
commit6513755670892983db88a6633b8c1ea6019c03d1 (patch)
tree44e9eccdb7a3a74ab7e96a8fee7572dd6a78dc73 /Omni/Cloud/Web.nix
parentae7b7e0186b5f2e0dcd4d5fac0a71fa264caedc2 (diff)
Re-namespace some stuff to Omni
I was getting confused about what is a product and what is internal infrastructure; I think it is good to keep those things separate. So I moved a bunch of stuff to an Omni namespace, actually most stuff went there. Only things that are explicitly external products are still in the Biz namespace.
Diffstat (limited to 'Omni/Cloud/Web.nix')
-rw-r--r--Omni/Cloud/Web.nix303
1 files changed, 303 insertions, 0 deletions
diff --git a/Omni/Cloud/Web.nix b/Omni/Cloud/Web.nix
new file mode 100644
index 0000000..0e080f5
--- /dev/null
+++ b/Omni/Cloud/Web.nix
@@ -0,0 +1,303 @@
+{ 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}";
+ };
+
+ "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" ] ++ 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"
+ ];
+}