Your ejabberd XMPP server is a powerful piece of software. But configuring everything requires several steps. Your best place to start is this hands-on ejabberd installation tutorial and this ejabberd STUN/TURN tutorial. If you have specific questions, first be sure to consult the official ejabberd documentation.
Testing your ejabberd configuration can be a tricky task. Luckily, Daniel Gultsch and Rishi Raj created an XMPP compliance test that will assist you in this process.
ejabberd XMPP server passes most of the XMPP compliance test checks out-of-the box, in default configuration. My fresh installation started at 94%. To get a 100% result, you need to configure a few things to pass the remaining 3 tests.
I’m assuming the configuration from my previous two tutorials on setting up your ejabberd real time IM server and configuring ejabberd video & voice calling.
XEP-0363: HTTP File Upload (CORS Headers)
You need to configure ejabberd to add custom headers to pass this XMPP compliance test. I also recommend creating a dedicated directory at /var/www/upload
. For HTTP file upload to work, you don’t need anything else except ejabberd XMPP server. No PHP scripts or web servers. Remember that file upload operates on port 5443
. Make sure it’s allowed by your server’s firewall.
mod_http_upload:
put_url: https://@HOST@:5443/upload
docroot: /var/www/upload
custom_headers:
"Access-Control-Allow-Origin": "https://@HOST@"
"Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
"Access-Control-Allow-Headers": "Content-Type"
Make sure /var/www/upload
directory is owned by ejabberd. Execute the following command:
chown ejabberd:ejabberd /var/www/upload
Once you configure ejabberd XMPP server with custom_headers
, it will pass this XMPP compliance test.
XEP-0156: Discovering Alternative XMPP Connection Methods (HTTP)
To pass this test you need a web daemon on your ejabberd XMPP server. It could be Nginx or Apache. One way or another, it should allow http
and https
access to two files:
https://example.com/.well-known/host-meta
https://example.com/.well-known/host-meta.json
.
The first file is an XML document without any extension defined in its name. Fill it with the following code:
<?xml version='1.0' encoding='utf-8'?>
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
<Link rel="urn:xmpp:alt-connections:xbosh"
href="https://example.com:5443/bosh" />
<Link rel="urn:xmpp:alt-connections:websocket"
href="wss://example.com:5443/ws" />
</XRD>
Substitute example.com
with the domain name of your ejabberd XMPP server. The code above announces addresses for clients to connect using BOSH and WebSockets. Both services are available in the default ejabberd installation.
The second file is the same data encoded in JSON:
{
"links": [
{
"rel": "urn:xmpp:alt-connections:xbosh",
"href": "https://example.com:5443/bosh"
},
{
"rel": "urn:xmpp:alt-connections:websocket",
"href": "wss://example.com:5443/ws"
}
]
}
You can test the accessibility of these files using your regular web browser. Once reachable, your ejabberd server will pass this XMPP compliance test.
XEP-0368: SRV records for XMPP over TLS
To pass this test you need to add four SRV records to your ejabberd XMPP server domain DNS. You already should have STUN/TURN records there, so what you need are these:
_xmpp-client._tcp IN example.com 5 0 5222 example.com 3600
_xmpp-server._tcp IN example.com 5 0 5269 example.com 3600
_xmpps-client._tcp IN example.com 5 0 5223 example.com 3600
_xmpps-server._tcp IN example.com 5 0 5270 example.com 3600
Depending on your domain provider, the form to create these SRV records will vary. Most often the items are as follows:
- Service:
xmpp-client
,xmpp-server
,xmpps-client
,xmpps-server
- Protocol:
tcp
- Priority:
5
- Weight:
0
- Port:
5222
,5269
,5223
,5270
- Target:
example.com
- TTL:
3600
orDefault
Remember to open the 4 ports listed above in your ejabberd XMPP server’s firewall. Allow up to 24 hours for the changes in the DNS to propagate. Then re-run the XMPP compliance test.
Conclusion
XMPP compliance test is a great way to know if your ejabberd is well configured and accessible. It will also give you an option to embed a nice badge certifying you passed all the tests. My personal XMPP server report used during these several tutorials looks like this.
In this ejabberd tutorial series:
- How to move the office to ejabberd XMPP server
- How to set up ejabberd video & voice calling (STUN/TURN)
- How to configure ejabberd to get 100% in XMPP compliance test
- Check ejabberd XMPP server useful configuration steps
- Starting with MQTT protocol and ejabberd MQTT broker
- Getting started with WebSocket API in ejabberd
- Install and configure MariaDB with ejabberd
- Publish-Subscribe pattern and PubSub in ejabberd
Photo by Ali Yahya on Unsplash
Thank you very much for your guides, I now have my own xmpp server at 95% compliance.
However I cannot figure out at all how to get XEP-0368 working.
I’ve added the SRV records, but it still will not pass, do I need to do something with port 443 or direct it to 5223 or 5270 (via nginx)? As I think is the purpose of XEP-0368?
Reading around the web it seems like there are more steps than just adding the SRV records, but I can’t actually find what it is. Any advice on what else was necessary would be appreciated.
(On ejabberd 20.07)
You don’t need to redirect any ports, but make sure the TCP ports from the SRV records are open in your server firewall (5222, 5269, 5223, 5270). You can use a DNS lookup tool to compare my domain config with yours: https://compliance.conversations.im/server/marekfoss.org/
Hi George,
i have the sameProblem.
Thank you for that tipps.
By 20.07 compliance in OMEMO fault. Is there any issue known?
There should be no issue. OMEMO is mostly a client-side protocol, so try first debugging there. For example, start a chat between two Conversations clients on Android and see if OMEMO works there with your server.
Hi,
I have followed what is indicated in this tutorial (thank you), but can’t go over 95%. Two tests fail, while checking manually, the dns and http(s) records are there.
Same for me on ejabberd 21.01.
Clean setup, SQL back-end, followed the first two tutorials up to voice and video calling.
Stuck at 95% due to XEP-0368 failing.
I notice the article talks of port 5270 but ejabberd 21.01 does NOT listen on port 5270 out of the box. There is no reference to it in ejabberd.yml and I can see nothing listening on 5270 so there must be an additional step or redirect required.
netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 43.63.88.100:7777 0.0.0.0:* LISTEN 998 31015 1404/beam.smp
tcp 0 0 0.0.0.0:42693 0.0.0.0:* LISTEN 998 26091 1404/beam.smp
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 116 26988 1492/mysqld
tcp 0 0 0.0.0.0:4369 0.0.0.0:* LISTEN 998 25807 1433/epmd
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 101 23741 1100/systemd-resolv
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 25782 1392/sshd: /usr/sbi
tcp 0 0 0.0.0.0:28888 0.0.0.0:* LISTEN 0 32065 2250/lfd Cluster Se
tcp6 0 0 :::1883 :::* LISTEN 998 30955 1404/beam.smp
tcp6 0 0 :::8443 :::* LISTEN 998 30953 1404/beam.smp
tcp6 0 0 :::5280 :::* LISTEN 998 30954 1404/beam.smp
tcp6 0 0 :::5443 :::* LISTEN 998 30952 1404/beam.smp
tcp6 0 0 :::5349 :::* LISTEN 998 30957 1404/beam.smp
tcp6 0 0 :::5222 :::* LISTEN 998 30950 1404/beam.smp
tcp6 0 0 :::4369 :::* LISTEN 998 25808 1433/epmd
tcp6 0 0 :::5269 :::* LISTEN 998 30951 1404/beam.smp
tcp6 0 0 :::22 :::* LISTEN 0 25793 1392/sshd: /usr/sbi
udp 0 0 127.0.0.53:53 0.0.0.0:* 101 23740 1100/systemd-resolv
udp 0 0 0.0.0.0:68 0.0.0.0:* 0 22348 1029/dhclient
udp 0 0 127.0.0.1:323 0.0.0.0:* 0 24885 1345/chronyd
udp 0 0 0.0.0.0:3478 0.0.0.0:* 998 30956 1404/beam.smp
udp6 0 0 ::1:323 :::* 0 24886 1345/chronyd
FWIW on prosody I can get 100% compliance and pass XEP-0368 without having any reference to port 5270 in DNS or otherwise.
Good catch with that port 5270. If you check https://www.process-one.net/blog/ejabberd-xmpp-server-useful-configuration-steps/ you will see I use 5270 in tls-enabled ejabberd_s2s_in. As a secure “_xmpps-server” seems to be required for the SRV compliance test, please add that section, try again and let me know if that’s it.
Yes Marek, I got 100% now on the compliance check. I perused the XEP-0368 and compared to how I had it working to 100% pass rate on another XMPP server product before. There was indeed no need for legacy s2s. What WAS needed however was a legacy 5223 c2s.
So my listen is:
listen:
–
port: 5222
ip: “::”
module: ejabberd_c2s
max_stanza_size: 524288
shaper: c2s_shaper
access: c2s
starttls_required: true
–
port: 5223
ip: “::”
module: ejabberd_c2s
max_stanza_size: 524288
shaper: c2s_shaper
access: c2s
tls: true
–
port: 5269
ip: “::”
module: ejabberd_s2s_in
max_stanza_size: 524288
The 5223 port config being the pertinent part.
For the SRV records I am indeed only showing 5222, 5223 and 5269 for this XEP plus the STUN and TURN stuff from your Voice / Video calling tutorial. Example SRV records:
;; SRV Records
_stuns._tcp.example.com. 1 IN SRV 10 10 5349 x.example.com.
_stun._tcp.example.com. 1 IN SRV 10 10 3478 x.example.com.
_stun._udp.example.com. 1 IN SRV 10 10 3478 x.example.com.
_turns._tcp.example.com. 1 IN SRV 10 10 5349 x.example.com.
_turn._tcp.example.com. 1 IN SRV 10 10 3478 x.example.com.
_turn._udp.example.com. 1 IN SRV 10 10 3478 x.example.com.
_xmpp-client._tcp.example.com. 1 IN SRV 10 10 5222 x.example.com.
_xmpps-client._tcp.example.com. 1 IN SRV 10 10 5223 x.example.com.
_xmpp-server._tcp.example.com. 1 IN SRV 10 10 5269 x.example.com.
This combo of SRV records and listeners gets me 100%. Obviously need to open on firewall as well. Compliance checker tries to connect on port 5223. Now I am good. Smooth move over to ejabberd!
Glad you figured it out! Indeed it’s the _xmpps_client that is required, not the _server :)
Hello Marek,
sorry for asking again – but I can’t get “100%” due to the XEP-0368 issue.
I reproduced accurate the steps, which Michael F. pointed out
Here are the relevant DNS records (for domain “example.com” host “xmpp.example.com”):
————————————-88——————————-
…and listeners in “ejabberd.yml”
——————————————88—————————————-
I don’t see any mistake, do you?
Thank you for reading!
F.
Thanks. It solved my problems.
sorry – something went wrong with formatting the code block:
_stun._tcp.example.com. SRV 0 0 3478 xmpp.example.com.
_stun._udp.example.com. SRV 0 0 3478 xmpp.example.com.
_stuns._tcp.example.com. SRV 0 0 5349 xmpp.example.com.
_turn._udp.example.com. SRV 0 0 3478 xmpp.example.com.
_turns._tcp.example.com. SRV 0 0 5349 xmpp.example.com.
_xmpp-client._tcp.example.com. SRV 1 1 5222 xmpp.example.com.
_xmpp-server._tcp.example.com. SRV 1 1 5269 xmpp.example.com.
_xmpps-client._tcp.example.com. SRV 1 1 5223 xmpp.example.com.
_xmpps-server._tcp.example.com. SRV 1 1 5270 xmpp.example.com.
port: 5222
ip: “::”
module: ejabberd_c2s
max_stanza_size: 524288
shaper: c2s_shaper
access: c2s
starttls_required: true
–
port: 5223
ip: “::”
module: ejabberd_c2s
max_stanza_size: 524288
shaper: c2s_shaper
access: c2s
tls: true
–
port: 5269
ip: “::”
module: ejabberd_s2s_in
max_stanza_size: 524288
–
port: 5270
ip: “::”
tls: true
module: ejabberd_s2s_in
max_stanza_size: 524288
–
port: 3478
ip: “::”
transport: udp
module: ejabberd_stun
use_turn: true
turn_min_port: 49152
turn_max_port: 65535
turn_ipv4_address: “aaa.bbb.ccc.ddd”
turn_ipv6_address: “aaaa:bbbb:cccc:ddd::e”
–
port: 5349
transport: tcp
module: ejabberd_stun
use_turn: true
tls: true
turn_min_port: 49152
turn_max_port: 65535
ip: 0.0.0.0
turn_ipv4_address: “aaa.bbb.ccc.ddd”
turn_ipv6_address: “aaaa:bbbb:cccc:ddd::e”
–
Please check the SRV records code block again, I think you are missing the TCP turn line:
_turn._tcp IN SRV 0 0 3478 example.com.
Dear Marek,
Thanks for your great blog posts! From what I see the compliance test for https://compliance.conversations.im/server/marekfoss.org/ still has two fails in the informal section for XEP-0313 and XEP-0402. Would you share some details why those are open?
BR, Dominik
Hi,
XEP-0402 requires some development: https://github.com/processone/ejabberd/issues/3591
Core XEP-0313 is ok, but the XEP-0313 … (extended usage) is failing, I haven’t been able find an issue about it yet.
BR, Jeroen
Thank you.
I’m wondering if I got something completely wrong here – from my perspective, the SRV DNS records are missing the actual ‘SRV’ parameter – why is that?
Hello, I have an even more serious problem, I cannot establish a connection via websocket, it gives me the following error:
WebSocket connection to ‘wss://midominio.com:5443/ws’ failed: _connect @ websocket.js:156
error websocket error {“istrusted”:true}
error websocket closed unexcectedly
Thank you so much for this howto
It is possible to comply with “XEP-0368: SRV records for XMPP over TLS”, having DDNS (like duckdns for example)?
Best regards!