How to set up ejabberd video & voice calling

Last time, I described how to set up ejabberd real time IM server and migrate your office to XMPP chat. In this tutorial I will explain how to configure ejabberd video & voice calling.

I assume the ejabberd 20.03 configuration from that previous tutorial as a start. It turns out, if you try ejabberd video & voice calling within your local network, it just works. If your office is on the same LAN or Wi-Fi, everyone will be able to voice or video call each other. Follow the setup from my previous tutorial. To achieve the best result, everyone should use the same chat app (“client”) on their phones or computers.

But that’s not good enough. You want your office staff to communicate no matter the location. You could use an office VPN. But all devices connected to it should appear as if on the same local network. That’s a significant overhead, especially for smartphones.

Lucky for us, ProcessOne just released ejabberd 20.04. This new version has a built-in STUN/TURN server. It simplifies service discoverability between clients. This helps chat apps setup a direct link between each other no matter the network they are on. And makes ejabberd video & voice calling possible.

» Don’t want to configure ejabberd video & voice calling yourself?
ProcessOne experts will make your business instantly connected. Contact us »

ejabberd video & voice calling

Updating ejabberd

First, we need to update our current ejabberd instance to version 20.04 or newer. Be sure to make a backup. Please read the upgrade procedure docs to check the migration notes. Once ready, proceed with the update:

wget -O ejabberd_20.04.deb
apt install ./ejabberd_20.04.deb
/etc/init.d/ejabberd start

Configuring STUN/TURN for ejabberd video & voice calling

Now, we need to edit ejabberd.yml configuration file to enable STUN/TURN discovery using mod_stun_disco. Add the following somewhere at the bottom of the modules section:

    credentials_lifetime: 12h
          port: 3478
          type: stun
          transport: udp
          restricted: false
          port: 3478
          type: turn
          transport: udp
          restricted: true
          port: 5349
          type: stuns
          transport: tcp
          restricted: false
          port: 5349
          type: turns
          transport: tcp
          restricted: true

Substitute with the IP address of your ejabberd server, and with your ejabberd domain. Also, make sure your server & firewall allows connections on ports 3478, 5349.

Finally, we have to actually listen for STUN/TURN traffic. We need to add new listeners in the listen section at the top of that configuration file:

    port: 3478
    transport: udp
    module: ejabberd_stun
    use_turn: true
    turn_min_port: 49152
    turn_max_port: 65535
    ## The server's public IPv4 address:
    port: 5349
    transport: tcp
    module: ejabberd_stun
    use_turn: true
    tls: true
    turn_min_port: 49152
    turn_max_port: 65535

Substitute with the IP address of your ejabberd server. Make sure that server & firewall allows connections in the range of ports from 49152 to 65535.

Configuring ejabberd STUN/TURN domain records (DNS)

There are a few extra steps to make it easier for clients to discover the STUN/TURN services. Create a list of SRV records under your main ejabberd domain:

_stun._udp   IN SRV  0 0 3478
_stun._tcp   IN SRV  0 0 3478
_stuns._tcp  IN SRV  0 0 5349

_turn._udp   IN SRV  0 0 3478
_turn._tcp   IN SRV  0 0 3478
_turns._tcp  IN SRV  0 0 5349

Different domain providers have different names in the forms to set up such records. The above listings are usually split this way:

  • service: stun
  • protocol: udp or tcp
  • priority: 0
  • weight: 0
  • port: 3478 or 5349
  • target:

Testing ejabberd video & voice calling

In this tutorial I have tested ejabberd video & voice calling using two Android devices. Both were running Conversations. One device was on my local Wi-Fi while the other was on LTE. Both ejabberd video & voice calls were established quickly and the quality was between good and excellent.

Sometimes you may experience long delays while establishing calls. In that case try adjusting the shaper settings in ejabberd configuration as follows:

    rate: 3000
    burst_size: 20000
  fast: 100000

» Do you need a more specific solution?
ProcessOne experts are ready to help. Contact us »

What’s next?

ejabberd server has a lot more to offer. We could experiment with BOSH or WebSocket connections that are useful for web applications. We could try and set up an MQTT broker. Let me know in the comments what kind of tutorials you want the most. For now, let’s tweak your ejabberd server to get 100% in the XMPP compliance test.

In this ejabberd tutorial series:

Photo by Harry Cunningham on Unsplash

Let us know what you think 💬

