Help Verifying eJabberd XMPP STUN/TURN Server Configuration

I’ve have configured my default Freedombox eJabberd XMPP chat server for STUN/TURN voice and video connections. However, I’m finding it hard to verify that the STUN/TURN server is configured correctly. There are some references to STUN and TURN in my eJabberd log files (detailed below) but I can’t tell if I’m testing my setup correctly. Any help with understanding how to test my set up would be much appreciated?

I’m able to make voice calls between two Jitsi clients (Jitsi is the only XMPP client that I have found that can reliably and compatibly make voice connections between devices). My Android phone is running the Jitsi app installed from an APK and my Ubuntu laptop is running the Jitsi desktop app from the jitsi_2.11.5624-1_amd64.deb package.

Both client devices are connected to the internet through VPN connections, to different locations. Because both devices are connected through VPNs and are managing to establish a voice connection, to me this suggests that the STUN/TURN relay server it being activated, but I would appreciate verification of my setup from others who know more about this than I do?

Below are the details of my configuration and the steps I took to set up the eJabberd STUN/TURN server:

  • created DNS XMPP, STUN and TURN SRV records with domain host, based on instructions from the eJabberd documentation, here;
  • installed Rasbian Buster on Raspberry Pi3B+;
  • installed Freedombox as per instructions on the Wiki;;
  • updated Freedombox to version 2.7;
  • created two user accounts;
  • installed eJabberd via Plinth Freedombox;
  • edited eJabberd config file: sudo nano /etc/ejabberd/ejabberd.yml
  • added STUN/TURN configuration (see below):
  • restarted eJabberd via Plinth
  • logged into the eJabberd with Jitsi on Android and desktop both via VPN - the desktop took about a min to show “online”;
  • opened up eJabbered.log and eJabbered’s error.log in real time view in the terminal to view connection activity and ascertain if TURN is being used (further details below);
  • initiate a voice call from either device and establish an audio connection - the connection is audible.


Configuration of DNS SRV records based on info from the eJabbered documentation and further info here and here - see screenshot below (double click to enlarge image!):

eJabberd STUN/TURN configuration, below, added to the eJabberd config file: /etc/ejabberd/ejabberd.yml based on info from here:

- "/etc/ejabberd/letsencrypt/MY-DOMAIN-NAME/ejabberd.pem"

(I can’t remember if the above line was the default or not!)

STUN/TURN configuration lines

- port: 3478
  transport: udp
  module: ejabberd_stun
  auth_type: user
  auth_realm: "MY-DOMAIN-NAME"
  use_turn: true
  turn_ip: "MY-EXTERNAL-HOME-IP" # Your IP address
- port: 3478
  transport: tcp
  module: ejabberd_stun
  auth_type: user
  auth_realm: "MY-DOMAIN-NAME"
  use_turn: true
  turn_ip: "MY-EXTERNAL-HOME-IP" # Your IP address

Having a look at the error.log:

sudo su
cd /var/log/ejabberd
tail -f error.log

I had the following reference to STUN and TURN connecting, but have been unable to replicate:

