Helder Esteves

Type and hit Enter to search

JavaScript
Uncategorized
Software Architecture
React
General
Management
Next.JS
TypeScript
JavaScript
Uncategorized
Software Architecture
React
General
Management
Next.JS
TypeScript
blue UTP cord
Uncategorized

Setting up a TURN server with Node: Production-ready

Helder Esteves
Helder Esteves
May 19, 2023 5 Mins Read
136 Views
0 Comments

In this guide, you’ll learn how to set up a TURN relaying server and how to configure it to use with Node.JS for a production app.

The problem

If you’re familiar with WebRTC and P2P (peer-to-peer) connection, then you should know about its’ limitations.

One of the biggest hurdles in setting up a direct P2P connection is the existence of NATs (Network Address Translation).

As the name suggests, NAT basically converts one IP address to another. For example, when you’re behind a router, you have an internal IP associated with you, and then when it passes through the router you have another IP address that is considered public.

So what’s the problem?

When you’re connecting to the internet behind a NAT, your device only has knowledge of the IP associated with it (e.g. assigned IP from a router). However, other devices from around the internet only know your external IP (e.g. your router’s IP).

This causes problems when you connect P2P, as your device has no knowledge of its’ own external IP.

The solution

There are 2 ways of dealing with this:

Remember when I said that devices (e.g. your laptop) don’t know of their external IP address when behind a NAT? Well, STUN provides you with exactly that. When you make a request to a STUN server, it replies with your public IP address. This way you are now capable of connecting through P2P. That’s all!

STUN works well when the NAT works the same way for every connection. However, there are situations where a device is behind a symmetric NAT. In this case, connections to the “outside” always change, so you can’t define a specific IP and port to map your device.

To overcome this, a workaround is to simply relay all the communication through a server. With TURN, P2P is not so peer-to-peer (not at all, actually), as the communication is now going through a server instead.

Installing coTURN

Great, so now you know 2 of the fallacies of P2P, so how can you fix it in your case?

coTURN is an open-source implementation that lets you create a STUN and TURN server in one, without much hassle.

Let’s say you spin up a Debian (or Ubuntu) server on Digitalocean, AWS, GCloud, etc… In this case, you should first open the required ports:

80: TCP (if you need SSL)
443: TCP (if you need SSL)
3478: TCP/UDP
5349: TCP/UDP

Since managing the firewall depends on the provider you’re using, it’s out of the scope of this guide. If you’re having trouble, reply in the comments and I’ll help you out.

Once you’re done, all you need is to SSH into your server and install with the following commands:

sudo apt-get -y update
sudo apt-get -y install coturn
turnserver

That’s it! That’s all you need. You can check if it’s running by executing:

sudo systemctl status coturn

Which should show:

coturn.service - coTURN STUN/TURN Server
Loaded: loaded (/lib/systemd/system/coturn.service; enabled; ....)
Active: active (running) since Mon 2020-08-03 19:06:01 UTC; 3 days ago

If you want to execute coTURN as a service, edit the file /etc/default/coturn and add the following line to it:

TURNSERVER_ENABLED=1

Configuring coTURN

Although coTURN is now installed and running, there are a few things you should configure to:

  • Enhance the security of your server
  • Prevent other apps from using your TURN server
  • Set up SSL

To set up SSL, please go to certbot.eff.org and follow the interactive tutorial on setting up Let’s Encrypt on your server. We’ll use the certificates generated by certbot later.

We should also install fail2ban, which is a simple but effective extension that protects your server against unwanted requests. Let’s do it by running the command:

sudo apt install fail2ban

Now, on Debian / Ubuntu, the configuration file for coTURN can be found in /etc/turnserver.conf

If you check its’ contents, you’ll see it’s well documented for all you need, but you usually want to have a configuration like follows:

fingerprint
use-auth-secret
static-auth-secret=[SECRET] #change this
realm=[YOUR DOMAIN] #change this with e.g. example.com
total-quota=100
syslog
no-multicast-peers
cert=/etc/letsencrypt/live/[YOUR DOMAIN]/fullchain.pem #certificate from ssl
pkey=/etc/letsencrypt/live/[YOUR DOMAIN]/privkey.pem #certificate from ssl

If your server is also behind a NAT (e.g if you’re using AWS), you need to add 3 more options

listening-ip=[INTERNAL IP ADDRESS] #change this
relay-ip=[INTERNAL IP ADDRESS] #change this
external-ip=[EXTERNAL IP ADDRESS]/[INTERNAL IP ADDRESS] #change this

In many other configurations, you see using lt-cred-mech instead of use-auth-secret.

In WebRTC, you need to share the user and password with the client for it to be able to connect with the server.

With lt-cred-mech, you’ll set a password that is directly shared with the user. This is easy to set up and good for testing, but not recommended for production.

With use-auth-secret, you’ll set a secret that generates other temporary passwords based on cryptography. This is crucial for any production app because it’ll prevent malicious activity like stealing your server to relay their own communications.

Now, it’s important that you change static-auth-secret with something secure. You’ll need this to generate the credentials for your backend server. To generate a secure password in Ubuntu / Debian, run the following command:

