From 80c170dd6915c18f11804764c1cc4a1ee35961bb Mon Sep 17 00:00:00 2001 From: steveseguin <punkrawker@gmail.com> Date: Sun, 12 Jan 2025 18:07:19 -0500 Subject: [PATCH] turn server install guide improved --- turnserver.conf | 54 ------ turnserver.md | 223 ++++++++++------------ turnserver2.conf | 52 ----- turnserver3.conf => turnserver_basic.conf | 0 turnserver_install.sh.sample | 159 +++++++++++++++ 5 files changed, 260 insertions(+), 228 deletions(-) delete mode 100644 turnserver.conf delete mode 100644 turnserver2.conf rename turnserver3.conf => turnserver_basic.conf (100%) create mode 100644 turnserver_install.sh.sample diff --git a/turnserver.conf b/turnserver.conf deleted file mode 100644 index 76f04588d..000000000 --- a/turnserver.conf +++ /dev/null @@ -1,54 +0,0 @@ -## How to setup a TURN server for free (or near free) -## This file is a bit out of day now; see turnserver.md for a newer one. -## You can still reference this file/settings when deploying onto Google Cloud or AWS servers. - -# Create a VM instance on Google Cloud (Free Tier available) -# Use Ubuntu and Open all PORTS for ingress/egress for TCP/UDP -#>> sudo apt-get update -#>> sudo apt-get install coturn -# Set a domain name to point to the server you setup. I use https://namecheap.com to buy a $1 .xyz domain -#>> sudo add-apt-repository ppa:certbot/certbot -#>> sudo apt-get install certbot -#>> sudo certbot certonly --standalone ## do the wizard , which will setup a SSH key for you -# edit /etc/default/coturn and set TURNSERVER_ENABLED=1 -# edit THIS file with required changes; CHANGE ME. -# put the edited file @ /etc/turnserver.conf -#>> systemctl start coturn -# Use with obs.ninja by adding: https://obs.ninja/?streamid=XXXXXXXXXXX&turn=steve;justtesting;turn:turn.obs.ninja:443 -# Obviously update the TURN settings with your domain, username, and password -- keep the password private. - - -listening-port=80 -tls-listening-port=443 -#alt-listening-port=0 -#alt-tls-listening-port=0 - -listening-ip = {10.168.0.2, 0.0.0.0, 127.0.0.1} ## CHANGE ME (internal IP) - -relay-ip = {10.168.0.2, 0.0.0.0, 127.0.0.1} ## CHANGE ME (internal IP) - -external-ip = 34.94.203.138/10.168.0.2 ## CHANGE ME ( external + internal IP) - -realm=turn2.obs.ninja ## CHANGE ME -server-name=turn2.obs.ninja ## CHANGE ME - -#lt-cred-mech -#userdb=/etc/turnuserdb.conf -fingerprint -stale-nonce -no-multicast-peers - -min-port=10000 -max-port=20000 - -#oauth -lt-cred-mech -user=steve:justtesting ## CHANGE ME - -# use real-valid certificate/privatekey files -cert=/etc/letsencrypt/live/turn2.obs.ninja/fullchain.pem ## CHANGE ME -pkey=/etc/letsencrypt/live/turn2.obs.ninja/privkey.pem ## CHANGE ME - -# verbose -no-stdout-log - diff --git a/turnserver.md b/turnserver.md index c7653ae12..94c809188 100644 --- a/turnserver.md +++ b/turnserver.md @@ -1,156 +1,135 @@ -## Install and setup guide for a TURN Relay Server +# TURN Server Setup Guide -#### why? You may want to deploy one to ensure high compatiblity with remote guests. If you try to use the official VDO.Ninja TURN servers for a private deployment, you may find yourself getting kicked off. +## Understanding STUN vs TURN -This install script and config file was used with a standard virtual machine server loaded with Ubuntu 20. GCP/AWS servers might need slightly different settings. +WebRTC tries to establish peer-to-peer connections using the following methods, in order: +1. Direct connection +2. STUN - helps peers discover their public IP address and port +3. TURN - relays traffic between peers when direct/STUN connections fail -``` -sudo apt-get update # update package lists - -sudo apt-get install coturn -y # install coturn, the implementation of the TURN server -sudo vi /etc/default/coturn # open the coturn configuration in Vim (you can also use nano or any other editor) -``` -...and we uncomment the line: -``` -#TURNSERVER_ENABLED=1 -``` -….leaving it like this: -``` -TURNSERVER_ENABLED=1 -``` -If we want to support TCP / TLS, we need an SSL certificate installed. Certbot has lots of issues to work around, but it's free. If you buy a cert some where else, you may need to convert your certificate to one that's compatible with coturn. Either way, adding TCP/TLS is a pain that isn't needed for 99% of the users out there. -``` -sudo add-apt-repository ppa:certbot/certbot # Add the certbot repository -sudo apt-get install certbot -y # Install certbot required for the HTTPS certificate -sudo certbot certonly --standalone # only generate the HTTPS certificate without actually changing any configs -``` -If you want to setup a firewall or configure an existing firewall, you can see the below setup and configurations. This can often be skipped for new Ubuntu installations, but I'll leave that up to you -``` -sudo apt install net-tools -sudo ufw allow 3478/tcp # The default coturn TCP port -sudo ufw allow 3478/udp # The default coturn UDP port -sudo ufw allow 3479/tcp # Sometimes port+1 is used -sudo ufw allow 3479/udp # Sometimes port+1 is used -sudo ufw allow 443/tcp # The HTTPS TCP port -sudo ufw allow 443/udp # The HTTPS UDP port -sudo ufw allow 49152:65535/tcp -sudo ufw allow 49152:65535/udp -``` -If we expect heavy usage of this server, like hundreds of connections, you might want to ensure your system supports enough open sockets. I'm not sure if this actually works or is needed, but you can see this article for example on how to increase the number of available sockets on Ubuntu: https://medium.com/@muhammadtriwibowo/set-permanently-ulimit-n-open-files-in-ubuntu-4d61064429a - -If you do want to increase the connection limit, for larger systems, it's as follows: -``` -ulimit -n 65535 -sudo vim /etc/sysctl.conf -``` -Add the following line to the file anywhere (with vim, press i to insert new text and :wq to save and exit) -``` -fs.file-max = 65535 -``` -Once saved, you can apply the changes -``` -sudo sysctl -p -``` -And that should have set the connection limit to be higher now. +### STUN (Session Traversal Utilities for NAT) +- Lightweight protocol that helps peers behind NAT discover their public IP address +- Low bandwidth usage as it only helps with connection discovery +- No relay costs, but doesn't work when peers are behind strict firewalls -Next, update turnserver.conf with passwords, domain names, and whatever else that needs changing. Example contents are provided below. Once you have updated it, start the TURN server and ensure it started correctly. At the bottom of this page is a sample conf file; I personally use `turnserver3.conf` (https://github.com/steveseguin/vdo.ninja/blob/master/turnserver3.conf), which is hosted in the main repo, for quick TURN deployments. +### TURN (Traversal Using Relays around NAT) +- Relays all traffic through the server when direct/STUN connections fail +- Higher bandwidth usage and server costs +- Required for peers behind symmetric NATs or strict firewalls +- More reliable but should only be used as a fallback -``` -sudo vi /etc/turnserver.conf -``` -Tip: For those doing their own LAN-deployment, you might want to add STUN-support to the TURN server while at it. Refer to the co-turn documentation for help there though. +## Quick Install -Next, once we have all the settings and configs setup, we can enable the system service for co-turn to auto-start on boot. +The installer script automates the complete TURN server setup process: -This is our service file; it should exist. -``` -sudo vi /usr/lib/systemd/system/coturn.service -``` -To ensure it's enabled, try this: -``` -sudo systemctl daemon-reload -sudo systemctl enable coturn -``` +```bash +# Download the installer +wget https://raw.githubusercontent.com/steveseguin/vdo.ninja/develop/turnserver_install.sh.sample +mv turnserver_install.sh.sample turnserver_install.sh +chmod +x turnserver_install.sh -To start the co-turn service and to see if it had any errors: -``` -sudo systemctl restart coturn -sudo systemctl status coturn +# Run the installer +sudo ./turnserver_install.sh ``` -You can then validate that things are working at the following site: - -https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ -An example URL is `turn:turnserver.mydomain.com:3478` -or for TCP/TLS, try `turns:turnTLS.mydomain.com:443` +The installer will: +1. Install coturn and dependencies +2. Configure system limits for high connection loads +3. Set up base TURN/STUN configuration +4. Optionally configure SSL/TLS support +5. Create systemd service for auto-start +6. Configure proper permissions -note: If you run into error 701 issues with your TURN server, check that the coturn service has access to your new SSL certificates: -see this issue with coturn: https://github.com/coturn/coturn/issues/268 +## Basic Configuration Explained -You might also want to consider buying a better certificiate, as not all Google-related projects properly support certbot certificates, including libwebrtc. see [this issue ticket](https://github.com/coturn/coturn/issues/240#issuecomment-648550885). If you go this route, see [turnserver2.conf](https://github.com/steveseguin/vdo.ninja/blob/master/turnserver2.conf) for an example config. +The basic configuration (`turnserver_basic.conf`) provides a minimal but functional TURN server: -Next, we may want to update the User and Group values in our service file to be "root". This seems to be a quick hacky fix for the issue with Lets Encrypt. .. I welcome a better solution tho. If you move the certs somewhere else, or buy proper certificates, then the default turnserver user/group will work. +```conf +listening-port=3478 # Standard STUN/TURN port +fingerprint # Required for WebRTC +lt-cred-mech # Long-term credential mechanism +user=username:password # Authentication credentials +stale-nonce=600 # Nonce timeout in seconds +realm=turn.example.com # Your server's domain +server-name=turn.example.com +no-multicast-peers # Security measure +dh2066 # Strong DH params +no-stdout-log # Disable stdout logging +``` -Ultimately though, if you are still getting the 701 error -- just test to see if the TURN service works; if it does, the error can probably be ignored. +## SSL/TLS Support (Optional) +The installer can configure SSL/TLS support which: +- Enables TURNS (TURN over TLS) on port 443 +- Automatically obtains and renews SSL certificates via certbot +- Configures automatic certificate reload without server restart -The following are the contents of an example /etc/turnserver.conf file from above -``` -## sudo vi /etc/turnserver.conf +## Testing Your Server -listening-port=3478 -## TLS needs an SSL certificate and domain, but enables TCP -tls-listening-port=443 +Test your TURN server at: https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ -# min-port=49152 -# max-port=65535 +Example configurations to test: +- STUN/TURN: `turn:your-domain:3478` +- TURNS (if SSL enabled): `turns:your-domain:443` -realm=turn.obs.ninja -server-name=turn.obs.ninja +## Firewall Configuration -## webrtc likes to use this -fingerprint +Required ports: +- 3478 TCP/UDP (STUN/TURN) +- 443 TCP/UDP (TURNS, if enabled) +- 49152:65535 TCP/UDP (Media relay ports) -## Lets just use Google since its more reliable -no-stun +## Advanced Usage -lt-cred-mech -user=SOMESUERNAME:SOMEPASSWQORD +### Reloading SSL Certificates +```bash +sudo systemctl --signal=SIGUSR2 kill coturn +``` -stale-nonce=600 +### Checking Server Status +```bash +sudo systemctl status coturn +``` -## depreciated in newer coturn -# no-loopback-peers +### Updating Configuration +1. Edit `/etc/turnserver.conf` +2. Restart service: `sudo systemctl restart coturn` -## prevents hackers from hacking -no-multicast-peers +## Common Issues -## 1-gbps/100 users = ~ 1-mbps each with this setting then -total-quota=100 +1. **Permission denied errors** + - The installer handles this by setting proper capabilities + - Manual fix: `sudo setcap cap_net_bind_service=+ep /usr/bin/turnserver` -cert=/etc/letsencrypt/live/turn.obs.ninja/fullchain.pem -pkey=/etc/letsencrypt/live/turn.obs.ninja/privkey.pem +2. **SSL certificate errors (701)** + - Verify certificate permissions + - Check certificate paths in configuration + - Ensure certificates are readable by turnserver user -## Tweaks to fix some lets encrypt errors -cipher-list="ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384" -no-sslv3 -no-tlsv1 -no-tlsv1_1 -# no-tlsv1_2 -dh2066 +## Production Considerations -# no-udp -# no-tcp +1. **System Limits** + The installer configures higher system limits for production use: + - File descriptors: 65535 + - System max files: 65535 -# verbose -no-stdout-log +2. **Monitoring** + - Monitor bandwidth usage + - Watch for high CPU/memory usage + - Track active connections -## optional -proc-user=root -proc-group=root +3. **Security** + - Regularly update credentials + - Monitor for abuse + - Keep coturn and SSL certificates up to date -``` +## Support -For those who are using Certificates with their coturn installations, you can use `sudo systemctl --signal=SIGUSR2 kill coturn` to reload the certs in coturn without restarting and disconnecting current users. This can be especially useful for certbot users, who need to update every few months; triggering the command after certbot runs could make life easy. +For issues or questions: +- Create an issue on the VDO.Ninja GitHub repository +- Join the VDO.Ninja Discord community -Anyways, setting this all up is easier said then done. My suggestion is to start simple, get that working, and if needed, improve from there. good luck! +## References +- [Coturn Documentation](https://github.com/coturn/coturn/wiki/turnserver) +- [WebRTC Samples](https://webrtc.github.io/samples/) +- [VDO.Ninja GitHub](https://github.com/steveseguin/vdo.ninja) \ No newline at end of file diff --git a/turnserver2.conf b/turnserver2.conf deleted file mode 100644 index a54da1fd1..000000000 --- a/turnserver2.conf +++ /dev/null @@ -1,52 +0,0 @@ -listening-port=3478 -alt-listening-port=3479 - -## TLS needs an SSL certificate and domain, but enables TCP -tls-listening-port=443 -alt-tls-listening-port=444 - -# min-port=10000 -# max-port=20000 - -realm=www.turn.obs.ninja -server-name=www.turn.obs.ninja - -fingerprint - -## Lets just use Google since its more reliable -no-stun - -lt-cred-mech -user=UUUUU:PPPPPPPPPPPPP - -stale-nonce=600 - -## depreciated in newer coturn -# no-loopback-peers - -no-multicast-peers - -## 1-gbps/100 users = 1mbps each -total-quota=100 - -cert=/var/certs/turn_obs_ninja_chain.crt -pkey=/var/certs/turn_obs_ninja.key - -## Tweaks to fix some lets encrypt errors -# cipher-list="ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384" -# no-sslv3 -# no-tlsv1 -# no-tlsv1_1 -# no-tlsv1_2 -dh2066 - -# max-bps=650000 -# no-udp -# no-tcp - -#verbose -no-stdout-log - -## bypass the letsencrypt bug; easier than modifying the service -#proc-user=root -#proc-group=root diff --git a/turnserver3.conf b/turnserver_basic.conf similarity index 100% rename from turnserver3.conf rename to turnserver_basic.conf diff --git a/turnserver_install.sh.sample b/turnserver_install.sh.sample new file mode 100644 index 000000000..c0fb21439 --- /dev/null +++ b/turnserver_install.sh.sample @@ -0,0 +1,159 @@ +#!/bin/bash + +if [ "$EUID" -ne 0 ]; then + echo "Please run as root or with sudo" + exit 1 +fi + +configure_ssl() { + local DOMAIN=$1 + + # Check if port 80 is in use + if netstat -tuln | grep ':80 '; then + echo "Warning: Port 80 is in use. Stopping potentially conflicting services..." + systemctl stop nginx 2>/dev/null || true + systemctl stop apache2 2>/dev/null || true + fi + + # Install certbot if needed + if ! command -v certbot >/dev/null; then + apt-get install certbot -y + fi + + # Verify domain points to this server + LOCAL_IP=$(curl -s https://api.ipify.org) + DOMAIN_IP=$(dig +short "$DOMAIN") + + echo "Verifying domain configuration..." + echo "Server IP: $LOCAL_IP" + echo "Domain IP: $DOMAIN_IP" + + if [ "$LOCAL_IP" != "$DOMAIN_IP" ]; then + echo "Warning: Domain $DOMAIN does not point to this server's IP ($LOCAL_IP)" + read -p "Continue anyway? (y/N): " CONTINUE + if [ "${CONTINUE,,}" != "y" ]; then + return 1 + fi + fi + + # Try to get the cert + if ! certbot certonly --standalone --preferred-challenges http -d "$DOMAIN"; then + echo "Failed to obtain SSL certificate. Trying alternative method..." + if ! certbot certonly --standalone --preferred-challenges tls-alpn-01 -d "$DOMAIN"; then + return 1 + fi + fi + + # Update turnserver.conf with SSL settings + cat >> /etc/turnserver.conf << EOL +cert=/etc/letsencrypt/live/${DOMAIN}/fullchain.pem +pkey=/etc/letsencrypt/live/${DOMAIN}/privkey.pem +tls-listening-port=443 +EOL + + # Create renewal hook + mkdir -p /etc/letsencrypt/renewal-hooks/deploy + cat > /etc/letsencrypt/renewal-hooks/deploy/coturn-reload << EOL +#!/bin/bash +systemctl --signal=SIGUSR2 kill coturn +EOL + chmod +x /etc/letsencrypt/renewal-hooks/deploy/coturn-reload + + return 0 +} + +# Main installation function +install_coturn() { + local DOMAIN=$1 + local USERNAME=$2 + local PASSWORD=$3 + + # Install required packages + apt-get update + apt-get install coturn curl dnsutils -y + + # Configure system limits + echo "fs.file-max = 65535" >> /etc/sysctl.conf + sysctl -p + ulimit -n 65535 + + # Enable TURN server + echo "TURNSERVER_ENABLED=1" > /etc/default/coturn + + # Generate base turnserver configuration + cat > /etc/turnserver.conf << EOL +listening-port=3478 +alt-listening-port=0 +fingerprint +lt-cred-mech +# STUN/TURN configuration +stun-port=3478 +min-port=49152 +max-port=65535 +user=${USERNAME}:${PASSWORD} +stale-nonce=600 +realm=${DOMAIN} +server-name=${DOMAIN} +no-multicast-peers +dh2066 +no-stdout-log +EOL + + # Set proper permissions for binding to privileged ports + setcap cap_net_bind_service=+ep /usr/bin/turnserver + + # Start services + systemctl daemon-reload + systemctl enable coturn + systemctl start coturn +} + +# Main script execution +echo "TURN Server Installation and Configuration" +echo "----------------------------------------" + +# Get or verify domain +while true; do + read -p "Enter your domain (e.g., turn.example.com): " DOMAIN + echo "Verifying domain..." + if dig +short "$DOMAIN" >/dev/null; then + break + else + echo "Warning: Domain $DOMAIN does not appear to be configured. Please verify DNS settings." + read -p "Try a different domain? (Y/n): " RETRY + if [ "${RETRY,,}" = "n" ]; then + break + fi + fi +done + +read -p "Enter username for TURN: " USERNAME +read -s -p "Enter password for TURN: " PASSWORD +echo + +# Install base TURN server +install_coturn "$DOMAIN" "$USERNAME" "$PASSWORD" + +# Configure SSL if desired +read -p "Do you want to enable SSL/TLS support? (y/N): " ENABLE_SSL +if [ "${ENABLE_SSL,,}" = "y" ]; then + if ! configure_ssl "$DOMAIN"; then + echo "SSL configuration failed. You can retry SSL setup later by running:" + echo "certbot delete" + echo "certbot certonly --standalone -d $DOMAIN" + echo "Then restart coturn: systemctl restart coturn" + fi +fi + +# Display status +systemctl status coturn + +echo "Installation complete!" +echo "----------------------------------------" +echo "Domain: $DOMAIN" +echo "Username: $USERNAME" +echo "STUN/TURN ports: 3478 (default)" +if [ "${ENABLE_SSL,,}" = "y" ]; then + echo "TLS enabled on port 443" + echo "SSL certificates will automatically renew via certbot" +fi \ No newline at end of file