[SOLVED] AV Calls (coturn) not working with ejabberd (XMPP) outside local network

Outside local network, audio and video calls cant get through to any xmpp clients.

If anyone has managed to get coturn working (or found any other solution) to have audio / video calls work outside of their local network, I’d really appreciate to know how they solved it.

Thanks in advance.

Checked that firewall lets traffic through?

ports are forwarded… and i do get a ping… any other check to do?

If you can ping on those ports from outside the firewall coming in, then that satisfies that.

I presume other functions like messaging and presence work fine?

Yeah… I finally came to a conclusion to just disable Coturn and proceed with using the ejabberd stun/turn server. I’m lucky I have a domain name, so I went with How to set up ejabberd video & voice calling / ProcessOne

For anyone following this; once coturn is removed (deactivated) please also do not forget to:

a. disable Automatically manage audio/video call setup in ejabberd configuration under plinth
b. run cockpit and activate ‘coturn-freedombox’ service in networking > firewall settings
c. if you have a router/modem make sure relevant ports are forwarded
d. I’m sharing my config below:

listen:
 ...
- port: 3478
  transport: udp
  module: ejabberd_stun
  use_turn: true
  turn_min_port: 49152
  turn_max_port: 50175
  turn_ip: <your_static_ip_goes_here>
  auth_type: user
- port: 5349
  transport: tcp
  module: ejabberd_stun
  use_turn: true
  tls: true
  turn_min_port: 49152
  turn_max_port: 50175
  ip: "::"
  turn_ip: <your_static_ip_goes_here>
...
modules:
  mod_disco: {}
...
  mod_stun_disco:
    credentials_lifetime: 1000d
    secret: <whateveritis>
    services:
    - host: <your_domain.com>
      port: 3478
      type: stun
      transport: tcp
      restricted: false
    - host: <your_domain.com>
      port: 3478
      type: stun
      transport: udp
      restricted: false
    - host: <your_domain.com>
      port: 3478
      type: turn
      transport: tcp
      restricted: false
    - host: <your_domain.com>
      port: 3478
      type: turn
      transport: udp
      restricted: false
...

Once ejabberd.yml is edited, dont forget to sudo systemctl restart ejabberd

Please note, my configuration works where I have a static IP and a domain name.
Hope it helps (anyone).

Regards,

Ged.

I have the same problem.
Can someone please confirm that using domain from freedombox.rocks means that Xmpp calls don’t work outside the home network?

It might be a long shot, but it has suspiciously common similarities with my post about TTRSS. There picking the second option (although the same) made it work. In plinth → apps → coturn I get the same two choices, but in this case picking the second option results to

Setting unchanged

antidoto,

I can confirm that ejabberd works outside the local network while using domain from ‘fbx.one’. Text, voice, and video work well. FreedomBox is exposed to internet via DMZ, and Coturn is running. So, if you are still having issues, I would check what ports are open at your router and where they are being directed within your network.

Jim

Thank you for your confirmation.
I have checked that all the necessary ports in my router for both ejabberd and coturn, but the issue still remains.
Every time I try to make a call outside the network. The recipients client rings but after a few second of “connecting” status, I get a message about “Connection Error”
Is there anyway I can get a log file?

Thanks for the info.

Just in case: in my ejabberd.yml file that service for STUN is missing. There is no TCP, only UDP. This matches the data reported for Coturn in Plinth, which does not specify its required protocols, though it does for TURN.

I don’t know if this silently restricts STUN’s capability or obstructs its operation. I have not modified the default configuration of that file. I have not yet been able to test whether AV works. I run FredomBox 25.9.3 on Debian 13.

Hi @problema

My initial post does go back some time and it has mistakes. Back then i was stumbling to try to get it to work.
Can’t say I’m “pro” now, but the configuration I’m using has turned out as below.

Some keypoints:

  • this configuration breaks FBX bosh
  • you need to create an upload folder /var/www/upload and give ownership to ejabberd
  • im using a static ip and own a domain name
  • i had to manually adjust my firewall and router port forward settings
  • the developers of ejabberd (process-one) have a nice mini-blog on how to tweak things. the series begin here. It’s worth taking a look at especially for configuring your dns settings.

adjust your_domain_name / your_static_ip / your_secret_key as necessary

