Discover the new easier way to develop Kurento video applications

Frequently Asked Questions

About NAT, ICE, STUN, TURN

What is NAT?

Network Address Translation (NAT) is a mechanism that hides from the public access the private IP addresses of machines inside a network. This NAT mechanism is typically found in all types of network devices, ranging from home routers to full-fledged corporate firewalls. In all cases the effect is the same: machines inside the NAT cannot be freely accessed from outside.

The effects of a NAT is very negative for WebRTC communications: machines inside the network will be able to send data to the outside, but they won’t be able to receive data from remote endpoints that are sitting outside the network. In order to allow for this need, NAT devices typically allow to configure NAT bindings to let data come in from the outside part of the network; creating these NAT bindings is what is called NAT traversal, also commonly referred as “opening ports”.

What is ICE?

Interactive Connectivity Establishment (ICE) is a protocol used for NAT traversal. It defines a technique that allows communication between two endpoints when one is inside a NAT and the other is outside of it. The net effect of the ICE process is that the NAT will be left with all needed ports open for communication, and both endpoints will have complete information about the IP address and ports where the other endpoint can be contacted.

ICE doesn’t work standalone: it needs to use a helper protocol called STUN.

What are STUN and TURN?

Session Traversal Utilities for NAT (STUN) is a protocol that complements ICE in the task of solving the NAT traversal issue. It can be used by any endpoints to determine the IP address and port allocated to it by a NAT. It can also be used to check connectivity between two endpoints, and as a keep-alive protocol to maintain NAT bindings. STUN works with many existing NATs, and does not require any special behavior from them.

Traversal Using Relays around NAT (TURN) is an extension of STUN, used where the NAT security policies are too strict and the needed NAT bindings cannot be successfully created. In these situations, it is necessary for the host to use the services of an intermediate node that acts as a communication relay.

Note

TURN is an extension of STUN. This means that you don’t need to configure a STUN server if you are already using a TURN server.

When is STUN needed?

STUN is needed for every endpoint behind a NAT. All NAT-ed peers need to open their own NAT ports, doing NAT traversal by using a STUN server that is outside of the NAT.

If you are installing Kurento in a NAT environment (eg. if your server is behind a NAT firewall), you need to use a STUN or TURN server, and configure KMS appropriately in /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini. Apart from that, you need to open all UDP ports in your cloud provider’s security group, as STUN/TURN will use any port available from the whole 0-65535 range.

Similarly, all browser endpoints that are behind a NAT need to configure the STUN and/or TURN server details with the iceServers field of the RTCPeerConnection constructor.

Let’s see this with an example: The typical installation scenario for Kurento Media Server is to have a strict separation between Application Server and client. KMS and Application Server are running in a cloud machine without any NAT or port restriction on incoming connections, while a browser client runs from any (possibly restricted) network that forbids incoming connections on any port that hasn’t been “opened” in advance. The client may communicate with the Application Server for signaling purposes, but at the end of the day the bulk of the communication is done between the WebRTC engines of the browser and KMS.

NAT client without STUN

In scenarios such as this one, the client is able to send data to KMS because its NAT will allow outgoing packets. However, KMS will not be able to send data to the client, because the client’s NAT is closed for incoming packets. This is solved by configuring the client to use some STUN server, then opening the appropriate ports in the NAT by using the STUN protocol. After this operation, the client is now able to receive audio/video streams from KMS:

NAT client with STUN

This procedure is called ICE.

Note that you can also deploy KMS behind a NAT firewall, as long as KMS itself is also configured to open its own NAT ports by following the same procedure (again, with a STUN server that is outside of the NAT).

Note

TURN is an extension of STUN. This means that you don’t need to configure a STUN server if you are already using a TURN server.

How to install Coturn?

Coturn is a STUN server and (optionally) a TURN relay, supporting all features required for the ICE protocol and allowing to establish WebRTC connections between hosts that sit behind a NAT.

Coturn can be installed directly from the Ubuntu package repositories:

sudo apt-get update && sudo apt-get install --no-install-recommends --yes \
    coturn
  1. Edit the file /etc/turnserver.conf and configure the server according to your needs.

    This basic configuration is a good first step; it will work for using Coturn with Kurento Media Server for WebRTC streams:

    # TURN server public address, if Coturn is behind NAT.
    # It must be an IP address, not a domain name.
    external-ip=<CoturnPublicIpAddress>
    
    # TURN server lower and upper bounds of the UDP relay endpoints.
    # Default: 49152, 65535.
    #min-port=49152
    #max-port=65535
    
    # Uncomment to run server in 'normal' 'moderate' verbose mode.
    # By default the verbose mode is off.
    #verbose
    
    # Use fingerprints in the TURN messages.
    fingerprint
    
    # Use long-term credential mechanism.
    lt-cred-mech
    
    # 'Static' user accounts for long-term credentials mechanism.
    user=<TurnUser>:<TurnPassword>
    
    # Realm used for the long-term credentials mechanism.
    realm=kurento.org
    
    # Set the log file name.
    # The log file can be reset sending a SIGHUP signal to the turnserver process.
    log-file=/var/log/turnserver/turnserver.log
    
    # Disable log file rollover and use log file name as-is.
    simple-log
    
  2. Edit the file /etc/default/coturn and set

    TURNSERVER_ENABLED=1
    

    so the server starts automatically as a system service daemon.

  3. Configure KMS and point it to where the server is listening for connections. Edit the file /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini and set either the STUN or the TURN parameters:

    stunServerAddress=<CoturnPublicIpAddress>
    stunServerPort=3478
    
    turnURL=<TurnUser>:<TurnPassword>@<CoturnPublicIpAddress>:3478
    

    If you only configure the STUN parameters in KMS, then the TURN relay capability of Coturn won’t be used. Of course, if you instead configure the whole TURN URL, then KMS will be able to use the Coturn server as a TURN relay when it needs to. Note that TURN is an extension of STUN, so if you configure TURN then there is no need to also configure the STUN details in KMS.

    The following ports should be open in the firewall or your cloud machine’s Security Groups:

    • 3478 TCP & UDP.
    • 49152-65535 UDP: As per RFC 5766, these are the ports that the TURN server will use to exchange media. These ports can be changed using Coturn’s min-port and max-port parameters.

    Note

    The STUN protocol doesn’t constrain the range of ports that might be used, so with the default configuration you should open all UDP ports. However, it is possible to edit the file /etc/kurento/modules/kurento/BaseRtpEndpoint.conf.ini and restrict the port range used by Kurento Media Server. That would allow to have a reduced set of ports open in your server.

  4. Lastly, start the Coturn server and the media server:

    sudo service coturn start
    sudo service kurento-media-server restart
    

Note

Make sure to check your installation using this test application:

https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

How To …

Know how many Media Pipelines do I need for my Application?

Media Elements can only communicate with each other when they are part of the same pipeline. Different MediaPipelines in the server are independent do not share audio, video, data or events.

A good heuristic is that you will need one pipeline per each set of communicating partners in a channel, and one Endpoint in this pipeline per audio/video streams reaching a partner.

Know how many Endpoints do I need?

Your application will need to create an Endpoint for each media stream flowing to (or from) the pipeline. As we said in the previous answer, each set of communicating partners in a channel will be in the same Media Pipeline, and each of them will use one or more Endpoints. They could use more than one if they are recording or reproducing several streams.

Know to what client a given WebRtcEndPoint belongs or where is it coming from?

Kurento API currently offers no way to get application attributes stored in a Media Element. However, the application developer can maintain a hashmap or equivalent data structure mapping the WebRtcEndpoint internal Id (which is a string) to whatever application information is desired.

Why do I get the error …

“Cannot create gstreamer element”?

This is a typical error which happens when you update Kurento Media Server from version 4 to 5. The problem is related to the GStreamer dependency version. The solution is the following:

sudo apt-get purge --auto-remove '^(kms|kurento).*'
sudo apt-get autoremove
sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install kurento-media-server