Allow users behind firewalls



Introduction 🔗

OpenVidu deployments include a TURN server (Coturn) that listens at port 3478. While that's a good setup for most scenarios, some corporate networks only allow connections to port 443, which OpenVidu uses for its API and WebSocket endpoints. This means that the included TURN server cannot be used in those networks.

To solve this limitation, OpenVidu now can be easily configured with external TURN servers, either to use our brand new TURN appliance that can be deployed externally, or a third-party TURN SaaS. In the next sections, both scenarios will be described.

Prerequisites 🔗

  1. A Linux machine with its own public IP. It must be a different machine than those used by OpenVidu.
  2. A FQDN(Fully Qualified Domain Name) which must point to the public IP of the machine. No proxies or anything else, just a simple domain/subdomain with a register of type A pointing to its public IP.
  3. Good network bandwidth.
  4. Docker and docker-compose installed.

Also, you will need to open these ports:


Inbound Ports 🔗

  • Port 80 TCP is needed by certbot to renew certificates
  • Port 443 TCP/UDP is needed to connect to coturn from browsers
  • Port 22 TCP is only necessary if you want to SSH into your instance


Outbound Ports 🔗

  • All outbound traffic is recommended for TURN to be able to relay media from all ports to the media nodes.




Deploy a TURN service for clients behind firewalls (with Let's Encrypt) 🔗


We provide our own deployment based on the Coturn project which can be deployed at port 443 with SSL using Let's Encrypt. In this section we will describe how to install it and configure it to be used by OpenVidu:


1) SSH into the machine you will deploy coturn as root.

2) Go to /opt/ directory.

3) Execute this command to install our Coturn deployment.

curl https://s3.eu-west-1.amazonaws.com/aws.openvidu.io/external-turn/4.5.2/install_openvidu_external_coturn.sh | bash

4) Fill in the file /opt/coturn/.env these environment variables:

  • TURN_DOMAIN_NAME: Domain which is pointing to the public ip of the machine.
  • LETSENCRYPT_EMAIL: Email you want to use for letsencrypt certificate.
  • TURN_STATIC_AUTH_SECRET: TURN shared key with OpenVidu. It is recommended to use alphanumeric characters.

5) Execute coturn:

docker-compose up -d

Check the logs to see if everything is OK:

docker-compose logs -f

You should see this log trace from certbot and coturn containers:

certbot    | Account registered.
certbot    | Requesting a certificate for <TURN_DOMAIN_NAME>
certbot    |
certbot    | Successfully received certificate.
certbot    | Certificate is saved at: /etc/letsencrypt/live/<TURN_DOMAIN_NAME>/fullchain.pem
certbot    | Key is saved at:         /etc/letsencrypt/live/<TURN_DOMAIN_NAME>/privkey.pem
certbot    | This certificate expires on ******.
certbot    | These files will be updated when the certificate renews.
...
coturn     | 0: : <SSL_TLS_DTLS_VERSION>: Certificate file found: /etc/letsencrypt/live/<TURN_DOMAIN_NAME>/cert.pem
...
coturn     | 0: : <SSL_TLS_DTLS_VERSION>: Certificate file found: /etc/letsencrypt/live/<TURN_DOMAIN_NAME>/privkey.pem
...
coturn     | 0: : IPv4 <PROTOCOL> listener opened on : 0.0.0.0:443

Now your TURN server is ready at port 443 with SSL.

As long as the output of the coturn service matches the above one, you can ignore some error logs that you may see. Coturn is very verbose and tries to apply some default configurations that may produce those errors.

Configure OpenVidu to use the new TURN server deployed: 🔗

Configure the previously defined TURN_DOMAIN_NAME and TURN_STATIC_AUTH_SECRET in OpenVidu server using this parameter at /opt/openvidu/.env/:

OPENVIDU_WEBRTC_ICE_SERVERS=["url=turns:<TURN_DOMAIN_NAME>:443,staticAuthSecret=<TURN_STATIC_AUTH_SECRET>"]

Deployment example 🔗

Let's supose that we want to deploy a TURN server using 443 SSL using:

  • Domain name of Turn: turn-server.example.com
  • Static auth secret (Shared secret): mysecret
  • Letsencrypt email: example-email@example.com

We should have a machine with its own Public IP with a domain name pointing to it. It must also be in a different machine than OpenVidu ones. The file /opt/coturn/.env should look like this:

TURN_DOMAIN_NAME=turn-server.example.com
LETSENCRYPT_EMAIL=example-email@example.com
TURN_STATIC_AUTH_SECRET=mysecret

On the other hand at OpenVidu, configuration in /opt/openvidu/.env should include this property:

