This guide provides a comprehensive, step-by-step walkthrough to deploy and configure a private coTURN server for WebRTC audio/video calls on a free-tier Oracle Cloud Infrastructure (OCI) Ubuntu VPS. This setup is fully framework-agnostic and will work with any WebRTC client (Web, Mobile, Desktop, Unity, etc.).
Table of Contents
- Prerequisite: Account Activation
- Step 1: Create the Virtual Cloud Network (VCN Wizard)
- Step 2: Create and Launch the Ubuntu VM (Compute Instance)
- Step 3: Open OCI Network Security Ports (Security List)
- Step 4: Connect via SSH
- Step 5: Install and Configure coTURN on the VM
- Step 6: Configure OS-level Firewall (VPS)
- Step 7: Start and Monitor coTURN
- Step 8: WebRTC Client Configuration (Standard JS API)
- Verification: Test Your TURN Server
- Troubleshooting
- License
Architecture Flow
Below is a visual representation of how the TURN server acts as an encrypted media relay when direct peer-to-peer (P2P) host connection is blocked by Carrier-Grade NAT (CGNAT) on cellular networks.
flowchart TD
subgraph Direct_P2P [Attempt 1: Direct Host-to-Host]
Client_A_Local[Client A] -.->|Direct P2P Blocked by CGNAT| Client_B_Local[Client B]
end
Direct_P2P ~~~ Fallback_Relay
subgraph Fallback_Relay [Attempt 2: Fallback coTURN Relay]
Client_A[Client A] <==>|Encrypted SRTP Stream| TURN[coTURN Server on Oracle VPS]
TURN <==>|Encrypted SRTP Stream| Client_B[Client B]
end
style TURN fill:#3b82f6,stroke:#1d4ed8,stroke-width:2px,color:#fff
Prerequisite: Account Activation
- Oracle Cloud Sign-up: Register for a free-tier Oracle Cloud account.
-
Wait for Activation Banner: Immediately after registration, a green banner appears at the top of the home page: “Your account is currently setting up...”
- > [!IMPORTANT] > Do NOT attempt to create any networks or servers while this banner is visible. If you do, Oracle will block the creation of public IP addresses and disable network controls.
- Wait until the green banner disappears completely (usually takes 10–20 minutes) before proceeding to Step 1.
Step 1: Create the Virtual Cloud Network (VCN Wizard)
Once the account is fully active, create your network:
- In the Build section on the Home page, click Networking: Set up a network with a wizard.
- Choose Create VCN with Internet Connectivity and click Start VCN Wizard.
- Leave all default CIDR blocks and naming fields as they are and click Next.
- Click Create at the bottom right.
- Your Virtual Cloud Network (VCN) and Public Subnet are successfully created.
Step 2: Create and Launch the Ubuntu VM (Compute Instance)
- Go to Compute -> Instances -> click Create instance.
- Image selection: Click Edit next to Image and Shape, select Canonical Ubuntu -> version 24.04 (Shape: VM.Standard.E2.1.Micro).
-
Primary Network Settings:
- Check Select existing virtual cloud network -> select your wizard-created VCN.
- Check Select existing subnet -> select your public subnet.
- Toggle Automatically assign public IPv4 address to ON (so it turns blue/green).
-
Add SSH keys:
- > [!TIP]
> Click Download private key (saves
.keyfile) and optionally Download public key (saves.pubfile) to your computer. Keep these files secure in your Downloads folder.
- > [!TIP]
> Click Download private key (saves
- Click Create at the bottom.
- Wait 1 minute for the status badge to turn green (Running).
- Copy the Public IP Address and the Private IP Address of your running instance.
Step 3: Open OCI Network Security Ports (Security List)
OCI blocks all ports except 22 by default.
- Go to Networking -> Virtual Cloud Networks -> click on your newly created VCN.
- Under Subnets (in the horizontal tab), click on your public subnet.
- Under the Security Lists table, click on the Default Security List for your VCN.
- Click Add Ingress Rules and add these 3 separate rules (do NOT use commas, as OCI does not support them):
Rule 1 (TCP):
-
Source CIDR:
0.0.0.0/0 -
IP Protocol:
TCP -
Destination Port Range:
3478-5349 -
Description:
coTURN TCP Range
Rule 2 (UDP):
-
Source CIDR:
0.0.0.0/0 -
IP Protocol:
UDP -
Destination Port Range:
3478-5349 -
Description:
coTURN UDP Range
Rule 3 (UDP Media):
-
Source CIDR:
0.0.0.0/0 -
IP Protocol:
UDP -
Destination Port Range:
49152-65535 -
Description:
coTURN UDP Media
Click **Add Ingress Rules* to save.*
Step 4: Connect via SSH
Open PowerShell (on Windows) or Terminal (on Mac/Linux) and execute:
# 1. Navigate to the folder where you saved the SSH keys
cd C:\Users\<YourUsername>\Downloads
# 2. Connect via SSH (replace key filename and public IP with yours)
ssh -i "your-ssh-key.key" ubuntu@<YOUR_SERVER_PUBLIC_IP>
Type yes when prompted to verify host authenticity.
Step 5: Install and Configure coTURN on the VM
Once logged in, execute the following commands:
1. Install coTURN
sudo apt update && sudo apt install coturn -y && sudo systemctl stop coturn
2. Enable coTURN System Daemon
sudo sed -i 's/#TURNSERVER_ENABLED=1/TURNSERVER_ENABLED=1/' /etc/default/coturn
3. Backup Default Configuration
sudo mv /etc/turnserver.conf /etc/turnserver.conf.backup
4. Create and Edit coTURN Configuration File
sudo nano /etc/turnserver.conf
Paste the following configuration.
[!IMPORTANT]
NAT Mapping Correction: Ensure you map your public IP directly to the private IP inexternal-ipusing the slash (/) format so the TURN server knows it is running behind a NAT.
listening-port=3478
tls-listening-port=5349
listening-ip=<YOUR_SERVER_PRIVATE_IP>
external-ip=<YOUR_SERVER_PUBLIC_IP>/<YOUR_SERVER_PRIVATE_IP>
min-port=49152
max-port=65535
no-syslog
no-stdout-log
log-file=/dev/null
no-cli
stale-nonce
fingerprint
lt-cred-mech
user=<YOUR_TURN_USERNAME>:<YOUR_TURN_PASSWORD>
realm=<YOUR_REALM_NAME>
Save and Exit: Press **Ctrl+O, then **Enter, then **Ctrl+X.
Step 6: Configure OS-level Firewall (VPS)
# 1. Flush default OCI blocking rules
sudo iptables -F
# 2. Install persistent firewall utility (select "Yes" on the purple screen prompts)
sudo apt-get install iptables-persistent -y
# 3. Save the flushed firewall rules permanently
sudo netfilter-persistent save
Step 7: Start and Monitor coTURN
# 1. Start the service
sudo systemctl start coturn
# 2. Verify status (should show green "active (running)")
sudo systemctl status coturn
# 3. Monitor live connection logs
sudo journalctl -u coturn -f
Press **Ctrl+C* to stop watching live logs.*
Step 8: WebRTC Client Configuration (Standard JS API)
To connect your WebRTC peer connection to the newly deployed coTURN server, initialize your RTCPeerConnection with the following standard ICE configuration parameters:
const peerConnection = new RTCPeerConnection({
iceServers: [
{
urls: [
"stun:stun.l.google.com:19302",
"stun:stun1.l.google.com:19302",
"stun:<YOUR_SERVER_PUBLIC_IP>:3478"
]
},
{
urls: [
"turn:<YOUR_SERVER_PUBLIC_IP>:3478?transport=udp",
"turn:<YOUR_SERVER_PUBLIC_IP>:3478?transport=tcp",
"turn:<YOUR_SERVER_PUBLIC_IP>:5349?transport=udp",
"turn:<YOUR_SERVER_PUBLIC_IP>:5349?transport=tcp"
],
username: "<YOUR_TURN_USERNAME>",
credential: "<YOUR_TURN_PASSWORD>"
}
]
});
Replace placeholders with your server's details. For Flutter/Dart, map these exact JSON key-value pairs into your iceConfiguration map.
Verification: Test Your TURN Server
You can verify that your TURN server is functioning correctly and successfully generating media relays without writing any code:
- Open the Official WebRTC Trickle ICE Test Tool.
- Under ICE servers, fill out the credentials:
-
STUN or TURN URI:
turn:<YOUR_SERVER_PUBLIC_IP>:3478?transport=udp -
TURN username:
<YOUR_TURN_USERNAME> -
TURN password:
<YOUR_TURN_PASSWORD>
-
STUN or TURN URI:
- Click Add Server.
- Click the Gather candidates button at the bottom.
- In the generated table, look at the Type column:
- If you see a row with
relayin the Type column and your server's Public IP in the address column, your TURN server is 100% working and ready! - If you only see
hostorsrflxcandidates, the connection to the TURN server failed (check ports and credentials).
- If you see a row with
Troubleshooting
Issue 1: Connection timed out
- Symptoms: The ICE test tool halts or the VPS fails to respond during SSH/TURN requests.
-
Resolution:
- Go to OCI console -> VCN -> Default Security List and verify that rules 1, 2, and 3 are present with the exact port ranges.
- Verify that OS-level firewall rules have been flushed on the VPS (
sudo iptables -Ffollowed bysudo netfilter-persistent save).
Issue 2: TURN authentication failed
-
Symptoms: Live logs show
Unauthorizedmessages or the ICE tool fails to gatherrelaycandidates. -
Resolution:
- Verify the
userstring inside/etc/turnserver.conf. It must follow the exact syntax:user=username:password. - Make sure to restart the service to apply credentials:
sudo systemctl restart coturn.
- Verify the
Issue 3: No relay candidates are generated
-
Symptoms: The test runs successfully but does not output any
relaytypes in the table. -
Resolution:
- Ensure the
external-ipparameter in/etc/turnserver.confmaps the public IP to the private IP:external-ip=<PUBLIC_IP>/<PRIVATE_IP>. - Ensure the UDP port range
49152-65535is open in both OCI Security Lists and Ubuntu local firewall configurations.
- Ensure the
License
This project is licensed under the MIT License. Feel free to use, modify, and share.
Top comments (0)