The TURN Server project contains the source code of a TURN
server and TURN client messaging library. Also, some extra programs
provided, for testing-only purposes.
See the INSTALL file for the building instructions.
After the build, you will have the following binary images:
- 1.
- turnserver: TURN Server relay. The compiled binary image of
the TURN Server program is located in bin/ sub-directory.
- 2.
- turnadmin: TURN administration tool. See README.turnadmin and
turnadmin man page.
- 3.
- turnutils_uclient. See README.turnutils and turnutils man
page.
- 4.
- turnutils_peer. See README.turnutils and turnutils man page.
- 5.
- turnutils_stunclient. See README.turnutils and turnutils man
page.
- 6.
- turnutils_rfc5769check. See README.turnutils and turnutils man
page.
In the "examples/scripts" sub-directory, you will find
the examples of command lines to be used to run the programs. The scripts
are meant to be run from examples/ sub-directory, for example:
$ cd examples $ ./scripts/secure_relay.sh
If the systemd development library is available, then it will
notify systemd about the server status.
To run the coturn server as a daemon use:
$ turnserver -o
Note that if you make any changes to the config file the server has to be
restarted.
Options note: turnserver has long and short option names,
for most options. Some options have only long form, some options have only
short form. Their syntax somewhat different, if an argument is required:
The short form must be used as this (for example):
$ turnserver -L 12.34.56.78
The long form equivalent must use the "=" character:
$ turnserver --listening-ip=12.34.56.78
If this is a flag option (no argument required) then their usage are the same,
for example:
$ turnserver -a
is equivalent to:
$ turnserver --lt-cred-mech
turnserver - a TURN relay server
implementation.
$ turnserver [-n | -c <config-file> ] [flags] [ --userdb=<userdb-file> | --psql-userdb=<db-conn-string> | --mysql-userdb=<db-conn-string> | --mongo-userdb=<db-conn-string> | --redis-userdb=<db-conn-string> ] [-z | --no-auth | -a | --lt-cred-mech ] [options]
$ turnserver -h
Config file settings:
- -n
- Do not use configuration file, use only command line parameters.
- -c
- Configuration file name (default - turnserver.conf). The format of config
file can be seen in the supplied examples/etc/turnserver.conf example
file. Long names of the options are used as the configuration items
names in the file. If not an absolute path is supplied, then the file is
searched in the following directories:
- current directory
- current directory etc/ sub-directory
- upper directory level etc/
- /etc/
- /usr/local/etc/
- installation directory /etc
User database settings:
- -b, --db,
--userdb
- SQLite user database file name (default - /var/db/turndb or
/usr/local/var/db/turndb or /var/lib/turn/turndb).
- -e,
--psql-userdb
- User database connection string for PostgreSQL. This database can be used
for long-term credentials mechanism, and it can store the secret value for
secret-based timed authentication in TURN REST API. The connection string
format is like that:
"host=<host> dbname=<dbname> user=<db-user>
password=<db-user-password> connect_timeout=<seconds>" (for
8.x or newer Postgres).
Or:
"postgresql://username:password@hostname:port/databasename"
(for 9.x or newer Postgres).
See the INSTALL file for more explanations and examples.
Also, see http://www.PostgreSQL.org for full PostgreSQL
documentation.
- -M,
--mysql-userdb
- User database connection string for MySQL or MariaDB. This database can be
used for long-term credentials mechanism, and it can store the secret
value for secret-based timed authentication in TURN REST API. The
connection string format is like that:
"host=<host> dbname=<dbname> user=<db-user>
password=<db-user-password> connect_timeout=<seconds>
read_timeout=<seconds>"
See the INSTALL file for more explanations and examples.
Also, see http://www.mysql.org or http://mariadb.org for full
MySQL documentation.
Optional connection string parameters for the secure
communications (SSL): ca, capath, cert, key, cipher (see
http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the command
options description).
- --secret-key-file
- This is the file path which contain secret key of aes encryption while
using MySQL password encryption. If you want to use in the MySQL
connection string the password in encrypted format, then set in this
option the file path of the secret key. The key which is used to encrypt
MySQL password. Warning: If this option is set, then MySQL password must
be set in "mysql-userdb" option in encrypted format! If you want
to use cleartext password then do not set this option!
- -J,
--mongo-userdb
- User database connection string for MongoDB. This database can be used for
long-term credentials mechanism, and it can store the secret value for
secret-based timed authentication in TURN REST API. The connection string
format is like that:
"mongodb://username:password@host:port/database?options"
See the INSTALL file for more explanations and examples.
Also, see http://docs.mongodb.org/manual/ for full MongoDB
documentation.
- -N,
--redis-userdb
- User database connection string for Redis. This database can be used for
long-term credentials mechanism, and it can store the secret value for
secret-based timed authentication in TURN REST API. The connection string
format is like that:
"ip=<ip-addr> dbname=<db-number>
password=<db-password> connect_timeout=<seconds>"
See the INSTALL file for more explanations and examples.
Also, see http://redis.io for full Redis documentation.
Flags:
- -v,
--verbose
- Moderate verbose mode.
- -V,
--Verbose
- Extra verbose mode, very annoying and not recommended.
- -o,
--daemon
- Run server as daemon.
--no-software-attribute Production mode: hide the software
version.
- -f,
--fingerprint
- Use fingerprints in the TURN messages. If an incoming request contains a
fingerprint, then TURN server will always add fingerprints to the messages
in this session, regardless of the per-server setting.
- -a,
--lt-cred-mech
- Use long-term credentials mechanism (this one you need for WebRTC
usage).
- -z,
--no-auth
- Do not use any credentials mechanism, allow anonymous access. Opposite to
-a and -A options. This is default option when no
authentication-related options are set. By default, no credential
mechanism is used - any user is allowed.
- --use-auth-secret
- TURN REST API flag. Flag that sets a special WebRTC authorization option
that is based upon authentication secret. The feature purpose is to
support "TURN Server REST API" as described in the TURN
REST API section below. This option uses timestamp as part of combined
username: usercombo -> "timestamp:username", turn user ->
usercombo, turn password -> base64(hmac(input_buffer =
usercombo, key = shared-secret)). This allows TURN credentials to be
accounted for a specific user id. If you don't have a suitable id, the
timestamp alone can be used. This option is just turns on secret-based
authentication. The actual value of the secret is defined either by option
static-auth-secret, or can be found in the turn_secret table in the
database.
- --oauth
- Support oAuth authentication, as in the third-party STUN/TURN RFC
7635.
- --dh566
- Use 566 bits predefined DH TLS key. Default size of the key is 2066.
- --dh1066
- Use 1066 bits predefined DH TLS key. Default size of the key is 2066.
- --no-tlsv1
- Do not allow TLSv1/DTLSv1 protocol.
- --no-tlsv1_1
- Do not allow TLSv1.1 protocol.
- --no-tlsv1_2
- Do not allow TLSv1.2/DTLSv1.2 protocol.
- --no-udp
- Do not start UDP client listeners.
- --no-tcp
- Do not start TCP client listeners.
- --no-tls
- Do not start TLS client listeners.
- --no-dtls
- Do not start DTLS client listeners.
- --no-udp-relay
- Do not allow UDP relay endpoints defined in RFC 5766, use only TCP relay
endpoints as defined in RFC 6062.
- --no-tcp-relay
- Do not allow TCP relay endpoints defined in RFC 6062, use only UDP relay
endpoints as defined in RFC 5766.
- --no-stdout-log
- Flag to prevent stdout log messages. By default, all log messages are
going to both stdout and to the configured log file. With this option
everything will be going to the log file only (unless the log file itself
is stdout).
- --syslog
- With this flag, all log will be redirected to the system log
(syslog).
- --simple-log
- This flag means that no log file rollover will be used, and the log file
name will be constructed as-is, without PID and date appendage. This
option can be used, for example, together with the logrotate tool.
- --new-log-timestamp
- Enable full ISO-8601 timestamp in all logs.
- --new-log-timestamp-format
- <format> Set timestamp format (in strftime(1) format)
- --log-binding
- Log STUN binding request. It is now disabled by default to avoid DoS
attacks.
- --secure-stun
- Require authentication of the STUN Binding request. By default, the
clients are allowed anonymous access to the STUN Binding
functionality.
- -S,
--stun-only
- Run as STUN server only, all TURN requests will be ignored. Option to
suppress TURN functionality, only STUN requests will be processed.
- --no-stun
- Run as TURN server only, all STUN requests will be ignored. Option to
suppress STUN functionality, only TURN requests will be processed.
- --allow-loopback-peers
- Allow peers on the loopback addresses (127.x.x.x and ::1). Allow it only
for testing in a development environment! In production it adds a possible
security vulnerability, and so due to security reasons, it is not allowed
using it together with empty cli-password.
- --no-multicast-peers
- Disallow peers on well-known broadcast addresses (224.0.0.0 and above, and
FFXX:*).
- --mobility
- Mobility with ICE (MICE) specs support.
- --no-cli
- Turn OFF the CLI support. By default it is always ON. See also
options --cli-ip and --cli-port.
- --server-relay
- Server relay. NON-STANDARD AND DANGEROUS OPTION. Only for those
applications when we want to run server applications on the relay
endpoints. This option eliminates the IP permissions check on the packets
incoming to the relay endpoints. See
http://tools.ietf.org/search/rfc5766#section-17.2.3 .
- --udp-self-balance
- (recommended for older Linuxes only) Automatically balance UDP traffic
over auxiliary servers (if configured). The load balancing is using the
ALTERNATE-SERVER mechanism. The TURN client must support 300
ALTERNATE-SERVER response for this functionality.
- --check-origin-consistency
- The flag that sets the origin consistency check: across the session, all
requests must have the same main ORIGIN attribute value (if the ORIGIN was
initially used by the session).
- --prometheus
- Enable prometheus metrics. By default it is disabled. Would listen on port
9641 under the path /metrics also the path / on this port can be used as a
health check
- --prometheus-port
- Prometheus listener port (Default: 9641).
- --prometheus-username-labels
- Enable labeling prometheus traffic metrics with client usernames. Labeling
with client usernames is disabled by default, because this may cause
memory leaks when using authentication with ephemeral usernames (e.g. TURN
REST API).
- -h
- Help.
Options with values:
- --stale-nonce[=<value>]
- Use extra security with nonce value having limited lifetime, in seconds
(default 600 secs). Set it to 0 for unlimited nonce lifetime.
- --max-allocate-lifetime
- Set the maximum value for the allocation lifetime. Default to 3600
secs.
- --channel-lifetime
- Set the lifetime for channel binding, default to 600 secs. This value MUST
not be changed for production purposes.
- --permission-lifetime
- Set the value for the lifetime of the permission. Default to 300 secs.
This MUST not be changed for production purposes.
- -d,
--listening-device
- Listener interface device. (NOT RECOMMENDED. Optional functionality, Linux
only). The turnserver process must have root privileges to bind the
listening endpoint to a device. If turnserver must run as a process
without root privileges, then just do not use this setting.
- -L,
--listening-ip
- Listener IP address of relay server. Multiple listeners can be specified,
for example: -L ip1 -L ip2 -L ip3 If no IP(s)
specified, then all IPv4 and IPv6 system IPs will be used for listening.
The same ip(s) can be used as both listening and relay
ip(s).
- -p,
--listening-port
- TURN listener port for UDP and TCP listeners (Default: 3478). Note:
actually, TLS & DTLS sessions can connect to the "plain" TCP
& UDP port(s), too - if allowed by configuration.
- --tls-listening-port
- TURN listener port for TLS and DTLS listeners (Default: 5349). Note:
actually, "plain" TCP & UDP sessions can connect to the TLS
& DTLS port(s), too - if allowed by configuration. The TURN
server "automatically" recognizes the type of traffic. Actually,
two listening endpoints (the "plain" one and the "tls"
one) are equivalent in terms of functionality; but we keep both endpoints
to satisfy the RFC 5766 specs. For secure TCP connections, we currently
support SSL version 3 and TLS versions 1.0, 1.1, 1.2. For secure UDP
connections, we support DTLS version 1.
- --alt-listening-port
- Alternative listening port for UDP and TCP listeners; default (or zero)
value means "listening port plus one". This is needed for STUN
CHANGE_REQUEST - in RFC 5780 sense or in old RFC 3489 sense - for NAT
behavior discovery). The TURN Server supports CHANGE_REQUEST only
if it is started with more than one listening IP address of the same
family (IPv4 or IPv6). The CHANGE_REQUEST is only supported by UDP
protocol, other protocols are listening on that endpoint only for
"symmetry".
- --alt-tls-listening-port
- Alternative listening port for TLS and DTLS protocols. Default (or zero)
value means "TLS listening port plus one".
- --tcp-proxy-port
- Support connections from TCP loadbalancer on this port. The loadbalancer
should use the binary proxy protocol.
(https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)
- --aux-server
- Auxiliary STUN/TURN server listening endpoint. Aux servers have almost
full TURN and STUN functionality. The (minor) limitations are:
- 1)
- Auxiliary servers do not have alternative ports and they do not support
STUN RFC 5780 functionality (CHANGE REQUEST).
- 2)
- Auxiliary servers also are never returning ALTERNATIVE-SERVER reply.
Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for
IPv6. There may be multiple aux-server options, each will be used for
listening to client requests.
- -i,
--relay-device
- Relay interface device for relay sockets (NOT RECOMMENDED. Optional, Linux
only).
- -E,
--relay-ip
- Relay address (the local IP address that will be used to relay the packets
to the peer). Multiple relay addresses may be used: -E ip1
-E ip2 -E ip3 The same IP(s) can be used as both
listening IP(s) and relay IP(s). If no relay IP(s)
specified, then the turnserver will apply the default policy: it
will decide itself which relay addresses to be used, and it will always be
using the client socket IP address as the relay IP address of the TURN
session (if the requested relay address family is the same as the family
of the client socket).
- -X,
--external-ip
- TURN Server public/private address mapping, if the server is behind
NAT. In that situation, if a -X is used in form "-X
<ip>" then that ip will be reported as relay IP address of all
allocations. This scenario works only in a simple case when one single
relay address is be used, and no CHANGE_REQUEST functionality is required.
That single relay address must be mapped by NAT to the 'external' IP. The
"external-ip" value, if not empty, is returned in
XOR-RELAYED-ADDRESS field. For that 'external' IP, NAT must forward ports
directly (relayed port 12345 must be always mapped to the same 'external'
port 12345). In more complex case when more than one IP address is
involved, that option must be used several times, each entry must have
form "-X <public-ip/private-ip>", to map all
involved addresses. CHANGE_REQUEST (RFC5780 or RFC3489) NAT discovery STUN
functionality will work correctly, if the addresses are mapped properly,
even when the TURN server itself is behind A NAT. By default, this value
is empty, and no address mapping is used.
- -m,
--relay-threads
- Number of the relay threads to handle the established connections (in
addition to authentication thread and the listener thread). If explicitly
set to 0 then application runs relay process in a single thread, in the
same thread with the listener process (the authentication thread will
still be a separate thread). If not set, then a default optimal algorithm
will be employed (OS-dependent). In the older Linux systems (before Linux
kernel 3.9), the number of UDP threads is always one threads per network
listening endpoint - unless "-m 0" or "-m
1" is set.
- --min-port
- Lower bound of the UDP port range for relay endpoints allocation. Default
value is 49152, according to RFC 5766.
- --max-port
- Upper bound of the UDP port range for relay endpoints allocation. Default
value is 65535, according to RFC 5766.
- -u,
--user
- Long-term security mechanism credentials user account, in the
column-separated form username:key. Multiple user accounts may be used in
the command line. The key is either the user password, or the key is
generated by turnadmin command. In the second case, the key must be
prepended with 0x symbols. The key is calculated over the user name, the
user realm, and the user password. This setting may not be used with TURN
REST API.
- -r,
--realm
- The default realm to be used for the users when no explicit origin/realm
relationship was found in the database, or if the TURN server is not using
any database (just the commands-line settings and the userdb file). Must
be used with long-term credentials mechanism or with TURN REST API.
- -C,
--rest-api-separator
- This is the timestamp/username separator symbol (character) in TURN REST
API. The default value is :.
- -q,
--user-quota
- Per-user allocations quota: how many concurrent allocations a user can
create. This option can also be set through the database, for a particular
realm.
- -Q,
--total-quota
- Total allocations quota: global limit on concurrent allocations. This
option can also be set through the database, for a particular realm.
- -s,
--max-bps
- Max bytes-per-second bandwidth a TURN session is allowed to handle (input
and output network streams are treated separately). Anything above that
limit will be dropped or temporary suppressed (within the available buffer
limits). This option can also be set through the database, for a
particular realm.
- -B,
--bps-capacity
- Maximum server capacity. Total bytes-per-second bandwidth the TURN server
is allowed to allocate for the sessions, combined (input and output
network streams are treated separately).
- --static-auth-secret
- Static authentication secret value (a string) for TURN REST API only. If
not set, then the turn server will try to use the dynamic value in
turn_secret table in user database (if present). The database-stored value
can be changed on-the-fly by a separate program, so this is why that other
mode is dynamic. Multiple shared secrets can be used (both in the database
and in the "static" fashion).
- --server-name
- Server name used for the oAuth authentication purposes. The default value
is the realm name.
- --cert
- Certificate file, PEM format. Same file search rules applied as for the
configuration file. If both --no-tls and --no-dtls
options are specified, then this parameter is not needed. Default
value is turn_server_cert.pem.
- --pkey
- Private key file, PEM format. Same file search rules applied as for the
configuration file. If both --no-tls and --no-dtls
options are specified, then this parameter is not needed. Default
value is turn_server_pkey.pem.
- --pkey-pwd
- If the private key file is encrypted, then this password to be used.
- --cipher-list
- Allowed OpenSSL cipher list for TLS/DTLS connections. Default value is
"DEFAULT".
- --CA-file
- CA file in OpenSSL format. Forces TURN server to verify the client SSL
certificates. By default, no CA is set and no client certificate check is
performed.
- --ec-curve-name
- Curve name for EC ciphers, if supported by OpenSSL library (TLS and DTLS).
The default value is prime256v1, if pre-OpenSSL 1.0.2 is used. With
OpenSSL 1.0.2+, an optimal curve will be automatically calculated, if not
defined by this option.
- --dh-file
- Use custom DH TLS key, stored in PEM format in the file. Flags
--dh566 and --dh1066 are ignored when the DH key is taken
from a file.
- -l,
--log-file
- Option to set the full path name of the log file. By default, the
turnserver tries to open a log file in /var/log/turnserver,
/var/log, /var/tmp, /tmp and . (current) directories (which file open
operation succeeds first that file will be used). With this option you can
set the definite log file name. The special names are "stdout"
and "-" - they will force everything to the stdout. Also,
"syslog" name will redirect everything into the system log
(syslog), as if the option "--syslog" was set. In the
runtime, the logfile can be reset with the SIGHUP signal to the
turnserver process.
- --alternate-server
- Option to set the "redirection" mode. The value of this option
will be the address of the alternate server for UDP & TCP service in
form of <ip>[:<port>]. The server will send this value in the
attribute ALTERNATE-SERVER, with error 300, on ALLOCATE request, to the
client. Client will receive only values with the same address family as
the client network endpoint address family. See RFC 5389 and RFC 5766 for
ALTERNATE-SERVER functionality description. The client must use the
obtained value for subsequent TURN communications. If more than one
--alternate-server options are provided, then the
functionality can be more accurately described as
"load-balancing" than a mere "redirection". If the
port number is omitted, then the default port number 3478 for the UDP/TCP
protocols will be used. Colon (:) characters in IPv6 addresses may
conflict with the syntax of the option. To alleviate this conflict,
literal IPv6 addresses are enclosed in square brackets in such resource
identifiers, for example: [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 .
Multiple alternate servers can be set. They will be used in the
round-robin manner. All servers in the pool are considered of equal weight
and the load will be distributed equally. For example, if we have 4
alternate servers, then each server will receive 25% of ALLOCATE requests.
An alternate TURN server address can be used more than one time with the
alternate-server option, so this can emulate "weighting" of the
servers.
- --tls-alternate-server
- Option to set alternative server for TLS & DTLS services in form of
<ip>:<port>. If the port number is omitted, then the default
port number 5349 for the TLS/DTLS protocols will be used. See the previous
option for the functionality description.
- -O,
--redis-statsdb
- Redis status and statistics database connection string, if used (default -
empty, no Redis stats DB used). This database keeps allocations status
information, and it can be also used for publishing and delivering traffic
and allocation event notifications. This database option can be used
independently of --redis-userdb option, and actually Redis can be
used for status/statistics and SQLite or MySQL or MongoDB or PostgreSQL
can be used for the user database. The connection string has the same
parameters as redis-userdb connection string.
- --max-allocate-timeout
- Max time, in seconds, allowed for full allocation establishment. Default
is 60 seconds.
--denied-peer-ip=<IPaddr[-IPaddr]>
--allowed-peer-ip=<IPaddr[-IPaddr]> Options to
ban or allow specific ip addresses or ranges of ip addresses. If an ip
address is specified as both allowed and denied, then the ip address is
considered to be allowed. This is useful when you wish to ban a range of ip
addresses, except for a few specific ips within that range. This can be used
when you do not want users of the turn server to be able to access machines
reachable by the turn server, but would otherwise be unreachable from the
internet (e.g. when the turn server is sitting behind a NAT). The
'white" and "black" peer IP ranges can also be dynamically
changed in the database. The allowed/denied addresses (white/black lists)
rules are very simple:
- 1)
- If there is no rule for an address, then it is allowed;
- 2)
- If there is an "allowed" rule that fits the address then it is
allowed - no matter what;
- 3)
- If there is no "allowed" rule that fits the address, and if
there is a "denied" rule that fits the address, then it is
denied.
- --pidfile
- File name to store the pid of the process. Default is
/var/run/turnserver.pid (if superuser account is used) or
/var/tmp/turnserver.pid .
- --acme-redirect
- <URL> Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests,
i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to
<URL>$1 with $1 == (.*). No validation of <URL> will be done,
so make sure you do not forget the trailing slash. If <URL> is an
empty string (the default value), no special handling of such requests
will be done.
- --proc-user
- User name to run the process. After the initialization, the
turnserver process will make an attempt to change the current user
ID to that user.
- --proc-group
- Group name to run the process. After the initialization, the
turnserver process will make an attempt to change the current group
ID to that group.
- -K,
--keep-address-family
- Deprecated and will be removed in favor of
--allocation-default-address-family!! TURN server allocates address
family according TURN Client <=> Server communication address
family. !! It breaks RFC6156 section-4.2 (violates default IPv4) !!
- -A
--allocation-default-address-family=<ipv4|ipv6|keep>
- Default is IPv4 TURN server allocates address family according TURN client
requested address family. If address family not requested explicitly by
the client, then it falls back to this default. The standard RFC
explicitly define that this default must be IPv4, so use other option
values with care!
- --cli-ip
- Local system IP address to be used for CLI management interface. The
turnserver process can be accessed for management with telnet, at
this IP address and on the CLI port (see the next parameter). Default
value is 127.0.0.1. You can use telnet or putty (in telnet mode) to access
the CLI management interface.
- --cli-port
- CLI management interface listening port. Default is 5766.
- --cli-password
- CLI access password. Default is empty (no password). For the security
reasons, it is recommended to use the encrypted form of the password (see
the -P command in the turnadmin utility). The dollar signs
in the encrypted form must be escaped.
- --cli-max-output-sessions
- Maximum number of output sessions in ps CLI command. This value can be
changed on-the-fly in CLI. The default value is 256.
- --web-admin
- Enable Turn Web-admin support. By default it is disabled.
- --web-admin-ip=<IP>
- Local system IP address to be used for Web-admin server endpoint. Default
value is 127.0.0.1.
- --web-admin-port=<port>
- Web-admin server port. Default is 8080.
- --web-admin-listen-on-workers
- Enable for web-admin server to listens on STUN/TURN workers STUN/TURN
ports. By default it is disabled for security reasons! (This behavior used
to be the default behavior, and was enabled by default.)
- --ne=[1|2|3]
- Set network engine type for the process (for internal purposes).
- --no-rfc5780
- Disable RFC5780 (NAT behavior discovery). Originally, if there are more
than one listener address from the same address family, then by default
the NAT behavior discovery feature enabled. This option disables this
original behavior, because the NAT behavior discovery adds attributes to
response, and this increase the possibility of an amplification attack.
Strongly encouraged to use this option to decrease gain factor in STUN
binding responses.
- --no-stun-backward-compatibility
- Disable handling old STUN Binding requests and disable MAPPED-ADDRESS
attribute in binding response (use only the XOR-MAPPED-ADDRESS).
- --response-origin-only-with-rfc5780
- Only send RESPONSE-ORIGIN attribute in binding response if RFC5780 is
enabled.
This topic is covered in the wiki page:
https://github.com/coturn/coturn/wiki/turn_performance_and_load_balance
This is a set of notes for the WebRTC users:
- 1)
- WebRTC uses long-term authentication mechanism, so you have to use
-a option (or --lt-cred-mech). WebRTC relaying will not work
with anonymous access. With -a option, do not forget to set the
default realm (-r option). You will also have to set up the user
accounts, for that you have a number of options:
a) command-line options (-u).
b) a database table (SQLite or PostgreSQL or MySQL or MongoDB). You will have to
set keys with turnadmin utility (see docs and wiki for turnadmin).
You cannot use open passwords in the database.
c) Redis key/value pair(s), if Redis is used. You key use either keys or
open passwords with Redis; see turndb/testredisdbsetup.sh file.
d) You also can use the TURN REST API. You will need shared secret(s) set
either through the command line option, or through the config file, or through
the database table or Redis key/value pairs.
- 2)
- Usually WebRTC uses fingerprinting (-f).
- 3)
- -v option may be nice to see the connected clients.
- 4)
- -X is needed if you are running your TURN server behind a NAT.
- 5)
- --min-port and --max-port may be needed if you want to limit
the relay endpoints ports number range.
In WebRTC, the browser obtains the TURN connection information
from the web server. This information is a secure information - because it
contains the necessary TURN credentials. As these credentials are
transmitted over the public networks, we have a potential security
breach.
If we have to transmit a valuable information over the public
network, then this information has to have a limited lifetime. Then the guy
who obtains this information without permission will be able to perform only
limited damage.
This is how the idea of TURN REST API - time-limited TURN
credentials - appeared. This security mechanism is based upon the long-term
credentials mechanism. The main idea of the REST API is that the web server
provides the credentials to the client, but those credentials can be used
only limited time by an application that has to create a TURN server
connection.
The "classic" long-term credentials mechanism (LTCM) is
described here:
http://tools.ietf.org/html/rfc5389#section-10.2
http://tools.ietf.org/html/rfc5389#section-15.4
For authentication, each user must know two things: the username
and the password. Optionally, the user must supply the ORIGIN value, so that
the server can figure out the realm to be used for the user. The nonce and
the realm values are supplied by the TURN server. But LTCM is not saying
anything about the nature and about the persistence of the username and of
the password; and this is used by the REST API.
In the TURN REST API, there is no persistent passwords for users.
A user has just the username. The password is always temporary, and it is
generated by the web server on-demand, when the user accesses the WebRTC
page. And, actually, a temporary one-time session only, username is provided
to the user, too.
The temporary user is generated as:
temporary-username="timestamp" + ":" +
"username"
where username is the persistent user name, and the timestamp
format is just seconds since 1970 - the same value as time(NULL)
function returns.
The temporary password is obtained as HMAC-SHA1 function over the
temporary username, with shared secret as the HMAC key, and then the result
is encoded:
temporary-password = base64_encode(hmac-sha1(shared-secret,
temporary-username))
Both the TURN server and the web server know the same shared
secret. How the shared secret is distributed among the involved entities is
left to the WebRTC deployment details - this is beyond the scope of the TURN
REST API.
So, a timestamp is used for the temporary password calculation,
and this timestamp can be retrieved from the temporary username. This
information is valuable, but only temporary, while the timestamp is not
expired. Without knowledge of the shared secret, a new temporary password
cannot be generated.
This is all formally described in Justin's Uberti TURN REST API
document that can be obtained following the link "TURN REST API"
in the TURN Server project's page
https://github.com/coturn/coturn/.
Once the temporary username and password are obtained by the
client (browser) application, then the rest is just 'classic" long-term
credentials mechanism. For developers, we are going to describe it
step-by-step below:
- a new TURN client sends a request command to the TURN server. Optionally,
it adds the ORIGIN field to it.
- TURN server sees that this is a new client and the message is not
authenticated.
- the TURN server generates a random nonce string, and return the error 401
to the client, with nonce and realm included. If the ORIGIN field was
present in the client request, it may affect the realm value that the
server chooses for the client.
- the client sees the 401 error and it extracts two values from the error
response: the nonce and the realm.
- the client uses username, realm and password to produce a key:
key = MD5(username ":" realm ":" SASLprep(password))
(SASLprep is described here: http://tools.ietf.org/html/rfc4013)
- the client forms a new request, adds username, realm and nonce to the
request. Then, the client calculates and adds the integrity field to the
request. This is the trickiest part of the process, and it is described in
the end of section 15.4:
http://tools.ietf.org/html/rfc5389#section-15.4
- the client, optionally, adds the fingerprint field. This may be also a
tricky procedure, described in section 15.5 of the same document. WebRTC
usually uses fingerprinted TURN messages.
- the TURN server receives the request, reads the username.
- then the TURN server checks that the nonce and the realm in the request
are the valid ones.
- then the TURN server calculates the key.
- then the TURN server calculates the integrity field.
- then the TURN server compares the calculated integrity field with the
received one - they must be the same. If the integrity fields differ, then
the request is rejected.
In subsequent communications, the client may go with exactly the
same sequence, but for optimization usually the client, having already
information about realm and nonce, pre-calculates the integrity string for
each request, so that the 401 error response becomes unnecessary. The TURN
server may use "--stale-nonce" option for extra security:
in some time, the nonce expires and the client will obtain 438 error
response with the new nonce, and the client will have to start using the new
nonce.
In subsequent communications, the server and the client will
always assume the same password - the original password becomes the session
parameter and is never expiring. So the password is not changing while the
session is valid and unexpired. So, if the session is properly maintained,
it may go forever, even if the user password has been already changed (in
the database). The session simply is using the old password. Once the
session got disconnected, the client will have to use the new password to
re-connect (if the password has been changed).
An example when a new shared secret is generated every hour by the
TURN server box and then supplied to the web server, remotely, is provided
in the script examples/scripts/restapi/shared_secret_maintainer.pl .
A very important thing is that the nonce must be totally random
and it must be different for different clients and different sessions.
For the user database, the turnserver has the following
options:
- 1)
- Users can be set in the command line, with multiple -u or
--user options. Obviously, only a few users can be set that
way, and their credentials are fixed for the turnserver process
lifetime.
- 2)
- Users can be stored in SQLite DB. The default SQLite database file is
/var/db/turndb or /usr/local/var/db/turndb or /var/lib/turn/turndb.
- 3)
- Users can be stored in PostgreSQL database, if the turnserver was
compiled with PostgreSQL support. Each time turnserver checks user
credentials, it reads the database (asynchronously, of course, so that the
current flow of packets is not delayed in any way), so any change in the
database content is immediately visible by the turnserver. This is
the way if you need the best scalability. The schema for the database can
be found in schema.sql file. For long-term credentials, you have to set
the "keys" for the users; the "keys" are generated by
the turnadmin utility. For the key generation, you need username,
password and the realm. All users in the database must use the same realm
value; if down the road you will decide to change the realm name, then you
will have to re-generate all user keys (that can be done in a batch
script). See the file turndb/testsqldbsetup.sql as an example.
- 4)
- The same is true for MySQL database. The same schema file is applicable.
The same considerations are applicable.
- 5)
- The same is true for the Redis database, but the Redis database has a
different schema - it can be found (in the form of explanation) in
schema.userdb.redis. Also, in Redis you can store both "keys"
and open passwords (for long term credentials) - the "open
password" option is less secure but more convenient for low-security
environments. See the file turndb/testredisdbsetup.sh as an example.
- 6)
- If a database is used, then users can be divided into multiple independent
realms. Each realm can be administered separately, and each realm can have
its own set of users and its own performance options (max-bps,
user-quota, total-quota).
- 7)
- If you use MongoDB, the database will be setup for you automatically.
- 8)
- Of course, the turnserver can be used in non-secure mode, when
users are allowed to establish sessions anonymously. But in most cases
(like WebRTC) that will not work.
For the status and statistics database, there are two choices:
- 1)
- The simplest choice is not to use it. Do not set --redis-statsdb
option, and this functionality will be simply ignored.
- 2)
- If you choose to use it, then set the --redis-statsdb option. This
may be the same database as in --redis-userdb option, or it may be
a different database. You may want to use different database for security
or convenience reasons. Also, you can use different database management
systems for the user database and for the ststus and statistics database.
For example, you can use MySQL as the user database, and you can use redis
for the statistics. Or you can use Redis for both.
So, we have 6 choices for the user management, and 2 choices for
the statistics management. These two are totally independent. So, you have
overall 6*2=12 ways to handle persistent information, choose any for your
convenience.
You do not have to handle the database information
"manually" - the turnadmin program can handle everything
for you. For PostgreSQL and MySQL you will just have to create an empty
database with schema.sql SQL script. With Redis, you do not have to do even
that - just run turnadmin and it will set the users for you (see the
turnadmin manuals). If you are using SQLite, then the
turnserver or turnadmin will initialize the empty database,
for you, when started. The TURN server installation process creates an empty
initialized SQLite database in the default location (/var/db/turndb or
/usr/local/var/db/turndb or /var/lib/turn/turndb, depending on the
system).
The server supports ALPNs "stun.turn" and
"stun.nat-discovery", when compiled with OpenSSL 1.0.2 or newer.
If the server receives a TLS/DTLS ClientHello message that contains one or
both of those ALPNs, then the server chooses the first stun.* label and
sends it back (in the ServerHello) in the ALPN extension field. If no stun.*
label is found, then the server does not include the ALPN information into
the ServerHello.
In the lib/ sub-directory the build process will create TURN
client messaging library. In the include/ sub-directory, the necessary
include files will be placed. The C++ wrapper for the messaging
functionality is located in TurnMsgLib.h header. An example of C++ code can
be found in stunclient.c file.
After installation, run the command:
$ man turnserver
or in the project root directory:
$ man -M man turnserver
to see the man page.
In the docs/html subdirectory of the original archive tree, you
will find the client library reference. After the installation, it will be
placed in PREFIX/share/doc/turnserver/html.
When the TURN Server starts, it makes efforts to create a
log file turn_<pid>.log in the following directories:
- /var/log
- /log/
- /var/tmp
- /tmp
- current directory
If all efforts failed (due to the system permission settings) then
all log messages are sent only to the standard output of the process.
This behavior can be controlled by --log-file,
--syslog and --no-stdout-log options.
The turnserver process provides an HTTPS Web access as
statistics and basic management interface. The turnserver listens to
incoming HTTPS admin connections on the same ports as the main TURN/STUN
listener. The Web admin pages are basic and self-explanatory.
To make the HTTPS interface active, the database table admin_user
must be populated with the admin user account(s). An admin user can
be a superuser (if not assigned to a particular realm) or a restricted user
(if assigned to a realm). The restricted admin users can perform only
limited actions, within their corresponding realms.
The turnserver process provides a telnet CLI access as
statistics and basic management interface. By default, the turnserver
starts a telnet CLI listener on IP 127.0.0.1 and port 5766. That can be
changed by the command-cline options of the turnserver process
(see --cli-ip and --cli-port options). The full list of
telnet CLI commands is provided in "help" command output in the
telnet CLI.
TURN Server can be a part of the cluster installation. But,
to support the "even port" functionality (RTP/RTCP streams pairs)
the client requests from a particular IP must be delivered to the same
TURN Server instance, so it requires some networking setup massaging
for the cluster. The reason is that the RTP and RTCP relaying endpoints must
be allocated on the same relay IP. It would be possible to design a scheme
with the application-level requests forwarding (and we may do that later)
but it would affect the performance.
/etc/turnserver.conf
/var/db/turndb
/usr/local/var/db/turndb
/var/lib/turn/turndb
/usr/local/etc/turnserver.conf
/usr/local/share/turnserver
/usr/local/share/doc/turnserver
/usr/local/share/examples/turnserver
obsolete STUN RFC 3489
new STUN RFC 5389
TURN-TCP extension RFC 6062
TURN IPv6 extension RFC 6156
STUN/TURN test vectors RFC 5769
STUN NAT behavior discovery RFC 5780
project page:
https://github.com/coturn/coturn/
Wiki page:
https://github.com/coturn/coturn/wiki
forum:
https://groups.google.com/forum/?fromgroups=#!forum/turn-server-project-rfc5766-turn-server
Oleg Moskalenko <mom040267@gmail.com>
Gabor Kovesdan http://kovesdan.org/
Daniel Pocock http://danielpocock.com/
John Selbie (jselbie@gmail.com)
Lee Sylvester <lee@designrealm.co.uk>
Erik Johnston <erikj@openmarket.com>
Roman Lisagor <roman@demonware.net>
Vladimir Tsanev <tsachev@gmail.com>
Po-sheng Lin <personlin118@gmail.com>
Peter Dunkley <peter.dunkley@acision.com>
Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>
Federico Pinna <fpinna@vivocha.com>
Bradley T. Hughes <bradleythughes@fastmail.fm>
Mihály Mészáros <misi@majd.eu>
Mihály Mészáros <misi@majd.eu>