diff --git a/hosts/by-name/servo/services/ejabberd.nix b/hosts/by-name/servo/services/ejabberd.nix index 91e59696..2ef36de1 100644 --- a/hosts/by-name/servo/services/ejabberd.nix +++ b/hosts/by-name/servo/services/ejabberd.nix @@ -40,6 +40,9 @@ let turnPortHigh = 49167; turnPortRange = lib.range turnPortLow turnPortHigh; in +# XXX(2023/10/15): disabled in favor of Prosody. +# everything configured below was fine: used ejabberd for several months. +lib.mkIf false { sane.persist.sys.plaintext = [ { user = "ejabberd"; group = "ejabberd"; path = "/var/lib/ejabberd"; } diff --git a/hosts/by-name/servo/services/prosody.nix b/hosts/by-name/servo/services/prosody.nix index 12def62e..7c62b548 100644 --- a/hosts/by-name/servo/services/prosody.nix +++ b/hosts/by-name/servo/services/prosody.nix @@ -1,13 +1,43 @@ # example configs: -# - +# - official: +# - nixos: +# config options: +# - +# +# modules: +# - main: +# - community: +# # create users with: # - `sudo -u prosody prosodyctl adduser colin@uninsane.org` +# sanity checks: +# - `sudo -u prosody -g prosody prosodyctl check connectivity` +# - `sudo -u prosody -g prosody prosodyctl check turn` +# - `sudo -u prosody -g prosody prosodyctl check` (dns, config, certs) +# +# federation/support matrix: +# - nixnet.services (runs ejabberd): +# - WORKS: sending and receiving PMs and calls (2023/10/15) +# - N.B.: it didn't originally work; was solved by disabling the lua-unbound DNS option & forcing the system/local resolver +# - cheogram (XMPP <-> SMS gateway): +# - WORKS: sending and receiving PMs, images (2023/10/15) +# - PARTIAL: calls (xmpp -> tel works; tel -> xmpp fails) +# - maybe i need to setup stun/turn +# +# TODO: +# - fix cheogram -> uninsane.org calls +# - enable mod_turn_external? +# - ensure muc is working +# - enable file uploads +# - "upload.xmpp.uninsane.org:http_upload: URL: - Ensure this can be reached by users" +# - move proxy65 to own port +# - "portmanager: Failed to open server port 5000 on *, this port is in use by another application" +# - port 5000 is in use by nix-serve (`sudo lsof -P -i4`) +# - disable or fix bosh (jabber over http): +# - "certmanager: No certificate/key found for client_https port 0" -{ lib, ... }: +{ lib, pkgs, ... }: -# XXX disabled: doesn't send messages to nixnet.social (only receives them). -# nixnet runs ejabberd, so revisiting that. -lib.mkIf false { sane.persist.sys.plaintext = [ { user = "prosody"; group = "prosody"; path = "/var/lib/prosody"; } @@ -18,11 +48,22 @@ lib.mkIf false visibleTo.wan = true; description = "colin-xmpp-client-to-server"; }; + sane.ports.ports."5223" = { + protocol = [ "tcp" ]; + visibleTo.lan = true; + visibleTo.wan = true; + description = "colin-xmpps-client-to-server"; # XMPP over TLS + }; sane.ports.ports."5269" = { protocol = [ "tcp" ]; visibleTo.wan = true; description = "colin-xmpp-server-to-server"; }; + sane.ports.ports."5270" = { + protocol = [ "tcp" ]; + visibleTo.wan = true; + description = "colin-xmpps-server-to-server"; # XMPP over TLS + }; sane.ports.ports."5280" = { protocol = [ "tcp" ]; visibleTo.lan = true; @@ -40,12 +81,64 @@ lib.mkIf false users.users.prosody.extraGroups = [ "nginx" ]; security.acme.certs."uninsane.org".extraDomainNames = [ + "xmpp.uninsane.org" "conference.xmpp.uninsane.org" "upload.xmpp.uninsane.org" ]; + # exists so the XMPP server's cert can obtain altNames for all its resources + services.nginx.virtualHosts."xmpp.uninsane.org" = { + useACMEHost = "uninsane.org"; + }; + services.nginx.virtualHosts."conference.xmpp.uninsane.org" = { + useACMEHost = "uninsane.org"; + }; + services.nginx.virtualHosts."upload.xmpp.uninsane.org" = { + useACMEHost = "uninsane.org"; + }; + + sane.dns.zones."uninsane.org".inet = { + # XXX: SRV records have to point to something with a A/AAAA record; no CNAMEs + A."xmpp" = "%ANATIVE%"; + CNAME."conference.xmpp" = "xmpp"; + CNAME."upload.xmpp" = "xmpp"; + + # _Service._Proto.Name TTL Class SRV Priority Weight Port Target + # - + # something's requesting the SRV records for conference.xmpp, so let's include it + # nothing seems to request XMPP SRVs for the other records (except @) + # lower numerical priority field tells clients to prefer this method + SRV."_xmpps-client._tcp.conference.xmpp" = "3 50 5223 xmpp"; + SRV."_xmpps-server._tcp.conference.xmpp" = "3 50 5270 xmpp"; + SRV."_xmpp-client._tcp.conference.xmpp" = "5 50 5222 xmpp"; + SRV."_xmpp-server._tcp.conference.xmpp" = "5 50 5269 xmpp"; + + SRV."_xmpps-client._tcp" = "3 50 5223 xmpp"; + SRV."_xmpps-server._tcp" = "3 50 5270 xmpp"; + SRV."_xmpp-client._tcp" = "5 50 5222 xmpp"; + SRV."_xmpp-server._tcp" = "5 50 5269 xmpp"; + }; + + # help Prosody find its certificates. + # pointing it to /var/lib/acme doesn't quite work because it expects the private key + # to be named `privkey.pem` instead of acme's `key.pem` + # + sane.fs."/etc/prosody/certs/uninsane.org/fullchain.pem".symlink.target = + "/var/lib/acme/uninsane.org/fullchain.pem"; + sane.fs."/etc/prosody/certs/uninsane.org/privkey.pem".symlink.target = + "/var/lib/acme/uninsane.org/key.pem"; + services.prosody = { enable = true; + package = pkgs.prosody.override { + # XXX(2023/10/15): build without lua-unbound support. + # this forces Prosody to fall back to the default Lua DNS resolver, which seems more reliable. + # fixes errors like "unbound.queryXYZUV: Resolver error: out of memory" + # related: + lua.withPackages = selector: pkgs.lua.withPackages (p: + selector (p // { luaunbound = null; }) + ); + }; admins = [ "colin@uninsane.org" ]; # allowRegistration = false; # extraConfig = '' @@ -53,8 +146,6 @@ lib.mkIf false # c2s_require_encryption = true # ''; - extraModules = [ "private" "vcard" "privacy" "compression" "component" "muc" "pep" "adhoc" "lastactivity" "admin_adhoc" "blocklist"]; - ssl.cert = "/var/lib/acme/uninsane.org/fullchain.pem"; ssl.key = "/var/lib/acme/uninsane.org/key.pem"; @@ -66,16 +157,72 @@ lib.mkIf false uploadHttp.domain = "upload.xmpp.uninsane.org"; virtualHosts = { - localhost = { - domain = "localhost"; - enabled = true; - }; + # "Prosody requires at least one enabled VirtualHost to function. You can + # safely remove or disable 'localhost' once you have added another." + # localhost = { + # domain = "localhost"; + # enabled = true; + # }; "xmpp.uninsane.org" = { domain = "uninsane.org"; enabled = true; ssl.cert = "/var/lib/acme/uninsane.org/fullchain.pem"; ssl.key = "/var/lib/acme/uninsane.org/key.pem"; - }; + }; }; + + ## modules: + # these are enabled by default, via + # - cloud_notify + # - http_upload + # - vcard_muc + # these are enabled by the module defaults (services.prosody.modules.) + # - admin_adhoc + # - blocklist + # - bookmarks + # - carbons + # - cloud_notify + # - csi + # - dialback + # - disco + # - http_files + # - mam + # - pep + # - ping + # - private + # - XEP-0049: let clients store arbitrary (private) data on the server + # - proxy65 + # - register + # - roster + # - saslauth + # - smacks + # - time + # - tls + # - uptime + # - vcard_legacy + # - version + extraModules = [ + "adhoc" # TODO: disable (should be auto-loaded by admin_adhoc) + # "admin_adhoc" + # "blocklist" + # "component" # not supposed to be manually enabled + # "compression" # moved to community modules; questionable safety + "lastactivity" # XEP-0012: allow users to query how long another user has been idle for + # "muc" # TODO: muc should be enabled as a component + # "pep" + # "privacy" # replaced by mod_blocklist + # "private" + # "vcard" # replaced by vcard_legacy + ]; + + extraConfig = '' + -- see: + -- try to solve: "certmanager: Error indexing certificate directory /etc/prosody/certs: cannot open /etc/prosody/certs: No such file or directory" + -- only, this doesn't work because prosody doesn't like acme's naming scheme + -- certificates = "/var/lib/acme" + + c2s_direct_tls_ports = { 5223 } + s2s_direct_tls_ports = { 5270 } + ''; }; }