###
###              ejabberd configuration file
###
### The parameters used in this configuration file are explained at
###
###       https://docs.ejabberd.im/admin/configuration
###
### The configuration file is written in YAML.
### *******************************************************
### *******           !!! WARNING !!!               *******
### *******     YAML IS INDENTATION SENSITIVE       *******
### ******* MAKE SURE YOU INDENT SECTIONS CORRECTLY *******
### *******************************************************
### Refer to http://en.wikipedia.org/wiki/YAML for the brief description.
###


# loglevel: Verbosity of log files generated by ejabberd
loglevel: info

# rotation: Disable ejabberd's internal log rotation, as the Debian package
# uses logrotate(8).
log_rotate_count: 0

# hosts: Domains served by ejabberd.
# You can define one or several, for example:
# hosts:
#   - "example.net"
#   - "example.com"
#   - "example.org"

hosts:
- "_your_domain_name_"

certfiles:
- "/etc/ejabberd/ejabberd.pem"
#  - /etc/letsencrypt/live/localhost/fullchain.pem
#  - /etc/letsencrypt/live/localhost/privkey.pem

# TLS configuration
define_macro:
  'TLS_CIPHERS': "HIGH:!aNULL:!eNULL:!3DES:@STRENGTH"
  'TLS_OPTIONS':
  - "no_sslv3"
  - "no_tlsv1"
  - "no_tlsv1_1"
  - "cipher_server_preference"
  - "no_compression"
    # 'DH_FILE': "/path/to/dhparams.pem"
    # generated with: openssl dhparam -out dhparams.pem 2048

c2s_ciphers: 'TLS_CIPHERS'
s2s_ciphers: 'TLS_CIPHERS'
c2s_protocol_options: 'TLS_OPTIONS'
s2s_protocol_options: 'TLS_OPTIONS'
# c2s_dhfile: 'DH_FILE'
# s2s_dhfile: 'DH_FILE'

listen:
- port: 5222
  ip: "::"
  module: ejabberd_c2s
  max_stanza_size: 262144
  shaper: c2s_shaper
  access: c2s
  starttls_required: true
  protocol_options: 'TLS_OPTIONS'
- port: 5223
  ip: "::"
  module: ejabberd_c2s
  max_stanza_size: 262144
  shaper: c2s_shaper
  access: c2s
  tls: false
  protocol_options: 'TLS_OPTIONS'
- port: 5269
  ip: "::"
  module: ejabberd_s2s_in
  max_stanza_size: 524288
- port: 5443
  ip: "::"
  module: ejabberd_http
  tls: true
  protocol_options: 'TLS_OPTIONS'
  request_handlers:
    /api: mod_http_api
    /bosh: mod_bosh
      ## /captcha: ejabberd_captcha
    /upload: mod_http_upload
    /ws: ejabberd_http_ws
- port: 5280
  ip: "::"
  module: ejabberd_http
  tls: false
  protocol_options: 'TLS_OPTIONS'
  request_handlers:
    /admin: ejabberd_web_admin
    /.well-known/acme-challenge: ejabberd_acme
    /mqtt: mod_mqtt
- port: 1883
  ip: "::"
  module: mod_mqtt
  backlog: 1000
- port: 8883
  ip: "::"
  module: mod_mqtt
  backlog: 1000
  tls: true
- port: 5349
  transport: tcp
  module: ejabberd_stun
  use_turn: true
  tls: true
  turn_min_port: 49152
  turn_max_port: 65535
  ip: "::"
  turn_ip: _your_static_ip
# --

## Disabling digest-md5 SASL authentication. digest-md5 requires plain-text
## password storage (see auth_password_format option).
disable_sasl_mechanisms:
- "digest-md5"
- "X-OAUTH2"

s2s_use_starttls: required

## Store the plain passwords or hashed for SCRAM:
auth_password_format: scram

## Full path to a script that generates the image.
## captcha_cmd: "/usr/share/ejabberd/captcha.sh"

acl:
  admin:
    user:
    - ""

  local:
    user_regexp: ""
  loopback:
    ip:
    - 127.0.0.0/8
    - ::1/128

access_rules:
  local:
    allow: local
  c2s:
    deny: blocked
    allow: all
  announce:
    allow: admin
  configure:
    allow: admin
  muc_create:
    allow: local
  pubsub_createnode:
    allow: local
  trusted_network:
    allow: loopback

