How to provide custom TURN server settings when using a classic email account

I am using Delta Chat with an existing email setup, and I wanted to test calls in the android app. Unfortunately there is no UI to configure TURN server settings, and the builtin server is not reachable from my lan. So here are the instructions to configure the IMAP server to provide TURN server address to the client.

Prerequisites

  1. Existing coturn installation configured with static-auth-secret.
  2. Existing dovecot installation used as a classic email account. The server is configured with virtual users database and runs as vmail system user. All user mailboxes are stored in /home/vmail.

What Delta Chat expects

The client fetches TURN server address and credentials from the IMAP server by reading INBOX metadata item /shared/vendor/deltachat/turn. The value should be a string of the form:

server.address.or.domain:port_number:username:password

TURN server credentials

When coturn is configured with static-auth-secret it expects temporary time-limited usernames and passwords for authentication. To generate the credentials place this script in /etc/periodic/hourly/update-turn-server-credentials.sh, or arrange to run it hourly using some other mechanism.

#!/bin/sh

turn_sever_address=turn.example.com
turn_server_port=3478
static_auth_secret="your static-auth-secret value"

now=$(date +%s)
expires=$((now+3600*2))

password=$(printf "%s" "$expires" | openssl dgst -sha1 -hmac "$static_auth_secret" -binary | openssl enc -base64 -A)

printf "%s:%s:%s:%s" "$turn_server_address" "$turn_server_port" "$expires" "$password" > /var/lib/turn-server-info

This will write the TURN server information and credentials valid for two hours in the format Delta Chat expects to /var/lib/turn-server-info every hour. Run this one manually once, and verify that /var/lib/turn-server-info exists and has the right format.

Dovecot configuration

We need to enable IMAP metadata support in the server, so Delta Chat can read TURN server info. To do that, in your dovecot config file add the section to configure attribute storage in plain files:

mail_attribute {
  dict fs {
    fs posix {
      prefix = %{home}/attributes/
    }
  }
}

This sets the attributes storage directory in the virtual user’s home, next to the usual Maildir. Then inside the protocol imap block add imap_metadata = yes:

protocol imap {
  imap_metadata = yes
}

Restart the dovecot server after updating config file.

User-specific configuration

This needs to be done once for each new user.

Write the TURN attribute using doveadm, the actual value is not important:

doveadm mailbox metadata set -u "username" -s "" /shared/vendor/deltachat/turn x

Dovecot creates the actual directories and files in the user’s home. Now find the mailbox GUID for your user by running:

doveadm mailbox status -u "username" guid "INBOX"

This will print something like:

INBOX guid=888390389af833cdde

The string after = is the mailbox GUID that is used as a directory name. After that replace attribute file with a symbolic link to /var/lib/turn-server-info:

ln -sf /var/lib/turn-server-info /home/vmail/username/attributes/INBOX_guid_here/vendor/vendor.dovecot/pvt/server/vendor/deltachat/turn

And verify the results by running:

doveadm mailbox metadata get -u "username" -s "" /shared/vendor/deltachat/turn

This command should print the contents of /var/lib/turn-server-info.

Results

In my setup this allows sharing an existing coturn installation with other services, like galene.

5 Likes

Great work!

If one doesn’t really care about persistent TURN credentials leaking, this can be further simplified, as I suggested here:

first of all, welcome aboard, @Janus. then, thanks a lot for the guide!

indeed, i heard questions about that here and there. good thing with this approach is that one does not need to annoy end user to tweak some more weird settings. nor devs then discussing if settings on that level of detail, for potentially few user, are worth the effort :slight_smile:

thanks again :heart:

It would be nice if it was simply packaged in an app so that any user could enter the turn key and gain access to calls.