diff options
Diffstat (limited to 'Biz/Cloud/Comms/Xmpp.nix')
-rw-r--r-- | Biz/Cloud/Comms/Xmpp.nix | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/Biz/Cloud/Comms/Xmpp.nix b/Biz/Cloud/Comms/Xmpp.nix new file mode 100644 index 0000000..d74a6b7 --- /dev/null +++ b/Biz/Cloud/Comms/Xmpp.nix @@ -0,0 +1,214 @@ +{ config, pkgs, ... }: +# +# xmpp chat service +# +let + rootDomain = config.networking.domain; # simatime.com + ssl = { + cert = "/var/lib/acme/${rootDomain}/fullchain.pem"; + key = "/var/lib/acme/${rootDomain}/key.pem"; + }; +in { + networking.firewall.allowedTCPPorts = [ + # https://prosody.im/doc/ports + 5000 # file transfer + 5222 # client connections + 5269 # server-to-server + 5280 # http + 5281 # https + 5347 # external components + 5582 # telnet console + ]; + + services.prosody = { + enable = true; + package = pkgs.prosody.override { + withCommunityModules = [ + "conversejs" + ]; + }; + + # when i learn how to use security.acme better, and use separate certs, then i + # can fix this group + group = "nginx"; + admins = [ "bsima@${rootDomain}" ]; + allowRegistration = true; + inherit ssl; + uploadHttp = { + domain = "upload.${rootDomain}"; + uploadExpireAfter = toString (60*60*24*30); # 30 days, as seconds + }; + + modules = { + announce = true; + blocklist = true; + bookmarks = true; + bosh = true; + carbons = true; + cloud_notify = true; + csi = true; + dialback = true; + disco = true; + groups = true; + http_files = false; # hm, look into this + motd = true; + pep = true; + ping = true; + private = true; + proxy65 = true; + register = true; + roster = true; + server_contact_info = true; + smacks = true; + vcard = true; + watchregistrations = true; + websocket = true; + welcome = true; + }; + + extraConfig = '' + conversejs_options = { + allow_registration = true; + bosh_service_url = "https://${rootDomain}/http-bind"; + debug = true; + loglevel = "debug"; + -- default_domain = "${rootDomain}"; + -- domain_placeholder = "${rootDomain}"; + -- jid = "${rootDomain}"; + -- keepalive = true; + -- registration_domain = "${rootDomain}"; + websocket_url = "wss://${rootDomain}/xmpp-websocket"; + } + + cross_domain_websocket = { "https://${rootDomain}", "https://anon.${rootDomain}" } + cross_domain_bosh = false; -- handle this with nginx + consider_bosh_secure = true; + + -- this is a virtualhost that allows anonymous authentication. use this + -- for a public lobby. the nix module doesn't support 'authentication' + -- so i have to do this here. + VirtualHost "anon.${rootDomain}" + authentication = "anonymous" + ssl = { + cafile = "/etc/ssl/certs/ca-bundle.crt"; + key = "${ssl.key}"; + certificate = "${ssl.cert}"; + }; + ''; + + muc = [ + { + domain = "conference.${rootDomain}"; + maxHistoryMessages = 10000; + name = "Chat Rooms"; + restrictRoomCreation = "admin"; + roomDefaultHistoryLength = 20; + roomDefaultMembersOnly = true; + roomDefaultModerated = true; + roomDefaultPublic = false; + } + { + domain = "chat.${rootDomain}"; + maxHistoryMessages = 10000; + name = "Chat Rooms"; + restrictRoomCreation = false; + roomDefaultHistoryLength = 200; + roomDefaultMembersOnly = false; + roomDefaultModerated = false; + roomDefaultPublic = true; + roomDefaultPublicJids = true; + } + ]; + + virtualHosts = { + "${rootDomain}" = { + domain = "${rootDomain}"; + enabled = true; + inherit ssl; + }; + }; + }; + + services.prosody-filer = { + enable = true; + }; + + services.nginx.virtualHosts."${rootDomain}".locations = { + "/http-bind" = { + proxyPass = "https://${rootDomain}:5281/http-bind"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + add_header Access-Control-Allow-Origin "*"; + ''; + }; + + "/xmpp-websocket" = { + proxyPass = "https://${rootDomain}:5281/xmpp-websocket"; + extraConfig = '' + proxy_http_version 1.1; + proxy_buffering off; + proxy_set_header Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 86400; + add_header Access-Control-Allow-Origin "*"; + ''; + }; + + "/chat" = { + proxyPass = "https://${rootDomain}:5281/conversejs"; + extraConfig = '' + add_header Access-Control-Allow-Origin "*"; + ''; + }; + }; + + services.nginx.virtualHosts."anon.${rootDomain}" = { + useACMEHost = "${rootDomain}"; + forceSSL = true; + locations = { + "/http-bind" = { + proxyPass = "https://anon.${rootDomain}:5281/http-bind"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + if ($request_method ~* "(GET|POST)") { + add_header Access-Control-Allow-Origin "*"; + } + if ($request_method = OPTIONS) { + add_header Access-Control-Allow-Origin "*"; + add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, HEAD"; + add_header Access-Control-Allow-Headers "Authorization, Origin, X-Requested-With, Content-Type, Accept"; + return 200; + } + ''; + }; + }; + }; + + users.users.nginx.extraGroups = [ "prosody" ]; + + security.acme.certs.${rootDomain}.extraDomainNames = [ + "upload.${rootDomain}" + "conference.${rootDomain}" + "anon.${rootDomain}" + "chat.${rootDomain}" + ]; + + #security.acme.certs.prosody = { + # domain = "${domain}"; + # group = "prosody"; + # dnsProvider = "rfc2136"; + # #credentialsFile = config.secrets.files.dns_creds.path; + # postRun = "systemctl restart prosody"; + # extraDomainNames = [ + # domain + # "upload.${domain}" + # ]; + #}; +} |