Skip to content
Parth Patel
All articles

How to set up a TURN server on AWS

Deploying Coturn on an EC2 Ubuntu instance, from security group rules to verifying the relay with Trickle ICE.

2 min read
  • webrtc
  • aws
  • devops

When a WebRTC peer sits behind a strict NAT or firewall, no direct path exists and traffic has to be relayed. That relay is a TURN server. Public ones are rate-limited and unreliable for anything real, so at some point you run your own.

This is how to deploy Coturn on an AWS EC2 Ubuntu instance. If the terms here are unfamiliar, start with what WebRTC actually is.

1. Create an EC2 Ubuntu instance

  • Sign in to the AWS Management Console.
  • Go to EC2 and click Launch Instance.
  • Choose Ubuntu as the Amazon Machine Image (AMI) and launch.

A small instance is fine to start with - TURN is bandwidth-bound, not CPU-bound.

2. Configure the security group

This is the step that silently breaks everything if you get it wrong. TURN needs both its control port and a wide UDP range for the relayed media.

  • Go to Network & Security → Security Groups.
  • Click Create security group.
  • Add these inbound rules:
UDP : 3478
TCP : 3478
UDP : 49152–65535
  • Save the security group.
  • Open your EC2 instance and go to Actions → Security → Change security groups.
  • Replace the existing security group with the one you just created.

3. Install Coturn

Connect to the instance to open a terminal session, then:

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

Verify the install:

turnserver --version

4. Configure the TURN server

Open the config file:

sudo nano /etc/turnserver.conf

Fill in your own values - replace listening-ip, external-ip, realm and the user credentials. On EC2 the machine only ever sees its internal address, so the internal/external form of external-ip is what makes NAT work:

/etc/turnserver.conf
# The EC2 internal IP is the listening IP
listening-ip=xxx.xx.xx.xx
 
# For an IP behind NAT like Amazon: internal_ip/external_ip
external-ip=xx.xx.xxx.xxx/xxx.xx.xx.xx
 
# Use static (long-term) credentials
lt-cred-mech
 
# Define the realm
realm=myrealm.com
 
# Define user and password (user:pass)
user=myuser:mypassword
 
fingerprint
no-tcp-relay
 
listening-port=3478
listening-ip=0.0.0.0
 
log-file=/var/log/turn.log

Save and exit.

For a quick test you can run the server in the foreground:

sudo turnserver -c /etc/turnserver.conf

Or enable it as a service:

sudo systemctl enable coturn
sudo systemctl restart coturn
sudo systemctl status coturn

5. Test it

Open the Trickle ICE test page, add your server under ICE servers with the username and password you set, and click Gather candidates.

You want to see candidates of type relay appear. host and srflx candidates come from your own machine and STUN - they prove nothing about TURN. If relay never shows up, the problem is almost always the UDP 49152–65535 range in the security group, or an external-ip that doesn't match the instance's public address.

Like this? Subscribe via RSS.