2020-05-01 00:50:00.339 [error] <0.383.0>@ejabberd_listener:init:114 failed to process callback function ejabberd_stun:udp_init(#Port<0.15>, [{turn_ip,{MY-IP}},{use_turn,true},{auth_realm,<<"MY-DOMAIN-NAMEe">>}]): {'EXIT',{application_start_failed,[{ejabberd,exit_or_halt,2,[{file,"src/ejabberd.erl"},{line,142}]},{ejabberd_stun,udp_init,2,[{file,"src/ejabberd_stun.erl"},{line,61}]},{ejabberd_listener,init,4,[{file,"src/ejabberd_listener.erl"},{line,112}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,249}]}]}}
2020-05-01 00:50:00.348 [critical] <0.382.0>@ejabberd:exit_or_halt:137 failed to start application 'stun': {error,
                                     {"no such file or directory",""}}
2020-05-01 00:50:00.349 [error] <0.382.0>@ejabberd_listener:init:146 failed to process callback function ejabberd_stun:tcp_init(#Port<0.14>, [{turn_ip,{MY-IP}},{use_turn,true},{auth_realm,<<"MY-DOMAIN-NAMEe">>}]): {'EXIT',{application_start_failed,[{ejabberd,exit_or_halt,2,[{file,"src/ejabberd.erl"},{line,142}]},{ejabberd_stun,tcp_init,2,[{file,"src/ejabberd_stun.erl"},{line,57}]},{ejabberd_listener,init,4,[{file,"src/ejabberd_listener.erl"},{line,144}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,249}]}]}}
2020-05-01 00:52:39.691 [critical] <0.392.0>@ejabberd:exit_or_halt:137 failed to start application 'stun': {error,
                                     {"no such file or directory",""}}
2020-05-01 00:52:39.691 [error] <0.392.0>@ejabberd_listener:init:114 failed to process callback function ejabberd_stun:udp_init(#Port<0.15>, [{turn_ip,{MY-IP}},{use_turn,true},{auth_realm,<<"MY-DOMAIN-NAMEe">>}]): {'EXIT',{application_start_failed,[{ejabberd,exit_or_halt,2,[{file,"src/ejabberd.erl"},{line,142}]},{ejabberd_stun,udp_init,2,[{file,"src/ejabberd_stun.erl"},{line,61}]},{ejabberd_listener,init,4,[{file,"src/ejabberd_listener.erl"},{line,112}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,249}]}]}}
2020-05-01 00:52:39.717 [critical] <0.391.0>@ejabberd:exit_or_halt:137 failed to start application 'stun': {error,
                                     {"no such file or directory",""}}
2020-05-01 00:52:39.717 [error] <0.391.0>@ejabberd_listener:init:146 failed to process callback function ejabberd_stun:tcp_init(#Port<0.14>, [{turn_ip,{MY-IP}},{use_turn,true},{auth_realm,<<"MY-DOMAIN-NAMEe">>}]): {'EXIT',{application_start_failed,[{ejabberd,exit_or_halt,2,[{file,"src/ejabberd.erl"},{line,142}]},{ejabberd_stun,tcp_init,2,[{file,"src/ejabberd_stun.erl"},{line,57}]},{ejabberd_listener,init,4,[{file,"src/ejabberd_listener.erl"},{line,144}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,249}]}]}}

Is there anything obviously wrong with my eJabberd STUN/TURN setup? Or any idea how I might verifiy my setup would be gratfully recived?

@homer77 I wonder if you might be able to shed any light on this?

1 Like

Well, I’m really no expert and also just learning by doing here.

But I found this stack overflow answer implicating that ejabberd stun won’t work with LDAP auth. And we are using that on Freedombox, aren’t we?

1 Like

Thanks for this :slight_smile:

I just watched this video from LinuxTutorial and now realise why I’m so slow to figure stuff out rofl:/ :

And this tutorial video from the same guy about setting up Prosody XMPP server is super helpful as he goes start to finish including setting up the DNS records:


Interestingly a new release of eJabberd (20.04) came out two days ago (30th April 2020) and in the accompanying press release it says the following:

We are pleased to announce ejabberd 20.04. In addition to various bugfixes and improvements, this release massively improves audio and video calls support.

ejabberd now implements XEP-0215: External Service Discovery, via the new mod_stun_disco module, which allows XMPP clients to discover STUN/TURN services and to obtain temporary credentials for using them.

The format of the temporary credentials handed out to clients is described in an IETF draft. Therefore, in addition of the ejabberd’s built-in STUN/TURN support, the module can also be used with external STUN/TURN servers that support the same draft (such as coturn or restund). It also allows (non-XMPP) WebRTC applications to use ejabberd’s built-in STUN/TURN support.

To promote this usage, STUN/TURN service is now enabled by default in ejabberd.

It means that ejabberd can now be used by modern clients with audio/video calls features. if you want to test it, Conversation or Movim clients already support XEP-0215.


1 Like

This is awesome work! Some comments:

  • Authentication should be disabled for STUN (it is very cheap, you can let anyone use it). Make sure your configuration means that.
  • You don’t seem to be listening on 5349 ports (but only on 3478) as advertised in the DNS configuration.
  • You can also turn on TLS/DTLS on the regular 3478. If ejabberd allows for it, you should do the same.

You should test your TURN/STUN servers using the trickle-ice web tool. For successful STUN setup, it will give a ‘srflx’ record in the output and for successful TURN setup, it will also give ‘relay’ in the output.

1 Like

Thanks for the feedback @sunil . I hope to have time next week to follow up on your observations and do some more testing.

Out of interest, is FreedomBox likely to adopt the new eJabberd release 20.04 anytime soon? Or is that quite a lot of work?

1 Like

The following extracts maybe useful from the Internet Engineering Task Force (IETF), PROPOSED STANDARD document, Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN), at:

This first helpful paragraph:

“The client learns the TURN server transport address through some unspecified means (e.g., configuration), and this address is typically used by many clients simultaneously.”

And then this more helpful section regarding the DNS SRV records set up:

6.1. Sending an Allocate Request

… The client also picks a server transport address, which SHOULD be done as follows. The client receives (perhaps through configuration) a domain name for a TURN server. The client then uses the DNS procedures described in [RFC5389], but using an SRV service name of “turn” (or “turns” for TURN over TLS) instead of “stun” (or “stuns”). For example, to find servers in the domain, the client performs a lookup for ‘’, ‘’, and ‘’ if the client wants to communicate with the server using UDP, TCP, or TLS-over-TCP, respectively. …

And this: “This section describes an optional procedure for STUN that allows a client to use DNS to determine the IP address and port of a server.” from [RFC5389], (as above)!

20.4 seems to be available in Debian unstable already and looks like it will transition into testing and buster-backports. However, FreedomBox stable will not use this version but instead use the stable version.

1 Like

Um, why? Are there important reasons do decide against this backport and what is possible, and needed to get calls working.

This is just the default FreedomBox policy. We have stable only by default and only give exceptions when absolutely needed. Currently that is FreedomBox itself and matrix-synapse (due to change in federation format). We could consider an exception for ejabberd too if needed. We need to ensure that security updates for ejabberd and dependencies will flow into backports and that there is no other way to provide STUN/TURN with ejabberd (such as by using Coturn, which is actually easier and better approach).

1 Like

Thank you, for explaining so well. Makes complete sense.

Trying to consider, as far as I understood, ejabberd only supports external coturn since v20.04, but I’m not sure if the internal STUN/TURN in stable could support audio and video calls in the new clients with a freedombox stable update.

Please update Ejabberd to the newest version.

Learned that it doesn’t, so audio and video requires a backported ejabberd.