{"id":3500,"date":"2020-06-17T05:56:07","date_gmt":"2020-06-17T05:56:07","guid":{"rendered":"http:\/\/truelogic.org\/wordpress\/?p=3500"},"modified":"2020-06-17T05:56:10","modified_gmt":"2020-06-17T05:56:10","slug":"setup-your-own-stun-turn-server-using-coturn","status":"publish","type":"post","link":"https:\/\/truelogic.org\/wordpress\/2020\/06\/17\/setup-your-own-stun-turn-server-using-coturn\/","title":{"rendered":"Setup Your Own STUN\/TURN Server using Coturn"},"content":{"rendered":"\n<p><strong>OVERVIEW<\/strong><\/p>\n\n\n\n<p>It is easy to find free STUN servers but there are no free TURN servers available. We are lucky that the people at Coturn have deployed an open-source TURN\/STUN server implementation which is up-to-date with the latest RFC-5766 specs. <a rel=\"noreferrer noopener\" aria-label=\"https:\/\/github.com\/coturn\/coturn (opens in a new tab)\" href=\"https:\/\/github.com\/coturn\/coturn\" target=\"_blank\">https:\/\/github.com\/coturn\/coturn<\/a><\/p>\n\n\n\n<p>Coturn allows us to setup our own STUN\/TURN server for WebRTC use. In this article we look at how to set it up on a Linux server. The steps are applicable to CentOS and Ubuntu\/Debian based distros.<\/p>\n\n\n\n<p><strong>INSTALLATION<\/strong><\/p>\n\n\n\n<p>Update your repositories: <code>sudo apt-get update <\/code><\/p>\n\n\n\n<p>Install Coturn: <code>sudo apt-get install coturn<\/code><\/p>\n\n\n\n<p>Once installation completes, the coturn service automatically starts. We need to stop it so that we can finish the configuration: <code>sudo systemctl stop coturn<\/code><\/p>\n\n\n\n<p>We will now setup a user which will run the turnserver process. This user will be added to the configuration setup of the turnserver:<\/p>\n\n\n\n<p><code>sudo adduser turnadmin<\/code><\/p>\n\n\n\n<p>Set a password for turnadmin to complete the process. It is not necessary to use turnadmin as a user. You can setup any user &#8211; new or existing. <\/p>\n\n\n\n<p>We will now add turnadmin to the <code>root<\/code> group. This is required because in some cases the turnadmin process is unable to access certain resources and fails to start otherwise. <\/p>\n\n\n\n<p><code>sudo usermod -a -G root turnadmin<\/code><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>SETUP SSL CERTIFICATES<\/strong><\/p>\n\n\n\n<p>This step is optional if you only plan to use Coturn as a STUN server. If you want to implement it as a TURN server also, then SSL is required.<\/p>\n\n\n\n<p><code>sudo apt install certbot<\/code><\/p>\n\n\n\n<p>If there is a webserver already running , stop that service first. Then run the command below for certbot to start a temporary webserver to generate the certificates:<\/p>\n\n\n\n<p><code>sudo certbot certonly  --standalone<\/code><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Once the key generation process is over, you will find the certificate files in <code>\/etc\/letsencrypt\/live\/&lt;domain<\/code>&gt; where &lt;domain&gt; is the domain of your server. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>CONFIGURATION<\/strong><\/p>\n\n\n\n<p>We will setup the configuration for coturn now. <\/p>\n\n\n\n<p><code>cd \/etc\/coturn<\/code><\/p>\n\n\n\n<p>Copy the two certificate files <code>cert.pem<\/code> and <code>privkey.pem<\/code> from <code>\/etc\/letsencrypt\/live\/&lt;domain<\/code>>  to this directory<\/p>\n\n\n\n<p>Make a backup of the default configuration file before making changes to it:<\/p>\n\n\n\n<p><code>cp turnserver.conf turnserver.conf.bak<\/code><\/p>\n\n\n\n<p>The following lines are to be put in turnserver.conf . Disable or comment out any other lines:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Coturn TURN SERVER configuration file\n#\n# Boolean values note: where boolean value is supposed to be used,\n# you can use '0', 'off', 'no', 'false', 'f' as 'false, \n# and you can use '1', 'on', 'yes', 'true', 't' as 'true' \n# If the value is missed, then it means 'true'.\n#\n\n# Listener interface device (optional, Linux only).\n# NOT RECOMMENDED. \n#\n#listening-device=eth0\n\n# TURN listener port for UDP and TCP (Default: 3478).\n# Note: actually, TLS &amp; DTLS sessions can connect to the \n# \"plain\" TCP &amp; UDP port(s), too - if allowed by configuration.\n#\nlistening-port=3478\n\n# TURN listener port for TLS (Default: 5349).\n# Note: actually, \"plain\" TCP &amp; UDP sessions can connect to the TLS &amp; DTLS\n# port(s), too - if allowed by configuration. The TURN server \n# \"automatically\" recognizes the type of traffic. Actually, two listening\n# endpoints (the \"plain\" one and the \"tls\" one) are equivalent in terms of\n# functionality; but we keep both endpoints to satisfy the RFC 5766 specs.\n# For secure TCP connections, we currently support SSL version 3 and \n# TLS version 1.0, 1.1 and 1.2.\n# For secure UDP connections, we support DTLS version 1.\n#\ntls-listening-port=5349\n\n# Alternative listening port for UDP and TCP listeners;\n# default (or zero) value means \"listening port plus one\". \n# This is needed for RFC 5780 support\n# (STUN extension specs, NAT behavior discovery). The TURN Server \n# supports RFC 5780 only if it is started with more than one \n# listening IP address of the same family (IPv4 or IPv6).\n# RFC 5780 is supported only by UDP protocol, other protocols\n# are listening to that endpoint only for \"symmetry\".\n#\nalt-listening-port=3479\n\t\t\t\t\t\t\t \n# Alternative listening port for TLS and DTLS protocols.\n# Default (or zero) value means \"TLS listening port plus one\".\n#\nalt-tls-listening-port=5350\n\t\n# Listener IP address of relay server. Multiple listeners can be specified.\n# If no IP(s) specified in the config file or in the command line options, \n# then all IPv4 and IPv6 system IPs will be used for listening.\n#\n#listening-ip=172.17.19.101\n#listening-ip=10.207.21.238\n#listening-ip=2607:f0d0:1002:51::4\n\n# Auxiliary STUN\/TURN server listening endpoint.\n# Aux servers have almost full TURN and STUN functionality.\n# The (minor) limitations are:\n#\n# 1) Auxiliary servers do not have alternative ports and\n# they do not support STUN RFC 5780 functionality (CHANGE REQUEST).\n#\n# 2) Auxiliary servers also are never returning ALTERNATIVE-SERVER reply.\n# \n# Valid formats are 1.2.3.4:5555 for IPv4 and &#91;1:2::3:4]:5555 for IPv6.\n#\n# There may be multiple aux-server options, each will be used for listening\n# to client requests.\n#\n#aux-server=172.17.19.110:33478\n#aux-server=&#91;2607:f0d0:1002:51::4]:33478\n\n# (recommended for older Linuxes only)\n# Automatically balance UDP traffic over auxiliary servers (if configured).\n# The load balancing is using the ALTERNATE-SERVER mechanism.\n# The TURN client must support 300 ALTERNATE-SERVER response for this \n# functionality.\n#\n#udp-self-balance\n\n# Relay interface device for relay sockets (optional, Linux only).\n# NOT RECOMMENDED.\n#\n#relay-device=eth1\n\n# Relay address (the local IP address that will be used to relay the \n# packets to the peer).\n# Multiple relay addresses may be used.\n# The same IP(s) can be used as both listening IP(s) and relay IP(s).\n#\n# If no relay IP(s) specified, then the turnserver will apply the default\n# policy: it will decide itself which relay addresses to be used, and it \n# will always be using the client socket IP address as the relay IP address\n# of the TURN session (if the requested relay address family is the same\n# as the family of the client socket).\n#\n#relay-ip=172.17.19.105\n#relay-ip=2607:f0d0:1002:51::5\n\n# For Amazon EC2 users:\n#\n# TURN Server public\/private address mapping, if the server is behind NAT.\n# In that situation, if a -X is used in form \"-X &lt;ip>\" then that ip will be reported\n# as relay IP address of all allocations. This scenario works only in a simple case\n# when one single relay address is be used, and no RFC5780 functionality is required.\n# That single relay address must be mapped by NAT to the 'external' IP.\n# The \"external-ip\" value, if not empty, is returned in XOR-RELAYED-ADDRESS field.\n# For that 'external' IP, NAT must forward ports directly (relayed port 12345\n# must be always mapped to the same 'external' port 12345).\n#\n# In more complex case when more than one IP address is involved,\n# that option must be used several times, each entry must\n# have form \"-X &lt;public-ip\/private-ip>\", to map all involved addresses.\n# RFC5780 NAT discovery STUN functionality will work correctly,\n# if the addresses are mapped properly, even when the TURN server itself \n# is behind A NAT.\n#\n# By default, this value is empty, and no address mapping is used.\n#\n#external-ip=60.70.80.91\n#\n#OR:\n#\n#external-ip=60.70.80.91\/172.17.19.101\n#external-ip=60.70.80.92\/172.17.19.102\n\n\n# Number of the relay threads to handle the established connections\n# (in addition to authentication thread and the listener thread).\n# If explicitly set to 0 then application runs relay process in a \n# single thread, in the same thread with the listener process \n# (the authentication thread will still be a separate thread).\n#\n# If this parameter is not set, then the default OS-dependent \n# thread pattern algorithm will be employed. Usually the default\n# algorithm is the most optimal, so you have to change this option\n# only if you want to make some fine tweaks. \n#\n# In the older systems (Linux kernel before 3.9),\n# the number of UDP threads is always one thread per network listening\n# endpoint - including the auxiliary endpoints - unless 0 (zero) or \n# 1 (one) value is set.\n#\n#relay-threads=0\n\n# Lower and upper bounds of the UDP relay endpoints:\n# (default values are 49152 and 65535)\n#\n#min-port=49152\n#max-port=65535\n\t\n# Uncomment to run TURN server in 'normal' 'moderate' verbose mode.\n# By default the verbose mode is off.\nverbose\n\t\n# Uncomment to run TURN server in 'extra' verbose mode.\n# This mode is very annoying and produces lots of output.\n# Not recommended under any normal circumstances.\n#\t\n#Verbose\n\n# Uncomment to use fingerprints in the TURN messages.\n# By default the fingerprints are off.\n#\nfingerprint\n\n# Uncomment to use long-term credential mechanism.\n# By default no credentials mechanism is used (any user allowed).\n#\nlt-cred-mech\n\n# This option is opposite to lt-cred-mech. \n# (TURN Server with no-auth option allows anonymous access).\n# If neither option is defined, and no users are defined,\n# then no-auth is default. If at least one user is defined, \n# in this file or in command line or in usersdb file, then\n# lt-cred-mech is default.\n#\n#no-auth\n\n# TURN REST API flag.\n# (Time Limited Long Term Credential)\n# Flag that sets a special authorization option that is based upon authentication secret.\n#\n# This feature's purpose is to support \"TURN Server REST API\", see\n# \"TURN REST API\" link in the project's page \n# https:\/\/github.com\/coturn\/coturn\/\n#\n# This option is used with timestamp:\n# \n# usercombo -> \"timestamp:userid\"\n# turn user -> usercombo\n# turn password -> base64(hmac(secret key, usercombo))\n#\n# This allows TURN credentials to be accounted for a specific user id.\n# If you don't have a suitable id, the timestamp alone can be used.\n# This option is just turning on secret-based authentication.\n# The actual value of the secret is defined either by option static-auth-secret,\n# or can be found in the turn_secret table in the database (see below).\n# \n# Read more about it:\n#  - https:\/\/tools.ietf.org\/html\/draft-uberti-behave-turn-rest-00\n#  - https:\/\/www.ietf.org\/proceedings\/87\/slides\/slides-87-behave-10.pdf\n#\n# Be aware that use-auth-secret overrides some part of lt-cred-mech.\n# Notice that this feature depends internally on lt-cred-mech, so if you set\n# use-auth-secret then it enables internally automatically lt-cred-mech option\n# like if you enable both.\n#\n# You can use only one of the to auth mechanisms in the same time because,\n# both mechanism use the username and password validation in different way.\n#\n# This way be aware that you can't use both auth mechnaism in the same time!\n# Use in config either the lt-cred-mech or the use-auth-secret\n# to avoid any confusion.\n#\n#use-auth-secret\n\n# 'Static' authentication secret value (a string) for TURN REST API only. \n# If not set, then the turn server\n# will try to use the 'dynamic' value in turn_secret table\n# in user database (if present). The database-stored  value can be changed on-the-fly\n# by a separate program, so this is why that other mode is 'dynamic'.\n#\n#static-auth-secret=north\n\n# Server name used for\n# the oAuth authentication purposes.\n# The default value is the realm name.\n#\nserver-name=yoursite.com\n\n# Flag that allows oAuth authentication.\n#\n#oauth\n\n# 'Static' user accounts for long term credentials mechanism, only.\n# This option cannot be used with TURN REST API.\n# 'Static' user accounts are NOT dynamically checked by the turnserver process, \n# so that they can NOT be changed while the turnserver is running.\n#\nuser=turnadmin:turnpwd\n#user=username2:key2\n# OR:\n#user=username1:password1\n#user=username2:password2\n#\n# Keys must be generated by turnadmin utility. The key value depends\n# on user name, realm, and password:\n#\n# Example:\n# $ turnadmin -k -u ninefingers -r north.gov -p youhavetoberealistic\n# Output: 0xbc807ee29df3c9ffa736523fb2c4e8ee\n# ('0x' in the beginning of the key is what differentiates the key from\n# password. If it has 0x then it is a key, otherwise it is a password).\n#\n# The corresponding user account entry in the config file will be:\n# \n#user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee\n# Or, equivalently, with open clear password (less secure):\n#user=ninefingers:youhavetoberealistic\n#\n\n# SQLite database file name.\n#\n# Default file name is \/var\/db\/turndb or \/usr\/local\/var\/db\/turndb or\n# \/var\/lib\/turn\/turndb.\n# \n#userdb=\/var\/db\/turndb\n\n# PostgreSQL database connection string in the case that we are using PostgreSQL\n# as the user database.\n# This database can be used for long-term credential mechanism\n# and it can store the secret value for secret-based timed authentication in TURN RESP API. \n# See http:\/\/www.postgresql.org\/docs\/8.4\/static\/libpq-connect.html for 8.x PostgreSQL\n# versions connection string format, see \n# http:\/\/www.postgresql.org\/docs\/9.2\/static\/libpq-connect.html#LIBPQ-CONNSTRING\n# for 9.x and newer connection string formats.\n#\n#psql-userdb=\"host=&lt;host> dbname=&lt;database-name> user=&lt;database-user> password=&lt;database-user-password> connect_timeout=30\"\n\n# MySQL database connection string in the case that we are using MySQL\n# as the user database.\n# This database can be used for long-term credential mechanism\n# and it can store the secret value for secret-based timed authentication in TURN RESP API.\n#\n# Optional connection string parameters for the secure communications (SSL): \n# ca, capath, cert, key, cipher \n# (see http:\/\/dev.mysql.com\/doc\/refman\/5.1\/en\/ssl-options.html for the \n# command options description).\n#\n# Use string format as below (space separated parameters, all optional):\n#\n#mysql-userdb=\"host=&lt;host> dbname=&lt;database-name> user=&lt;database-user> password=&lt;database-user-password> port=&lt;port> connect_timeout=&lt;seconds> read_timeout=&lt;seconds>\"\n\n# If you want to use in the MySQL connection string the password in encrypted format,\n# then set in this option the MySQL password encryption secret key file.\n#\n# Warning: If this option is set, then mysql password must be set in \"mysql-userdb\" in encrypted format! \n# If you want to use cleartext password then do not set this option!\n#\n# This is the file path which contain secret key of aes encryption while using password encryption.\n#\n#secret-key-file=\/path\/\n\n# MongoDB database connection string in the case that we are using MongoDB\n# as the user database.\n# This database can be used for long-term credential mechanism\n# and it can store the secret value for secret-based timed authentication in TURN RESP API. \n# Use string format is described at http:\/\/hergert.me\/docs\/mongo-c-driver\/mongoc_uri.html\n#\n#mongo-userdb=\"mongodb:\/\/&#91;username:password@]host1&#91;:port1]&#91;,host2&#91;:port2],...&#91;,hostN&#91;:portN]]]&#91;\/&#91;database]&#91;?options]]\"\n\n# Redis database connection string in the case that we are using Redis\n# as the user database.\n# This database can be used for long-term credential mechanism\n# and it can store the secret value for secret-based timed authentication in TURN RESP API. \n# Use string format as below (space separated parameters, all optional):\n#\n#redis-userdb=\"ip=&lt;ip-address> dbname=&lt;database-number> password=&lt;database-user-password> port=&lt;port> connect_timeout=&lt;seconds>\"\n\n# Redis status and statistics database connection string, if used (default - empty, no Redis stats DB used).\n# This database keeps allocations status information, and it can be also used for publishing\n# and delivering traffic and allocation event notifications.\n# The connection string has the same parameters as redis-userdb connection string. \n# Use string format as below (space separated parameters, all optional):\n#\n#redis-statsdb=\"ip=&lt;ip-address> dbname=&lt;database-number> password=&lt;database-user-password> port=&lt;port> connect_timeout=&lt;seconds>\"\n\n# The default realm to be used for the users when no explicit \n# origin\/realm relationship was found in the database, or if the TURN\n# server is not using any database (just the commands-line settings\n# and the userdb file). Must be used with long-term credentials \n# mechanism or with TURN REST API.\n#\n# Note: If default realm is not specified at all, then realm falls back to the host domain name.\n#       If domain name is empty string, or '(None)', then it is initialized to am empty string.\n#\nrealm=yoursite.com\n\n# The flag that sets the origin consistency \n# check: across the session, all requests must have the same\n# main ORIGIN attribute value (if the ORIGIN was\n# initially used by the session).\n#\n#check-origin-consistency\n\n# Per-user allocation quota.\n# default value is 0 (no quota, unlimited number of sessions per user).\n# This option can also be set through the database, for a particular realm.\n#\n#user-quota=0\n\n# Total allocation quota.\n# default value is 0 (no quota).\n# This option can also be set through the database, for a particular realm.\n#\n#total-quota=0\n\n# Max bytes-per-second bandwidth a TURN session is allowed to handle\n# (input and output network streams are treated separately). Anything above\n# that limit will be dropped or temporary suppressed (within\n# the available buffer limits).\n# This option can also be set through the database, for a particular realm.\n#\n#max-bps=0\n\n#\n# Maximum server capacity.\n# Total bytes-per-second bandwidth the TURN server is allowed to allocate\n# for the sessions, combined (input and output network streams are treated separately).\n#\n# bps-capacity=0\n\n# Uncomment if no UDP client listener is desired.\n# By default UDP client listener is always started.\n#\n#no-udp\n\n# Uncomment if no TCP client listener is desired.\n# By default TCP client listener is always started.\n#\n#no-tcp\n\n# Uncomment if no TLS client listener is desired.\n# By default TLS client listener is always started.\n#\n#no-tls\n\n# Uncomment if no DTLS client listener is desired.\n# By default DTLS client listener is always started.\n#\n#no-dtls\n\n# Uncomment if no UDP relay endpoints are allowed.\n# By default UDP relay endpoints are enabled (like in RFC 5766).\n#\n#no-udp-relay\n\n# Uncomment if no TCP relay endpoints are allowed.\n# By default TCP relay endpoints are enabled (like in RFC 6062).\n#\n#no-tcp-relay\n\n# Uncomment if extra security is desired,\n# with nonce value having limited lifetime.\n# By default, the nonce value is unique for a session,\n# and has unlimited lifetime. \n# Set this option to limit the nonce lifetime. \n# It defaults to 600 secs (10 min) if no value is provided. After that delay, \n# the client will get 438 error and will have to re-authenticate itself.\n#\n#stale-nonce=600\n\n# Uncomment if you want to set the maximum allocation\n# time before it has to be refreshed.\n# Default is 3600s.\n#\n#max-allocate-lifetime=3600\n\n\n# Uncomment to set the lifetime for the channel.\n# Default value is 600 secs (10 minutes).\n# This value MUST not be changed for production purposes.\n#\n#channel-lifetime=600\n\n# Uncomment to set the permission lifetime.\n# Default to 300 secs (5 minutes).\n# In production this value MUST not be changed,\n# however it can be useful for test purposes.\n#\n#permission-lifetime=300\n\n# Certificate file.\n# Use an absolute path or path relative to the \n# configuration file.\n#\n#cert=\/etc\/pki\/coturn\/public\/turn_server_cert.pem\ncert=\/etc\/coturn\/cert.pem\n\n# Private key file.\n# Use an absolute path or path relative to the \n# configuration file.\n# Use PEM file format.\n#\n#pkey=\/etc\/pki\/coturn\/private\/turn_server_pkey.pem\npkey=\/etc\/coturn\/privkey.pem\n\n# Private key file password, if it is in encoded format.\n# This option has no default value.\n#\n#pkey-pwd=...\n\n# Allowed OpenSSL cipher list for TLS\/DTLS connections.\n# Default value is \"DEFAULT\".\n#\ncipher-list=\"DEFAULT\"\n\n# CA file in OpenSSL format. \n# Forces TURN server to verify the client SSL certificates.\n# By default it is not set: there is no default value and the client\n# certificate is not checked.\n#\n# Example:\n#CA-file=\/etc\/ssh\/id_rsa.cert\n\n# Curve name for EC ciphers, if supported by OpenSSL \n# library (TLS and DTLS). The default value is prime256v1, \n# if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,\n# an optimal curve will be automatically calculated, if not defined\n# by this option.\n#\n#ec-curve-name=prime256v1\n\n# Use 566 bits predefined DH TLS key. Default size of the key is 1066.\n#\n#dh566\n\n# Use 2066 bits predefined DH TLS key. Default size of the key is 1066.\n#\n#dh2066\n\n# Use custom DH TLS key, stored in PEM format in the file.\n# Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file.\n#\n#dh-file=&lt;DH-PEM-file-name>\n\n# Flag to prevent stdout log messages.\n# By default, all log messages are going to both stdout and to \n# the configured log file. With this option everything will be \n# going to the configured log only (unless the log file itself is stdout).\n#\n#no-stdout-log\n\n# Option to set the log file name.\n# By default, the turnserver tries to open a log file in \n# \/var\/log, \/var\/tmp, \/tmp and current directories directories\n# (which open operation succeeds first that file will be used).\n# With this option you can set the definite log file name.\n# The special names are \"stdout\" and \"-\" - they will force everything \n# to the stdout. Also, the \"syslog\" name will force everything to\n# the system log (syslog). \n# In the runtime, the logfile can be reset with the SIGHUP signal \n# to the turnserver process.\n#\nlog-file=\/var\/log\/coturn\/turnserver.log\n\n# Option to redirect all log output into system log (syslog).\n#\n#syslog\n\n# This flag means that no log file rollover will be used, and the log file\n# name will be constructed as-is, without PID and date appendage.\n# This option can be used, for example, together with the logrotate tool.\n#\nsimple-log\n\n# Option to set the \"redirection\" mode. The value of this option\n# will be the address of the alternate server for UDP &amp; TCP service in form of \n# &lt;ip>&#91;:&lt;port>]. The server will send this value in the attribute\n# ALTERNATE-SERVER, with error 300, on ALLOCATE request, to the client.\n# Client will receive only values with the same address family\n# as the client network endpoint address family. \n# See RFC 5389 and RFC 5766 for ALTERNATE-SERVER functionality description. \n# The client must use the obtained value for subsequent TURN communications.\n# If more than one --alternate-server options are provided, then the functionality\n# can be more accurately described as \"load-balancing\" than a mere \"redirection\". \n# If the port number is omitted, then the default port \n# number 3478 for the UDP\/TCP protocols will be used.\n# Colon (:) characters in IPv6 addresses may conflict with the syntax of \n# the option. To alleviate this conflict, literal IPv6 addresses are enclosed \n# in square brackets in such resource identifiers, for example: \n# &#91;2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . \n# Multiple alternate servers can be set. They will be used in the\n# round-robin manner. All servers in the pool are considered of equal weight and \n# the load will be distributed equally. For example, if we have 4 alternate servers, \n# then each server will receive 25% of ALLOCATE requests. A alternate TURN server \n# address can be used more than one time with the alternate-server option, so this \n# can emulate \"weighting\" of the servers.\n#\n# Examples: \n#alternate-server=1.2.3.4:5678\n#alternate-server=11.22.33.44:56789\n#alternate-server=5.6.7.8\n#alternate-server=&#91;2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478\n\t\t\t\n# Option to set alternative server for TLS &amp; DTLS services in form of \n# &lt;ip>:&lt;port>. If the port number is omitted, then the default port \n# number 5349 for the TLS\/DTLS protocols will be used. See the previous \n# option for the functionality description.\n#\n# Examples: \n#tls-alternate-server=1.2.3.4:5678\n#tls-alternate-server=11.22.33.44:56789\n#tls-alternate-server=&#91;2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478\n\n# Option to suppress TURN functionality, only STUN requests will be processed.\n# Run as STUN server only, all TURN requests will be ignored.\n# By default, this option is NOT set.\n#\n#stun-only\n\n# Option to suppress STUN functionality, only TURN requests will be processed.\n# Run as TURN server only, all STUN requests will be ignored.\n# By default, this option is NOT set.\n#\n#no-stun\n\n# This is the timestamp\/username separator symbol (character) in TURN REST API.\n# The default value is ':'.\n# rest-api-separator=:\t\n\n# Flag that can be used to allow peers on the loopback addresses (127.x.x.x and ::1).\n# This is an extra security measure.\n#\n# (To avoid any security issue that allowing loopback access may raise,\n# the no-loopback-peers option is replaced by allow-loopback-peers.)\n#\n# Allow it only for testing in a development environment! \n# In production it adds a possible security vulnerability, so for security reasons \n# it is not allowed using it together with empty cli-password. \n#\n#allow-loopback-peers\n\n# Flag that can be used to disallow peers on well-known broadcast addresses (224.0.0.0 and above, and FFXX:*).\n# This is an extra security measure.\n#\n#no-multicast-peers\n\n# Option to set the max time, in seconds, allowed for full allocation establishment. \n# Default is 60 seconds.\n#\n#max-allocate-timeout=60\n\n# Option to allow or ban specific ip addresses or ranges of ip addresses. \n# If an ip address is specified as both allowed and denied, then the ip address is \n# considered to be allowed. This is useful when you wish to ban a range of ip \n# addresses, except for a few specific ips within that range.\n#\n# This can be used when you do not want users of the turn server to be able to access\n# machines reachable by the turn server, but would otherwise be unreachable from the \n# internet (e.g. when the turn server is sitting behind a NAT)\n#\n# Examples:\n# denied-peer-ip=83.166.64.0-83.166.95.255\n# allowed-peer-ip=83.166.68.45\n\n# File name to store the pid of the process.\n# Default is \/var\/run\/turnserver.pid (if superuser account is used) or\n# \/var\/tmp\/turnserver.pid .\n#\n#pidfile=\"\/var\/run\/turnserver.pid\"\n\n# Require authentication of the STUN Binding request.\n# By default, the clients are allowed anonymous access to the STUN Binding functionality.\n#\n#secure-stun\n\n# Mobility with ICE (MICE) specs support.\n#\n#mobility\n\n# Allocate Address Family according \n# If enabled then TURN server allocates address family according  the TURN \n# Client &lt;=> Server communication address family.\n# (By default coTURN works according RFC 6156.)\n# !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!!\n#\n#keep-address-family\n\n\n# User name to run the process. After the initialization, the turnserver process\n# will make an attempt to change the current user ID to that user.\n#\n#proc-user=root\n\n# Group name to run the process. After the initialization, the turnserver process\n# will make an attempt to change the current group ID to that group.\n#\n#proc-group=root\n\n# Turn OFF the CLI support.\n# By default it is always ON.\n# See also options cli-ip and cli-port.\n#\n#no-cli\n\n#Local system IP address to be used for CLI server endpoint. Default value\n# is 127.0.0.1.\n#\n#cli-ip=127.0.0.1\n\n# CLI server port. Default is 5766.\n#\n#cli-port=5766\n\n# CLI access password. Default is empty (no password).\n# For the security reasons, it is recommended to use the encrypted\n# for of the password (see the -P command in the turnadmin utility).\n#\n# Secure form for password 'qwerty':\n#\n#cli-password=$5$79a316b350311570$81df9cfb9af7f5e5a76eada31e7097b663a0670f99a3c07ded3f1c8e59c5658a\n#\n# Or unsecure form for the same password:\n#\n#cli-password=qwerty\n\n# Enable Web-admin support on https. By default it is Disabled.\n# If it is enabled it also enables a http a simple static banner page\n# with a small reminder that the admin page is available only on https.\n#\n#web-admin\n\n# Local system IP address to be used for Web-admin server endpoint. Default value is 127.0.0.1.\n#\n#web-admin-ip=127.0.0.1\n\n# Web-admin server port. Default is 8080.\n#\n#web-admin-port=8080\n\n# Web-admin server listen on STUN\/TURN worker threads\n# By default it is disabled for security resons! (Not recommended in any production environment!)\n#\n#web-admin-listen-on-workers\n\n# Server relay. NON-STANDARD AND DANGEROUS OPTION. \n# Only for those applications when we want to run \n# server applications on the relay endpoints.\n# This option eliminates the IP permissions check on \n# the packets incoming to the relay endpoints.\n#\n#server-relay\n\n# Maximum number of output sessions in ps CLI command.\n# This value can be changed on-the-fly in CLI. The default value is 256.\n#\n#cli-max-output-sessions\n\n# Set network engine type for the process (for internal purposes).\n#\n#ne=&#91;1|2|3]\n\n# Do not allow an TLS\/DTLS version of protocol\n#\n#no-tlsv1\n#no-tlsv1_1\n#no-tlsv1_2\n\nTURNSERVER_ENABLED=1\n<\/code><\/pre>\n\n\n\n<p>Be sure to replace &#8220;yoursite.com&#8221; to the domain of your choice.<\/p>\n\n\n\n<p>We have to use the turnadmin tool to add a user who will be the admin user for the turnserver:<\/p>\n\n\n\n<p><code>sudo turnadmin  -a -u turnadmin -r yoursite.com -p turnpwd<\/code><\/p>\n\n\n\n<p><strong>SETUP DNS ENTRIES<\/strong><\/p>\n\n\n\n<p>Before your server can function as a TURN\/STUN server, we need to add two entries to its DNS structure. In the domain registrar for this domain add the following two entries:<\/p>\n\n\n\n<p><strong>TYPE<\/strong>: A  <strong>Host<\/strong>: turn <strong>Points To<\/strong>: server.ip.address <strong>TTL<\/strong>: custom <strong>Seconds<\/strong>: 600<\/p>\n\n\n\n<p><strong>TYPE<\/strong>: A  <strong>Host<\/strong>: stun <strong>Points To<\/strong>: server.ip.address <strong>TTL<\/strong>: custom <strong>Seconds<\/strong>: 600<\/p>\n\n\n\n<p><strong>START THE SERVICE<\/strong><\/p>\n\n\n\n<p>Start the Coturn server: <code>sudo systemctl start coturn<\/code> <\/p>\n\n\n\n<p>Check the status : <code>sudo systemctl status coturn<\/code><\/p>\n\n\n\n<p>It should show something similar as below if there are no errors:<\/p>\n\n\n\n<p><code>coturn.service - coturn<br>    Loaded: loaded (\/usr\/lib\/systemd\/system\/coturn.service; disabled; vendor preset: disabled)<br>    Active: active (running) since Sat 2020-05-30 09:46:00 UTC; 2 weeks 3 days ago<br>      Docs: man:coturn(1)<br>            man:turnadmin(1)<br>            man:turnserver(1)<br>   Process: 27244 ExecStart=\/usr\/bin\/turnserver -o -c \/etc\/coturn\/turnserver.conf --pidfile \/run\/coturn\/turnserver.pid (code=exited, status=0\/SUCCESS)<br>  Main PID: 27245 (turnserver)<br>    CGroup: \/system.slice\/coturn.service<br>            \u2514\u250027245 \/usr\/bin\/turnserver -o -c \/etc\/coturn\/turnserver.conf --pi\u2026<br> [<\/code><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>TEST THE SERVICE<\/strong><\/p>\n\n\n\n<p>To check if the server is functioning correctly, use the free tool: TrickleICE : <a rel=\"noreferrer noopener\" aria-label=\"https:\/\/webrtc.github.io\/samples\/src\/content\/peerconnection\/trickle-ice\/ (opens in a new tab)\" href=\"https:\/\/webrtc.github.io\/samples\/src\/content\/peerconnection\/trickle-ice\/\" target=\"_blank\">https:\/\/webrtc.github.io\/samples\/src\/content\/peerconnection\/trickle-ice\/<\/a><\/p>\n\n\n\n<p>For STUN server enter it as <code>stun:mysite.com:5349<\/code><\/p>\n\n\n\n<p>For TURN server enter it as <code>turn:mysite.com:5349<\/code><\/p>\n\n\n\n<p>If you have followed the<a href=\"https:\/\/truelogic.org\/wordpress\/2020\/06\/14\/webrtc-video-chat-with-peer-js-and-node-js\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" previous post of setting up a WebRTC app (opens in a new tab)\"> previous post of setting up a WebRTC app<\/a>, then in script.js you would change the configuration to as below:<\/p>\n\n\n\n<p><code>'iceServers': [<br>                 { url: 'stun:mysite.com:5349' },<br>                 {<br>                     url: 'turn:mysite.com,<br>                     credential: 'turnpwd',<br>                     username: 'turnadmin'<br>                 }<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        ]<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>OVERVIEW It is easy to find free STUN servers but there are no free TURN servers available. We are lucky that the people at Coturn <a class=\"mh-excerpt-more\" href=\"https:\/\/truelogic.org\/wordpress\/2020\/06\/17\/setup-your-own-stun-turn-server-using-coturn\/\" title=\"Setup Your Own STUN\/TURN Server using Coturn\">[&#8230;]<\/a><\/p>\n<\/div>","protected":false},"author":1,"featured_media":3491,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[298,359],"tags":[],"class_list":["post-3500","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","category-webrtc"],"_links":{"self":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/3500","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/comments?post=3500"}],"version-history":[{"count":12,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/3500\/revisions"}],"predecessor-version":[{"id":3512,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/3500\/revisions\/3512"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/media\/3491"}],"wp:attachment":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/media?parent=3500"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/categories?post=3500"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/tags?post=3500"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}