XMPP over TLS Tutorial
XMPP over TLS Tutorial
How to setup XEP-0368
Was ist XEP-0368
Bei XEP-0368 handelt es sich um ein Verfahren welches XMPP-Clients ermöglicht über SRV Einträge im DNS, alternative Verbindungsmöglichkeiten zu entdecken. Dies ist äußerst nützlich, falls die regulären Verbindungswege blockiert sind zb. durch Firewalls.
XMPP Core specifies the use of xmpp-client/xmpp-server SRV records as the method of discovering how to connect to an XMPP server. This XEP extends that to include new xmpps-client/xmpps-server SRV records pointing to direct TLS ports and combine priorities and weights as if they were a single SRV record similar to RFC 6186. It also provides an easy way for clients to bypass restrictive firewalls that only allow HTTPS, for servers to host multiple protocols/services on a single port, and for servers and clients to take advantage of less round trips and existing direct TLS loadbalancers.
— XEP-0368 Definition
Was wird benötigt?
- Prosody Server
- optional gültiges SSL Zertifikat ( LetsEncrypt / oä )
- 2 IPv4 Adressen ( Hinweis beachten )
- iptables und iptables-persistent
- optional Webserver
- Kontrolle über eure DNS Zone
Hinweis: Notwendigkeit 2 IPv4 Adressen
Es werden 2 IP Adressen benötigt, wenn Ihre IP Adresse bereits auf Port 443 lauscht. Sprich eine https Website via Apache2 / nginx gehostet wird. Da für diese Methode der Port verpflichtend benötigt wird. Ist dies nicht der Fall reicht eine einzelne IP Adresse vollkommen aus.
1. DNS Einstellungen
Den Anfang machen die DNS Einstellungen, da die Veröffentlichung der neuen DNS Einstellungen bis zu 48 Stunden dauern kann.
Zusätzlich zu den Standard SRV Einträgen
wird ein weiterer _xmpps-client._tcp
Eintrag benötigt. Außerdem ein weiterer A Record für die gewünschte Subdomain.
In diesem Beispiel ist die Domain example.com
und XMPP over TLS soll über die SubDomain xmpps.example.com
erreichbar sein.
# Standard Settings
_xmpp-client._tcp.example.com. 18000 IN SRV 0 5 5222 example.com.
_xmpp-server._tcp.example.com. 18000 IN SRV 0 5 5269 example.com.
# XMPP over TLS Settings
_xmpps-client._tcp.example.com. 18000 IN SRV 10 5 443 xmpps.example.com.
# A record
xmpps.example.com. 18000 IN A $zweite_ip_adresse
2. Prosody Server Konfiguration
Für den Verbindungsaufbau muss in der Prosody Konfiguration legacy_ssl_ports definiert werden, damit das http
Modul auch auf dem gewählten Port lauscht. Das Modul mod_legacyauth wird hierfür allerdings nicht benötigt.
Ein Neustart des Prosody Services ist nach dem setzen dieser Einstellung zwingend erforderlich.
-- XEP-0368: SRV records for XMPP over TLS
legacy_ssl_ports = { 5223 }
3. SSL Zertifikat ( optional )
Hier wäre der Zeitpunkt das bestehende Zertifikat für example.com
auf xmpps.example.com
auszuweiten, um keinen common name error
zu erzeugen. Dieses erweiterte Zertifikat ist dem Prosody zur Verfügung zu stellen. Die Ausstellung eines neuen LetEncrypt Zertifikats ist nach Schritt 5: Webserver
deutlich einfacher.
Hinweis : Dieser Teil ist vollkommen optional. Die Prosody Dokumentation
zeigt auf, dass kein Zertifikat notwendig wäre.
IMHO Es macht das Gesamtbild einheitlicher, wenn auch an diesem Endpunkt ein gültiges SSL Zertifikat präsentiert wird.
In Section 5. Webserver
gehe ich darauf noch einmal genau ein.
4. iptables Regeln
Für das Umleiten der Pakete wird die PREROUTING und POSTROUTING Kette von iptables
verwendet. Dabei werden Pakete noch bevor sie überhaupt geroutet werden umgeleitet.
Dafür werden 2 Regeln verwendet um einen malformed xml-error
zu vermeiden.
Regel Nr. 1 leitet den gesamten Traffic der zweiten IP von Port 443, ohne Veränderung an Port 5223 der ersten IP weiter.
Für die Antwort des Prosody Servers wird allerdings eine zweite Regel benötigt, die sich in der POSTROUTING Kette befindet. Diese stellt sicher, dass das Antwort-Paket wieder über Port 443 der zweiten IP Adresse den Server verlässt.
Sollte bei der Prosody Konfiguration ein anderer Port gewählt werden als der default Port, muss dieser natürlich in den iptables Regeln ausgetauscht werden.
In diesem Beispiel ist erste_ip, jene IP-Adresse auf der auch der httpd Server lauscht. zweite_ip bezeichnet somit die zweite Adresse speziell für XMPP over TLS.
# PREROUTING
iptables -t nat -A PREROUTING -d zweite_ip -p tcp --dport 443 -j DNAT --to-destination erste_ip:5223
# POSTROUTING
iptables -t nat -A POSTROUTING -p tcp -d zweite_ip --dport 5223 -j SNAT --to-source erste_ip:5223
Abschließend sollten diese Regeln mit iptables-save
gespeichert werden, damit diese bei einem reboot erneut angewendet werden.
iptables-save > /etc/iptables/rules.v4
5. Webserver
Die Konfiguration des Webserver ist grundsätzlich nicht notwendig, macht das testen der vorgenommenen Änderungen, sowie erzeugen bzw. erweitern bestehender Zertifikate allerdings bedeutend einfacher.
Im Folgenden habe ich die simpelste Möglichkeit eins vHosts angenommen. Dabei ist als Beispiel immer example.de verwendet worden.
nginx
server {
listen zweite_ip:80;
server_name xmpps.example.de;
#hier kann je nach Wunsch eine Weiterleitung stattfinden
return 301 https://example.de;
# letsencrypt love
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
}
location = /.well-known/acme-challenge/ {
return 404;
}
}
apache2
<VirtualHost zweite_ip:80>
ServerName xmpps.example.de
# hier kann je nach Wunsch eine Weiterleitung stattfinden
Redirect / https://example.de;
</VirtualHost>
Sind diese Änderungen vorgenommen, ist es leicht möglich via LetsEncrypt ein Zertifikat für die SubDomain auszustellen. Zusätzlich dazu ist es nun möglich direkt zu testen ob XMPP over TLS funktioniert.
Abschluss
Sollten alle diese Schritte erfolgreich abgeschlossen sein, ist es sehr leicht möglich zu testen ob alles so funktioniert wie es soll. Hierfür lässt sich curl -i
verwenden.
curl -i https://xmpps.example.com
Falls es zu diesem Zeitpunkt noch keine gültigen Zertifikate gibt, kann mit dem
-k
Argument für curl
ein ungültiges Zertifikat ignoriert werden.Als Ergebnis sollte ein xml stream error zu sehen sein, ohne Apache2 / nginx header.
<?xml version='1.0'?>
<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xml:lang='en' xmlns='jabber:client'>
<stream:error>
<not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
</stream:stream>
Für das Testen via curl sollte eine andere Maschine gewählt werden. Ausgeführt auf der gleichen Maschine durchlaufen die Pakete nicht die PREROUTING bzw. POSTROUTING Kette, daher wird die Verbindung abgelehnt.