34 thoughts on “How to set up ejabberd video & voice calling

  1. It’s just great that ejabberd now supports audio and video calls. Thanks for this tutorial. Personally I lilke to see another one about how to set up BOSH.

  2. Does this setting not support passwords hashed in SCRAM?
    Does this setting only support plaintext passwords story?

      • Not exactly. Although ejabberd STUN/TURN server doesn’t support SCRAM, the settings in my tutorial rely on default ejabberd config that uses SCRAM. Conversations client relies on a temporary auth tokens, and this works with SCRAM.

  3. Hey, thank you so much for this great tutorial.
    I was able to make audio/video calls using Conversations until I had to reboot my server.
    After the reboot I can’t make any video/audio calls.
    The devices can’t succesfully establish connection.
    Can you help me please?

    • If you rebooted your server, it’s possible ejabberd didn’t start on your server boot. Check running command `/etc/init.d/ejabberd status` and if it’s not running then `/etc/init.d/ejabberd start`, otherwise `/etc/init.d/ejabberd restart`.

      • Hey Marek, thank you very much for your reply.
        Ejabberd is running, everything is working just fine, I can send messages with no problem.
        My only problem is connecting the devices to successfully establish the call.
        It only works inside my local network. Before you ask, the ports for the turn/stun server are open.

        When I reboot the server I usually run “./bin/ejabberdctl start” anyway I tried the commands you suggested and the result is the same.

        Could it be related with the fact that I didn’t the SRV records on the DNS provider?

        Sorry if I said something dumb.

  4. Hi, Thank you for this post. I would love to see how you connect the ejabberd server to a web application (website). I am trying to create a web live chat on an ejabberd server. The web live chat I am creating is similar to the ones seen on e-commerce websites used for customer support.

    Thanks in advance for your reply.

    • Yes. You don’t need a STUN/TURN server for that, it will just work. But, your ejabberd server needs to be inside your LAN and your config file needs to use the local IP address of this server. Additionally, you most likely have to ensure all servers and clients inside your LAN correctly resolve your ejabberd server domain. So if accounts on your ejabberd look like, each server and client should have in its hosts file an entry with pointing to ejabberd server local IP address.

        • He probado varias, para chat, en general todas funcionan bien, para llamadas estoy tratando con Jitsi (el software cliente los soporta, pero recién estoy probando voz.

  5. @Marek Foss, Can you link the version of conversations used for video call? I cant seem to see that option in the one i downloaded from the playstore. Did you build from source?

  6. Hola Marek Foss he quedado super impresionado con este proyecto y de verdad que lo estoy usando y tratando de sacar el máximo provecho aunque todavía no he entendido como configurarlo al 100 %.
    Estoy intentando configurar los servidores STUN / TURN para video ejabberd y llamadas de voz y no me ha resultado muy facil, por favor podrias explicarme mejor como hacerlo, yo uso Windows.
    He recomendado este grandioso proyecto a muchos de mis amigos y que bueno que encontre ese blog para ayuda.
    Por favor me podrias contactar en privado por mi correo.
    Muchas gracias por esta super herramienta, un saludo desde Cuba, recuerda contactarme.

    • Yes, but on the client side, so it depends on the client implementation. Conversations, for example, encrypts the calls.

    • What do you mean? I tested the connection between users registered on the same ejabberd server and domain, but interop should work as well.

      • Thx for your answer.
        I mean, is the stun/turn services are publicly reachable or is only usable by users of ejabberd server itself (and their contacts on others servers to reach them) ?
        Great “how to” anyway, work like a charm.

        • Thanks, glad it works well! By default, so in this tutorial as well, the stun/turn server setting is “auth_type: user” meaning ejabberd authentication backend is used, but that doesn’t block external people from calling you. It is enough if at least one party has a stun/turn server: in case you are calling someone, it will give that person your reachable address and port; in case someone is calling you, that person will receive your reachable address and port from your stun/turn server. So you should be able to call anyone, and everyone should be able to call you. However, there can be issues with some home routers that exhibit terrible network behaviour around port forwarding ;)

  7. According to your «how to» and documentation with «auth_realm» option, I have to multiply listen port for each virtual host. I understand that multiple vhost can’t share the same couple of stun/turn port (5349/3478). Right ?

    Another thing, «turn_ip» is deprecated according to log at launch, «turn_ipv4_address» must be used with 20.07 version.

  8. I digress about the original subject. I saw that ejabberd support the sip protocol, do you know if it is possible to make a call from sip to xmpp ?
    ty again for your answer.

  9. How to deal with dynamic ip addresses? I’m using ejabberd on a server in my basement with an ip address that changes every night. Until now clients connect via DynDNS, which works perfectly fine. However, STUN and TURN seem to require static ips, is that correct?
    So how can I use STUN/TURN with dynamic IPs?

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.