api_permissions:
  "console commands":
    from:
    - ejabberd_ctl
    who: all
    what: "*"
  "admin access":
    who:
      access:
        allow:
        - acl: loopback
        - acl: admin
      oauth:
        scope: "ejabberd:admin"
        access:
          allow:
          - acl: loopback
          - acl: admin
    what:
    - "*"
    - "!stop"
    - "!start"
  "public commands":
    who:
      ip: 127.0.0.1/8
    what:
    - status
    - connected_users_number

shaper:
  normal:
    rate: 3000
    burst_size: 20000
  fast: 200000

shaper_rules:
  max_user_sessions: 10
  max_user_offline_messages:
    5000: admin
    100: all
  c2s_shaper:
    none: admin
    normal: all
  s2s_shaper: fast

modules:
  mod_adhoc: {}
  mod_admin_extra: {}
  mod_announce:
    access: announce
  mod_avatar: {}
  mod_blocking: {}
  mod_bosh: {}
  mod_caps: {}
  mod_carboncopy: {}
  mod_client_state: {}
  mod_configure: {}
  ## mod_delegation: {}   # for xep0356
  mod_disco: {}
  mod_fail2ban: {}
  mod_http_api: {}
  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"
  mod_last: {}
  mod_mam:
    assume_mam_usage: false
    default: always
    cache_life_time: 3600
    cache_size: 1000
    db_type: mnesia
    request_activates_archiving: false
  ##   ## Mnesia is limited to 2GB, better to use an SQL backend
  ##   ## For small servers SQLite is a good fit and is very easy
  ##   ## to configure. Uncomment this when you have SQL configured:
  ##   ## db_type: sql
  ##  assume_mam_usage: false
  ##  default: always
  mod_mqtt: {}
  mod_muc:
    access:
    - allow
    access_admin:
    - allow: admin
    access_create: muc_create
    access_persistent: muc_create
    access_mam:
    - allow
    default_room_options:
      mam: true
  mod_muc_admin: {}
  mod_offline:
    access_max_user_messages: max_user_offline_messages
  mod_ping: {}
  mod_pres_counter:
    count: 5
    interval: 60
  mod_privacy: {}
  mod_private: {}
  mod_pubsub:
    access_createnode: pubsub_createnode
    plugins:
    - flat
    - pep
    force_node_config:
      "eu.siacs.conversations.axolotl.*":
        access_model: open
      ## Avoid buggy clients to make their bookmarks public
      storage:bookmarks:
        access_model: whitelist
  mod_push: {}
  mod_push_keepalive: {}
  ## mod_register:
  ##   ## Only accept registration requests from the "trusted"
  ##   ## network (see access_rules section above).
  ##   ## Think twice before enabling registration from any
  ##   ## address. See the Jabber SPAM Manifesto for details:
  ##   ## https://github.com/ge0rg/jabber-spam-fighting-manifesto
  ##   ip_access: trusted_network
  mod_roster:
    versioning: true
  mod_s2s_dialback: {}
  mod_shared_roster: {}
  mod_sic: {}
  mod_stream_mgmt:
    resend_on_timeout: if_offline
  mod_stun_disco:
    credentials_lifetime: 1000d
    secret: _your_secret_key
    services:
    - host: _your_domain_name
      port: 3478
      type: stun
      transport: udp
    - host: _your_domain_name
      port: 3478
      type: turn
      transport: udp
    - host: _your_domain_name
      port: 5349
      type: stuns
      transport: tcp
    - host: _your_domain_name
      port: 5349
      type: turns
      transport: tcp
  mod_vcard:
    search: false
  mod_vcard_xupdate: {}
  mod_version: {}
auth_method: ldap
ldap_servers:
- "localhost"
ldap_base: "ou=users,dc=thisbox"

### Local Variables:
### mode: yaml
### End:
### vim: set filetype=yaml tabstop=8
s2s_certfile: "/etc/ejabberd/letsencrypt/_your_domain_name/ejabberd.pem"

Over the past years, i have come to say that serving xmpp is not for the very faint-hearted. But when i look at the freedom, privacy and functions it presents, i think its very underrated.
I hope you like it as much as i do.

Have fun!

1 Like