OPENVIDU_WEBRTC_ICE_SERVERS=["url=turns:turn-server.example.com:443,staticAuthSecret=mysecret"]



Deploy a TURN service for clients behind firewalls (with custom certificates) 🔗


The instructions we provide at Deploy a TURN service for clients behind firewalls are prepared to work by default with SSL using Letsencrypt, but you may want to use a certificate purchased from a CA or you have your own self-signed certificate. To deploy it you just need to:

1) SSH into the machine you will deploy coturn and change to the root user.

2) Go to /opt/ directory.

3) Execute this command to install our Coturn deployment.

curl https://s3.eu-west-1.amazonaws.com/aws.openvidu.io/external-turn/4.5.2/install_openvidu_external_coturn.sh | bash

4) Place your certificates in a directory, for example: /opt/coturn/owncert. You should have two files at this directory:

  • privkey.pem (Private key file)
  • cert.pem (Certificate file)

5) Remove the certbot service from /opt/coturn/docker-compose.yml.

6) Modify /opt/coturn/docker-compose.yml to use the directory of your certificates. Instead of this volume...:

volumes:
    - ./certbot/etc/letsencrypt:/etc/letsencrypt

... change it to this one...:

volumes:
    - /opt/coturn/owncert:/opt/coturn/owncert

7) Modify /opt/coturn/docker-compose.yml to change all certificate parameters of the coturn service from this...

command:
    - --cert=/etc/letsencrypt/live/${TURN_DOMAIN_NAME}/cert.pem
    - --pkey=/etc/letsencrypt/live/${TURN_DOMAIN_NAME}/privkey.pem
    ...

... to this...:

command:
    - --cert=/opt/coturn/owncert/cert.pem
    - --pkey=/opt/coturn/owncert/privkey.pem
...

8) Give permission to your certificates files at /opt/coturn/owncert so it can be accessed by the coturn service:

chmod -R 655 /opt/coturn/owncert

9) Fill only these parameters in /opt/coturn/.env file:

TURN_DOMAIN_NAME=turn-server.example.com
TURN_STATIC_AUTH_SECRET=mysecret

10) Execute coturn:

docker-compose up -d

Check the logs to see if everything is OK:

docker-compose logs -f

You should see this log trace from coturn container:

coturn     | 0: : <SSL_TLS_DTLS_VERSION>: Certificate file found: //opt/openvidu/owncert/cert.pem
...
coturn     | 0: : <SSL_TLS_DTLS_VERSION>: Certificate file found: //opt/openvidu/owncert/privkey.pem
...
coturn     | 0: : IPv4 <PROTOCOL> listener opened on : 0.0.0.0:443

Now your TURN server is ready at port 443 with SSL.

As long as the output of the coturn service matches the above one, you can ignore some error logs that you may see. Coturn is very verbose and tries to apply some default configurations that may produce those errors.

Configure OpenVidu to use the new TURN server deployed: 🔗

Configure the previously defined TURN_DOMAIN_NAME and TURN_STATIC_AUTH_SECRET in OpenVidu server using this parameter at /opt/openvidu/.env/:

OPENVIDU_WEBRTC_ICE_SERVERS=["url=turns:<TURN_DOMAIN_NAME>:443,staticAuthSecret=<TURN_STATIC_AUTH_SECRET>"]



Use a third-party TURN SaaS for clients behind firewalls 🔗

If you don't want to manage and provision your own server, we provide in our SDKs the possibility to configure a third-party TURN SaaS as Xyrsys or Twilio Turn. With such services you can also benefit of a global network transversal service. These services has its own TURN servers deployed around the world so you can reach the nearest TURN server and benefit of less latency connections.

TURN SaaS offers easy to use APIs to generate TURN endpoints and credentials. You just need to get that information from the TURN SaaS API and pass it to OpenVidu while creating Connections.

Session session = OV.createSession();
IceServerProperties iceServerProperties = new IceServerProperties.Builder()
        .url("turn:<your_turn_endpoint>:443")
        .username("<your_username>")
        .credential("<your_credential>")
        .build();
ConnectionProperties connectionProperties = new ConnectionProperties.Builder()
        .addCustomIceServer(iceServerProperties)
        .build();
session.createConnection(connectionProperties);

See JavaDoc


It is also possible to set fixed TURN credentials at OpenVidu global configuration, but please note that this is generally not recommended, as dynamic credentials associated to the lifecycle of each user is a much more secure option.

OPENVIDU_WEBRTC_ICE_SERVERS=["url=turns:<your_turn_endpoint>:443,username=<your_username>,credential=<your_credential>"]