;2021-08: Serverkonfiguration auf Ansible umgestellt, dabei kleine Fehler behoben, neue Funktionen hinzugefügt, Conversejs aktualisiert.
==Files==
== Implementierung ==
Das Ansible-Playbook samt Inventory befinden sich hier: https://git.bingo-ev.de/xmpp
Im [https://git.bingo-ev.de/xmpp/bytewerk-xmpp-server/-/wikis/home Gitlab-Wiki]
=== Software ===
Auf der VM '''xmpp.bytewerk.org''' läuft:
* [https://prosody.im/ Prosody]: XMPP-Server
* [https://www.postgresql.org PostgreSQL]: Datenbank für Benutzer, Kontakte, Gruppen und Chats
* [https://github.com/coturn/coturn Coturn]: TURN und STUN (für Jingle/WebRTC benötigt, d.h. Audio-/Videotelefonie sowie Dateiübertragung von Client zu Client)
* [https://github.com/conversejs/converse.js ConverseJS]: XMPP-Webclient, mit einigen [https://github.com/conversejs/community-plugins Community-Plugins]
* [https://httpd.apache.org/ Apache2] mit mod_php: HTTPS-Reverse-Proxy für File-Up- und -Downloads, ''.well-known''-URLs, BOSH und Websocket, Bereitstellung von ConverseJS. PHP wird für das "share_v2.php"-Skript benötigt, das sich um Datei-Up- und Downloads kümmert.
* [https://github.com/DigitaleGesellschaft/Anonip Anonip]: Wird zum Logging in Apache2 benutzt um in den Access-Logs die letzten Stellen der IP-Adressen auf 0 setzen. Liegt unter ''/usr/local/Anonip.git''
* [https://certbot.eff.org Certbot]: Für TLS-Zertifikatsaktualisierung
* Crond: Um Certbot wöchentlich aufzurufen und um täglich das Fileupload-Verzeichnis aufzuräumen
=== DNS ===
XMPP-Server und -Clients nutzen SRV-Records, um anhand der JID-Domäne eines Nutzer den Server, die Components und deren Ports zu herauszufinden.
Die A/AAAA-Einträge werden gebraucht, um für die SRV-Records die TLS-Zertifikate zu erstellen.
==== Auszug aus dem Zonefile von bytewerk.org ====
<pre>
xmpp.bytewerk.org. 300 IN A 94.142.219.72 # Prosody-Server, Coturn-Server, Apache2
xmpp.bytewerk.org. 300 IN AAAA 2a02:868:15:72::1
conference.bytewerk.org. 300 IN A 94.142.219.72 # MUC-Component, Apache2
conference.bytewerk.org. 300 IN AAAA 2a02:868:15:72::1
proxy.bytewerk.org. 300 IN A 94.142.219.72 # Proxy65-Component, Apache2
proxy.bytewerk.org. 300 IN AAAA 2a02:868:15:72::1
upload.bytewerk.org. 300 IN A 94.142.219.72 # HTTP-Fileupload, Apache2
upload.bytewerk.org. 300 IN AAAA 2a02:868:15:72::1
pubsub.bytewerk.org. 300 IN A 94.142.219.72 # PubSub-Component, Apache2
pubsub.bytewerk.org. 300 IN AAAA 2a02:868:15:72::1
_xmpp-client._tcp.bytewerk.org. 300 IN SRV 0 5 5222 xmpp.bytewerk.org. # VirtualHost XMPP-Server, C2S
_xmpps-client._tcp.bytewerk.org. 300 IN SRV 0 5 5223 xmpp.bytewerk.org. # VirtualHost XMPP-Server, C2S Legacy SSL auf Port 5223
_xmpp-server._tcp.bytewerk.org. 300 IN SRV 0 5 5269 xmpp.bytewerk.org. # VirtualHost XMPP-Server, S2S
_xmpp-server._tcp.conference.bytewerk.org. 300 IN SRV 0 5 5269 xmpp.bytewerk.org. # MUC-Component, S2S
_xmpp-server._tcp.proxy.bytewerk.org. 300 IN SRV 0 5 5269 xmpp.bytewerk.org. # Proxy65-Component, S2S
_xmpp-server._tcp.pubsub.bytewerk.org. 300 IN SRV 0 5 5269 xmpp.bytewerk.org. # PubSub-Component, S2S
_xmppconnect.bytewerk.org. 300 IN TXT "_xmpp-client-xbosh=https://xmpp.bytewerk.org/http-bind" # BOSH
_xmppconnect.bytewerk.org. 300 IN TXT "_xmpp-client-websocket=wss://xmpp.bytewerk.org/xmpp-websocket" # Websocket
</pre>
==== Auszug aus dem Zonefile von bingo-ev.de ====
<pre>
conference.bingo-ev.de. 300 IN A 94.142.219.72 # MUC-Component, Apache2
conference.bingo-ev.de. 300 IN AAAA 2a02:868:15:72::1
proxy65.bingo-ev.de. 300 IN A 94.142.219.72 # Proxy65-Component, Apache2 ("proxy.bingo-ev.de" ist bereits belegt)
proxy65.bingo-ev.de. 300 IN AAAA 2a02:868:15:72::1
upload.bingo-ev.de. 300 IN A 94.142.219.72 # HTTP-Fileupload, Apache2
upload.bingo-ev.de. 300 IN AAAA 2a02:868:15:72::1
pubsub.bingo-ev.de. 300 IN A 94.142.219.72 # PubSub-Component, Apache2
pubsub.bingo-ev.de. 300 IN AAAA 2a02:868:15:72::1
_xmpp-client._tcp.bingo-ev.de. 300 IN SRV 0 5 5222 xmpp.bytewerk.org. # VirtualHost XMPP-Server, C2S
_xmpps-client._tcp.bingo-ev.de. 300 IN SRV 0 5 5225 xmpp.bytewerk.org. # VirtualHost XMPP-Server, C2S Legacy SSL auf Port 5225
_xmpp-server._tcp.bingo-ev.de. 300 IN SRV 0 5 5269 xmpp.bytewerk.org. # VirtualHost XMPP-Server, S2S
_xmpp-server._tcp.conference.bingo-ev.de. 300 IN SRV 0 5 5269 xmpp.bytewerk.org. # MUC-Component, S2S
_xmpp-server._tcp.proxy65.bingo-ev.de. 300 IN SRV 0 5 5269 xmpp.bytewerk.org. # Proxy65-Component, S2S
_xmpp-server._tcp.pubsub.bingo-ev.de. 300 IN SRV 0 5 5269 xmpp.bytewerk.org. # PubSub-Component, S2S
_xmppconnect.bingo-ev.de. 300 IN TXT "_xmpp-client-xbosh=https://xmpp.bytewerk.org/http-bind" # BOSH
_xmppconnect.bingo-ev.de. 300 IN TXT "_xmpp-client-websocket=wss://xmpp.bytewerk.org/xmpp-websocket" # Websocket
</pre>
=== Zertifikate ===
'''''Prosody''''' benötigt Zertifikate für ALLE beteiligten Domains, also auch von bytewerk.org und bingo-ev.de. Components ohne Zertifikat funktionieren nicht mit externen Usern.
Mit "prosodyct check" kann geprüft werden ob alle Zertikate passend zu den DNS-Einträgen und zu den Components vorhanden sind (Ausnahme: Legacy-SSL).
Für Feinheiten lohnt sich ein Blick in "/var/log/prosody/prosody.err", besonders mit eingeschaltetem "debug"-Loglevel.
'''''Coturn''''' benötigt nur das Zertifikat von "xmpp.bytewerk.org"
'''''Apache2''''' braucht grundsätzlich nur Zertifikate für "xmpp.bytewerk.org", "upload.bytewerk.org" und "upload.bingo-ev.de".
Um die Zertifikate, die von Prosody benötigt werden, mit Certbot zu erstellen, gibt's diese vHosts:
* xmpp.bytewerk.org
* conference.bytewerk.org, pubsub.bytewerk.org, proxy.bytewerk.org, upload.bytewerk.org
* conference.bingo-ev.de, pubsub.bingo-ev.de, proxy65.bingo-ev.de, upload.bingo-ev.de
==== TLS-Zertifikate für bytewerk.org und bingo-ev.de ====
Die Zertifikate für bytewerk.org und bino-ev.de wird nicht auf der VM erstellt sondern müssen auf den XMPP-Server kopiert und User "prosody" übereignet werden.
Danach muss Prosody mit "prosodyctl reload" neu geladen werden.
* bytewerk.org:
** ''/etc/prosody/certs/bytewerk.org/privkey.pem''
** ''/etc/prosody/certs/bytewerk.org/fullchain.pem''
* bingo-ev.de:
** ''/etc/prosody/certs/bingo-ev.de/privkey.pem''
** ''/etc/prosody/certs/bingo-ev.de/fullchain.pem''
==== Alle anderen Zertifikate ====
Alle Zertifikate außer dem von bytewerk.org und bingo-ev.de werden von LetsEncrypt-Certbot erstellt und liegen unter ''/etc/letsencrypt''.
Das Renewal wird per wöchentlichem Cronjob von root mit ''/usr/bin/certbot renew'' durchgeführt.
Zertifikate:
* xmpp.bytewerk.org
* conference.bytewerk.org, pubsub.bytewerk.org, proxy.bytewerk.org, upload.bytewerk.org
* conference.bingo-ev.de, pubsub.bingo-ev.de, proxy65.bingo-ev.de, upload.bingo-ev.de
Nach einem erfolgten Renewal führt Certbot die Post-Renewal-Hook-Skripte in ''/etc/letsencrypt/renewal-hooks/post/'' aus:
* ''apache2.sh'': Lädt Apache2 neu
* ''coturn.sh'': Kopiert die Zertifikate nach ''/etc/coturn/certs/'', passt die Rechte an und startet Coturn neu
* ''prosody.sh'': Kopiert die Zertifikate nach ''/etc/prosody/certs/'', passt die Rechte an und lädt Prosody neu
=== Konfiguration Prosody ===
Kommentierte Konfigurationsdatei "/etc/prosody/prosody.cfg.lua"
Da beim Prosody-Paket von OpenSuse eine Menge benötigter Module fehlen, wurden die Module direkt aus dem Prosody-Mercuriual-Repository nach "/usr/local/lib/prosody-modules/" geklont
Zum Aktualisieren einfach "/usr/local/sbin/update-prosody-modules.sh" ausführen und Prosody mit "prosodyctl reload" neu laden.
=== Konfiguration Apache2 ===
In ''/etc/apache2/vhosts.d/01-set-servername.conf'': Hostname auf xmpp.bytewerk.org setzen
Diese vHosts wurden in ''/etc/apache2/vhosts.d/'' angelegt:
* conference.bytewerk.org.conf, conference.bingo-ev.de.conf: Nur Platzhalter für Certbot
* proxy.bytewerk.org.conf, proxy65.bingo-ev.de.conf: Nur Platzhalter Certbot
* pubsub.bytewerk.org.conf, pubsub.bingo-ev.de.conf: Nur Platzhalter Certbot
* upload.bytewerk.org.conf, upload.bingo-ev.de.conf: Fileupload per mod_http_upload_external + share_v2.php
* xmpp.bytewerk.org.conf: Reverse-Proxy für BOSH, Websocket und für die von mod_http_altconnect erstellte .well-known-URIs
Alle vHosts außer upload.bytewerk.org leiten auf https://jabber.bytwerk.org um.
=== Konfiguration Coturn ===
Kommentierte Konfigurationsdatei "/etc/coturn/turnserver.conf"
=== Fileupload ===
Der in Prosody eingebaute HTTP-Server unterstützt nur den Upload von Dateien <= 10 MByte und funktioniert nicht mit einigen iOS-Clients (z.B. Monal, Siskin).
Um diese Probleme zu umgehen wird das von Prosody empfohlene Modul "mod_http_upload_external" verwendet.
Bei dem Modul funktioniert der Dateiup- und Download über das mitgelieferte PHP-Skript "share_v2.php", das unter dem Apache-vHost "https://upload.bytewerk.org/share_v2.php" (bzw. https://upload.bingo-ev.de/share_v2.php) eingebunden ist und hochgeladene Dateien unter "/srv/var/prosody-upload/<DOMAIN>/" abspeichert.
Dateien, die älter als ein Monat sind, werden per täglichem Cronjob von root gelöscht.
=== well-known-URLs ===
Um XEP-0156 ("Discovering Alternative XMPP Connection Methods") zu erfüllen, müssen die Webserver von bytewerk.org und bingo-ev.de per Reverse Proxy folgende URL vom XMPP-Server durchreichen. Es reicht wenn die URLs über HTTPS erreichbar sind:
* ''xmpp.bytewerk.org/.well-known/host-meta'' unter:
** https://bytewerk.org/.well-known/host-meta
** https://bingo-ev.de/.well-known/host-meta
* ''xmpp.bytewerk.org/.well-known/host-meta.json'' unter:
** https://bytewerk.org/.well-known/host-meta.json
** https://bingo-ev.de/.well-known/host-meta.json
Ein einfacher Redirect funktioniert nicht, da dieser die von Prosody gesetzten HTTP-CORS-Header zurücksetzt.
==Probleme/ToDo==
siehe https://git.bingo-ev.de/groups/xmpp/-/issues
=== Routing ===
Stand 02.09.2021 gibt's ohne folgende Änderungen Routingprobleme mit IPv6:
Route Announcements auf dem Interface net-nat ignorieren:
In ''/etc/sysctl.d/ipv6-ignore-ra.conf'':
<pre>
net.ipv6.conf.net-nat.accept_ra=0
net.ipv6.conf.net-nat.autoconf=0
</pre>
In ''/sysconfig/network/routes'' Default-Route für IPv4 setzen:
<pre>
# target via netmask interface
default 94.142.219.94 0.0.0.0 net-public
</pre>
In ''/etc/iproute2/rt_tables'' neue Routingtabelle namens "public" anlegen:
<pre>
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
200 public
</pre>
Verbindungen von der öffentliche IPv6-Adresse über diese Route laufen lassen. Dazu in ''/etc/sysconfig/network/ifrule-net-public'':
<pre>
ipv6 from 2a02:868:15:72::1/64 table public
</pre>
==Files==
Das Ansible Playbook und das Inventory befinden sich hier: https://git.bingo-ev.de/xmpp
|