openssl rand -base64 32

After you finish configuring, restart coTURN like this:

sudo systemctl restart coturn

And you’re done with the TURN server!

Generating temporary credentials in Node.JS

Now you have your TURN server working and properly configured. If you already set up a WebRTC connection in your frontend application, then the configuration params for RTCPeerConnection would be like like the following:

{
iceServers: [
{
urls: ['stun:yourturn.server.com']
},
{
urls: ['turn:yourturn.server.com'],
username: '????',
credential: '????'
}
],
sdpSemantics: 'unified-plan'
}

The username and credential in ???? are what we’ll be working to generate in this section, for a production-ready setup.

To generate the keys in Node.JS, use this code:

const crypto = require("crypto");

const secret = "YOUR_SECRET_KEY" // Replace this with the key from static-auth-secret

function generateTurnKey() {
  // The username is a timestamp that represents the expiration date of this credential
  // In this case, it's valid for 12 hours (change the '12' to how many hours you want)
  const username = (Date.now() / 1000 + 12 * 3600).toString();

  // Now create the corresponding credential based on the secret
  const hmac = crypto.createHmac("sha1", secret);
  hmac.setEncoding("base64");
  hmac.write(username);
  hmac.end();
  const credential = hmac.read();

  return {
    username,
    credential,
  };
};
console.log(generateTurnKey());

Now all you need is to send the generated values to the client (e.g. with Socket.io) and replace the values ‘????’ at the beginning of this section with what’s generated in the function above.

Testing the TURN server

To test your TURN server connectivity, open this link: Trickle ICE.

In “STUN or TURN URI” field type “turn:your.turnserver.com”

Now, run the function that generates the temporary in Node.JS, copy the “username” value, and paste it into “TURN username”. Do the same with “credential” and paste it in “TURN password”. Now press “Gather candidates”.

It should show up a list of candidates without errors if it’s working properly.

You can also try setting a wrong username or password on purpose to see if you get “Unauthorized” in the response.

If it does, then everything is working properly. Congrats!

If you have any questions, please comment below and I’ll be answering as much as I can. Happy TURNing!

Share Article

Other Articles

grayscale photo of person holding glass
Previous

Top 10 JavaScript Coding Challenges You Must Absolutely Know

a person pointing at a rock with writing on it
Next

7 Best Coding Challenge Websites for 2023: Improve Your Skills and Boost Your Career

Next
a person pointing at a rock with writing on it
May 20, 2023

7 Best Coding Challenge Websites for 2023: Improve Your Skills and Boost Your Career

Previews
May 17, 2023

Top 10 JavaScript Coding Challenges You Must Absolutely Know

grayscale photo of person holding glass

No Comment! Be the first one.

    Leave a Reply Cancel reply

    Your email address will not be published. Required fields are marked *

    Subscribe
    Stay Updated!
    Get notified when awesome content is posted. Learn more everyday.
    Most Read
    Software Architecture
    5 JS Design Patterns Every Developer Should Know
    March 10, 2023
    5 Min Read
    yellow line on gray asphalt road
    Next.JS
    5 Next.JS Tips You Never Heard About
    March 27, 2023
    4 Min Read
    text
    React
    React useEffect: 4 Tips Every Developer Should Know
    May 14, 2023
    4 Min Read
    Most Engagement
    JavaScript
    Simple Backgrounds For Websites — Cheat Sheet

    This cheat sheet will help you the next time you're choosing a background for your website....

    February 21, 2023
    3 Min Read
    Most Recent
    grayscale photo of person holding glass
    JavaScript
    Top 10 JavaScript Coding Challenges You Must Absolutely Know
    May 17, 2023
    9 Min Read
    a person pointing at a rock with writing on it
    JavaScript
    7 Best Coding Challenge Websites for 2023: Improve Your Skills and Boost Your Career
    May 20, 2023
    5 Min Read
    text
    React
    React useEffect: 4 Tips Every Developer Should Know
    May 14, 2023
    4 Min Read

    Related Posts

    yellow line on gray asphalt road
    Next.JS
    5 Next.JS Tips You Never Heard About
    March 27, 2023
    4 Min Read
    Read More
    four handheld tools on board
    React
    Tools to Speed Up React Component Creation
    May 5, 2023
    3 Min Read
    Read More
    JavaScript
    Simple Backgrounds For Websites — Cheat Sheet
    February 21, 2023
    3 Min Read
    Read More
    a computer screen with a bunch of buttons on it
    JavaScript
    JavaScript VSCode Extensions You Never Heard About
    April 25, 2023
    3 Min Read
    Read More

    Helder Esteves

    Read everything there is to know about the JavaScript development ecosystem, from programming to project management.

    Recent

    7 Best Coding Challenge Websites for 2023: Improve Your Skills and Boost Your Career
    May 20, 2023
    Setting up a TURN server with Node: Production-ready
    May 19, 2023

    Categories

    JavaScript9
    Uncategorized4
    Software Architecture2
    React2

    Contact

    Reach out to us through helder.writer@gmail.com

    © 2022, All Rights Reserved.

    Go to mobile version