Instalación y configuración de un servidor TURN Coturn en un VPS para WebRTC: TLS, WebSocket y autorización segura
TL;DR
Coturn es un servidor TURN/STUN para WebRTC que transmite audio, vídeo y tráfico de DataChannel entre clientes cuando NAT, CGNAT o los firewall corporativos bloquean la conexión P2P directa. En esta guía se configura Coturn en Ubuntu Server 24.04 LTS con un certificado TLS de Let’s Encrypt, autenticación REST segura y reglas de firewall para los puertos relay UDP/TCP.
- TURN se necesita como ruta alternativa para transmitir tráfico multimedia en WebRTC cuando STUN no permite establecer una conexión directa.
- Coturn escuchará STUN/TURN en los puertos
3478y5349, y el tráfico relay en un rango limitado de puertos UDP. - TLS se habilita directamente en Coturn con certificados de Let’s Encrypt; el proxy inverso no debe terminar TURN-TLS.
- WebSocket se utiliza para el canal de señalización seguro de WebRTC mediante
wss://, pero Coturn no convierte TURN en un servidor WebSocket. - En lugar de credenciales permanentes, se utilizan credenciales TURN de corta duración mediante el mecanismo
use-auth-secret. - Después de la configuración, el servidor se comprueba mediante los registros de Coturn, la utilidad
turnutils_uclienty el diagnóstico WebRTC del navegador.
Qué configuramos y por qué
WebRTC permite que los navegadores, las aplicaciones móviles y los clientes de escritorio transmitan voz, vídeo, pantalla y datos arbitrarios en tiempo real. En el caso ideal, dos clientes establecen una conexión P2P directa. En la práctica, esto suele fallar: el usuario está detrás de un NAT simétrico, un CGNAT móvil, un firewall de oficina estricto, la Wi-Fi de un hotel o una red que solo permite tráfico HTTPS.
Un servidor STUN ayuda al cliente a conocer su dirección IP pública y el tipo de NAT. Pero STUN no transmite medios por sí mismo. Si la ruta directa no está disponible, el cliente WebRTC utiliza un servidor TURN como relay: ambos participantes envían tráfico UDP, TCP o TLS al servidor y Coturn reenvía los paquetes entre ellos. Esto aumenta la fiabilidad de las llamadas, pero significa que el tráfico multimedia pasa por su VPS.
El resultado será la siguiente configuración:
- STUN/TURN por UDP y TCP en
turn.example.com:3478; - TURN over TLS en
turns:turn.example.com:5349; - rango de puertos relay, por ejemplo,
49160-49200/udp; - autenticación de usuarios de corta duración mediante un secreto compartido del servidor;
- renovación automática del certificado TLS de Let’s Encrypt;
- si es necesario, señalización WebSocket independiente mediante
wss://signal.example.com.
TURN, TLS y WebSocket: una distinción importante
WebRTC consta de varias partes independientes. La señalización transmite SDP offer/answer y candidatos ICE. Normalmente se realiza mediante WebSocket, Socket.IO, una API HTTPS, XMPP u otro canal de aplicación. Para el servidor de señalización se utiliza wss://, es decir, WebSocket sobre HTTPS.
TURN resuelve otra tarea: transmite el tráfico multimedia de WebRTC ya acordado. Coturn admite TURN por UDP, TCP y TLS, pero una instalación normal de Coturn no es un servidor TURN WebSocket. No se puede colocar Caddy o Nginx delante del puerto 3478 y esperar que TURN funcione mediante WebSocket: son protocolos distintos. Si su red corporativa solo permite TCP/443, utilice TURN over TLS en 5349 o una IP y un puerto 443 dedicados, siempre que no haya conflictos con HTTPS.
TURN autoalojado o TURN gestionado
| Criterio | TURN gestionado | Coturn propio en un VPS |
|---|---|---|
| Puesta en marcha | Rápida, sin administración | Se necesitan DNS, firewall, TLS y monitorización |
| Control de los datos | El tráfico pasa por un operador externo | El enrutamiento y los registros están bajo su control |
| Coste a medida que aumenta el tráfico | A menudo depende de los GB transferidos | La principal limitación es el tráfico incluido en el VPS |
| Configuración de la autenticación | Limitada por la API del proveedor | Se puede integrar con su propio backend |
| Ubicación geográfica | Depende de las regiones disponibles | Se puede elegir un VPS cerca de la audiencia |
El autoalojamiento de Coturn es una opción razonable para un chat de vídeo propio, un producto SaaS, Mattermost Calls, Jitsi, LiveKit, Janus, mediasoup, una aplicación móvil o las comunicaciones corporativas internas. Para un producto pequeño, ofrece una infraestructura predecible. Sin embargo, hay que calcular de antemano el tráfico saliente: en una conexión relay, el servidor suele recibir el flujo de un cliente y enviarlo al otro, por lo que 1 GB de vídeo transmitido puede requerir aproximadamente 2 GB de tráfico de red del servidor.
Qué configuración de VPS se necesita para esta tarea
Coturn consume poca CPU y RAM porque no recodifica el vídeo ni analiza el flujo multimedia. La carga principal recae en el ancho de banda de la red, el número de allocations simultáneas y los paquetes por segundo. En una llamada grupal con SFU, el tráfico TURN suele ser menor que en una llamada en malla, aunque depende de la arquitectura de la aplicación y del comportamiento de los clientes.
| Escenario | CPU | RAM | Disco | Red |
|---|---|---|---|---|
| Pruebas, entre 5 y 20 usuarios relay simultáneos | 1 vCPU | 1 GB | 10 GB SSD | 100 Mbit/s, IPv4 pública |
| Producto pequeño, entre 20 y 100 usuarios simultáneos | 2 vCPU | 2 GB | 20 GB SSD | 1 Gbit/s, desde 1 TB de tráfico |
| Videollamadas continuas, entre 100 y 500 usuarios relay | 4 vCPU | 4–8 GB | 40 GB SSD | 1 Gbit/s, gran volumen de tráfico o tráfico ilimitado |
Para el primer despliegue en producción bastan 2 vCPU, 2 GB de RAM, 20 GB SSD, IPv4 estática y un canal de 1 Gbit/s. Puede elegir una opción como un VPS con las características indicadas. Más importante que el espacio en disco es disponer de un ancho de banda garantizado o claramente definido, no tener un límite estricto de paquetes por segundo y contar con un volumen mensual suficiente de tráfico saliente.
Cuándo se necesita un servidor dedicado en lugar de un VPS
Un servidor dedicado está justificado cuando el tráfico relay ocupa de forma sostenida cientos de megabits o gigabits por segundo, se necesitan valores de PPS predecibles, hacen falta varias IP públicas o el servicio atiende cientos o miles de flujos de vídeo simultáneos. Un servidor dedicado también resulta útil si se necesita distribuir TURN entre nodos geográficos independientes y evitar depender de la virtualización de otros clientes.
No es necesario pasarse a un servidor dedicado solo porque la configuración incluya TLS. El cifrado TURN requiere CPU, pero en los procesadores modernos varios cientos de conexiones moderadas normalmente no representan un problema. Primero mida las métricas reales: CPU, tráfico entrante y saliente, número de allocations, pérdida de paquetes y latencia.
Cómo elegir la ubicación
TURN añade latencia a la ruta de los paquetes multimedia, por lo que conviene ubicar el servidor cerca de la mayoría de la audiencia. Para usuarios de Alemania, Polonia y los Países Bajos, es adecuada una ubicación en Europa central. Si los participantes de una conversación están en distintas regiones, un único servidor TURN será una solución de compromiso: el tráfico de ambos pasará por él.
Los productos globales utilizan varios nodos Coturn y proporcionan al cliente una lista regional de servidores ICE. No elija una ubicación únicamente por su precio: la pérdida de paquetes, un peering deficiente y una latencia alta afectan más a las llamadas que a un sitio web convencional.
Preparación del servidor
A continuación se presupone una instalación limpia de Ubuntu Server 24.04 LTS con una dirección IPv4 pública. Realice la conexión inicial como root y, después, cree un administrador normal. Antes de configurar DNS, cree un registro A turn.example.com que apunte a la IP del VPS. Para validar TLS, el registro ya debe estar propagado en DNS.
Actualice el sistema e instale las utilidades básicas
apt update && apt upgrade -y
apt install -y sudo curl ca-certificates gnupg ufw fail2ban dnsutils jq
reboot
El primer comando actualiza los paquetes de Ubuntu, instala herramientas de administración y reinicia el servidor si se han actualizado el kernel o las bibliotecas del sistema.
Cree un usuario para la administración
adduser deploy
usermod -aG sudo deploy
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
nano /home/deploy/.ssh/authorized_keys
chmod 600 /home/deploy/.ssh/authorized_keys
chown deploy:deploy /home/deploy/.ssh/authorized_keys
Pegue su clave SSH pública en una sola línea en authorized_keys. Antes de desactivar el acceso de root, abra una segunda sesión SSH y compruebe que el acceso como deploy funciona correctamente.
Desactive el acceso SSH mediante contraseña
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
cat > /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
EOF
sshd -t && systemctl restart ssh
El archivo en sshd_config.d sustituye los valores peligrosos sin modificar el archivo principal. El comando sshd -t comprueba la sintaxis antes de reiniciar SSH.
Configure UFW y Fail2ban
Coturn requiere UDP y TCP en el puerto 3478, TCP en 5349, UDP en 5349 para las variantes DTLS y, además, el rango relay. En el ejemplo se utiliza el rango limitado 49160:49200: 41 puertos UDP. Es suficiente para un servicio de prueba o pequeño. Cuantas más sesiones relay simultáneas haya, más amplio deberá ser el rango.
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 3478/tcp
ufw allow 3478/udp
ufw allow 5349/tcp
ufw allow 5349/udp
ufw allow 49160:49200/udp
ufw enable
ufw status numbered
Los puertos 80/tcp y 443/tcp se necesitan para emitir el certificado y para la futura señalización HTTPS/WSS. Si el servidor no tendrá una aplicación de señalización, puede cerrar el puerto 80 después de emitir el certificado si utiliza el desafío DNS; para la renovación HTTP-01 estándar, deberá permanecer accesible.
systemctl enable --now fail2ban
fail2ban-client status
timedatectl set-timezone UTC
timedatectl status
Fail2ban protege principalmente SSH. La autenticación TURN se protegerá con credenciales de corta duración, por lo que normalmente es menos útil bloquear errores TURN específicos mediante Fail2ban que limitar el acceso con el firewall y vigilar las anomalías del tráfico.
Instalación del software: paso a paso
Ubuntu 24.04 LTS ofrece el paquete Coturn de la rama 4.6.x. Para producción, es recomendable utilizar el paquete de la distribución: recibe actualizaciones de seguridad junto con el sistema, está correctamente integrado con systemd e incluye utilidades de diagnóstico. Al planificar la infraestructura en 2026, opte por la versión estable más reciente de la rama Coturn 4.6.x o posterior disponible en el repositorio de seguridad de su distribución.
Instale Coturn y Certbot
apt update
apt install -y coturn certbot
turnserver --version
certbot --version
El comando instala el servidor TURN/STUN y el cliente ACME de Let’s Encrypt. Compruebe la versión de Coturn: el paquete no debe estar obsoleto ni haberse compilado desde un repositorio de terceros no verificado.
Habilite el servicio systemd de Coturn
systemctl unmask coturn
systemctl enable coturn
systemctl status coturn --no-pager
En algunas compilaciones de Ubuntu, el servicio puede estar enmascarado antes de la configuración inicial. Mientras no se haya creado el archivo de configuración, es posible que el servicio termine con un error; es normal. Lo iniciaremos definitivamente después de crear la configuración.
Obtenga un certificado TLS
Antes de ejecutar el comando, asegúrese de que turn.example.com resuelva a la IP pública de este servidor y que el puerto 80/tcp sea accesible desde el exterior. Durante la comprobación, Certbot iniciará su propio servidor HTTP temporal.
systemctl stop coturn
certbot certonly --standalone \
--non-interactive \
--agree-tos \
--email [email protected] \
-d turn.example.com
Sustituya [email protected] y el dominio por los valores reales. Los certificados aparecerán en el directorio /etc/letsencrypt/live/turn.example.com/. No copie la clave privada en directorios personales ni la añada a Git.
Cree un grupo independiente para leer el certificado
El servicio Coturn suele ejecutarse con el usuario del sistema turnserver. El acceso a privkey.pem debe concederse únicamente al usuario que lo necesite, mediante el grupo ssl-cert.
usermod -aG ssl-cert turnserver
chgrp ssl-cert /etc/letsencrypt/live/turn.example.com/privkey.pem
chmod 640 /etc/letsencrypt/live/turn.example.com/privkey.pem
namei -l /etc/letsencrypt/live/turn.example.com/privkey.pem
Los enlaces simbólicos de live apuntan al directorio archive, por lo que los permisos pueden cambiar después de renovar el certificado. Más adelante añadiremos un deploy hook que vuelva a establecer los permisos y reinicie Coturn.
Genere un secreto para la autenticación REST
install -d -m 750 /etc/coturn
umask 077
openssl rand -hex 32 > /etc/coturn/auth-secret
chown root:turnserver /etc/coturn/auth-secret
chmod 640 /etc/coturn/auth-secret
cat /etc/coturn/auth-secret
Este comando crea un secreto de 256 bits. Guárdelo en un almacén de secretos seguro. El último comando mostrará el valor para transferirlo de forma segura al backend de la aplicación; no lo ejecute en un terminal que registre el historial o durante una demostración en pantalla.
Configuración de Coturn, TLS y señalización WebSocket
En producción, no utilice lt-cred-mech con usuarios permanentes si su backend puede emitir credenciales temporales. El modo use-auth-secret permite que la aplicación genere un nombre de usuario con el formato de una hora de expiración Unix y un identificador de usuario, y calcule la contraseña como un HMAC-SHA1 del nombre de usuario usando un secreto del servidor. Coturn verifica la credencial localmente, sin una base de datos.
Cree la configuración principal de Coturn
Sustituya la IP, el dominio y la dirección de la interfaz por los suyos. Si su VPS tiene una única IPv4 pública y no está detrás de una NAT interna, puede indicar la dirección pública en external-ip. Si el VPS está detrás de una NAT, utilice el formato PUBLIC_IP/PRIVATE_IP.
# /etc/turnserver.conf
listening-port=3478
tls-listening-port=5349
listening-ip=0.0.0.0
relay-ip=PUBLIC_IPV4
external-ip=PUBLIC_IPV4
realm=turn.example.com
server-name=turn.example.com
fingerprint
min-port=49160
max-port=49200
use-auth-secret
static-auth-secret=REPLACE_WITH_SECRET_FROM_AUTH_SECRET_FILE
no-multicast-peers
no-loopback-peers
stale-nonce=600
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
no-tlsv1
no-tlsv1_1
cipher-list=HIGH:!aNULL:!MD5:!RC4
no-cli
no-tcp-relay
log-file=/var/log/turnserver/turnserver.log
simple-log
syslog
El parámetro no-tcp-relay desactiva las asignaciones de relay TCP, pero no desactiva la recepción de TURN mediante TCP o TLS. En la mayoría de los casos de uso de WebRTC, es preferible el relay mediante UDP: ofrece menor latencia y menos bloqueo de línea principal. Si sus clientes realmente necesitan relay mediante TCP, elimine esta línea y pruebe la carga por separado.
La opción fingerprint habilita el atributo FINGERPRINT obligatorio para garantizar la compatibilidad y la integridad de los mensajes STUN. no-multicast-peers y no-loopback-peers impiden utilizar TURN como proxy hacia direcciones multicast o loopback. Limitar los puertos facilita el control del firewall y reduce la superficie de abuso.
Introduzca el secreto sin guardarlo en Git
El servicio lee el archivo de Coturn, que contiene un secreto, así que establezca permisos estrictos. Si la configuración se gestiona con Ansible, Terraform u otra herramienta de IaC, proporcione el secreto mediante variables cifradas o un gestor de secretos, en lugar de guardarlo en el repositorio.
SECRET="$(cat /etc/coturn/auth-secret)"
sed -i "s/REPLACE_WITH_SECRET_FROM_AUTH_SECRET_FILE/${SECRET}/" /etc/turnserver.conf
chown root:turnserver /etc/turnserver.conf
chmod 640 /etc/turnserver.conf
install -d -m 750 -o turnserver -g turnserver /var/log/turnserver
turnserver -c /etc/turnserver.conf -o -v
El último comando inicia Coturn en primer plano con una salida detallada. Si la sintaxis, la IP, el certificado o los permisos de la clave son incorrectos, el error aparecerá de inmediato. Después de la comprobación, detenga el proceso de prueba con Ctrl+C.
Inicie el servicio y compruebe los puertos de escucha
systemctl restart coturn
systemctl enable coturn
systemctl status coturn --no-pager
ss -lntup | grep -E ':(3478|5349)\b'
journalctl -u coturn -n 100 --no-pager
Se esperan UDP y TCP en 3478, TCP en 5349 y, según la compilación y la configuración de TLS/DTLS, UDP en 5349. No exponga la CLI administrativa de Coturn a Internet: está desactivada en la configuración mediante la directiva no-cli.
Configure la renovación automática del certificado
cat > /etc/letsencrypt/renewal-hooks/deploy/reload-coturn.sh <<'EOF'
#!/bin/sh
chgrp ssl-cert /etc/letsencrypt/live/turn.example.com/privkey.pem
chmod 640 /etc/letsencrypt/live/turn.example.com/privkey.pem
systemctl restart coturn
EOF
chmod 750 /etc/letsencrypt/renewal-hooks/deploy/reload-coturn.sh
certbot renew --dry-run
systemctl list-timers | grep certbot
El deploy hook reinicia Coturn solo después de que el certificado se haya renovado correctamente. El comando --dry-run comprueba que la renovación se realizará antes de que caduque el certificado. Un reinicio breve puede interrumpir las asignaciones activas, así que realice los cambios manuales de certificados durante una ventana de mantenimiento.
Cómo genera el backend las credenciales TURN temporales
El nombre de usuario suele tener el formato EXPIRES:USER_ID, donde EXPIRES es una marca de tiempo Unix. La contraseña es la representación Base64 de un HMAC-SHA1 del nombre de usuario con el secreto compartido. La duración, de 1 a 24 horas, se elige según la duración de las sesiones: para una videollamada, a menudo bastan entre 3600 y 7200 segundos. No emita credenciales con una vigencia de meses: si se filtra esa contraseña, otros podrán utilizar su relay para tráfico ajeno.
import crypto from 'node:crypto';
const secret = process.env.TURN_AUTH_SECRET;
const ttlSeconds = 3600;
const expires = Math.floor(Date.now() / 1000) + ttlSeconds;
const username = ${expires}:user-12345;
const credential = crypto
.createHmac('sha1', secret)
.update(username)
.digest('base64');
const iceServers = [
{
urls: [
'turn:turn.example.com:3478?transport=udp',
'turn:turn.example.com:3478?transport=tcp',
'turns:turn.example.com:5349?transport=tcp'
],
username,
credential
}
];
Proporcione el secreto a la aplicación mediante una variable de entorno, credenciales de systemd, un Kubernetes Secret o un vault. No envíe TURN_AUTH_SECRET al navegador. Al navegador solo se le envían username y credential temporales.
Ejemplo de variables de entorno del backend
cat > /etc/myapp/turn.env <<'EOF'
TURN_HOST=turn.example.com
TURN_TLS_PORT=5349
TURN_AUTH_SECRET=replace-with-the-same-secret
TURN_CREDENTIAL_TTL=3600
EOF
chmod 600 /etc/myapp/turn.env
El archivo /etc/myapp/turn.env es un ejemplo para su API de señalización. Coturn no lee este archivo: utiliza el valor de static-auth-secret de su configuración. Ambos valores deben coincidir.
Comprobación de TLS y prueba funcional
openssl s_client -connect turn.example.com:5349 \
-servername turn.example.com -brief < /dev/null
turnutils_uclient -u "EXPIRES:user-12345" \
-w "GENERATED_PASSWORD" \
-p 3478 turn.example.com
tail -f /var/log/turnserver/turnserver.log
El primer comando comprueba el certificado y el establecimiento de la conexión TLS. El segundo forma parte del paquete Coturn y crea una prueba de cliente; introduzca un par nuevo de credenciales temporales. Busque en el registro una autenticación correcta y la creación de una asignación. Para realizar la prueba desde el navegador, utilice la página de prueba de su aplicación, abra chrome://webrtc-internals y asegúrese de que el candidate pair seleccionado sea de tipo relay en una red donde P2P no esté disponible.
Señalización WebSocket mediante Caddy
Si tiene un servidor de señalización en el puerto local 3000, Caddy puede proporcionar HTTPS automáticamente y actuar como proxy de las conexiones WebSocket. Se trata de un servicio y un dominio independientes, por ejemplo, signal.example.com. No dirija los puertos UDP de Coturn a través de Caddy ni configure TURN como proxy HTTP.
signal.example.com {
reverse_proxy 127.0.0.1:3000
}
Caddy admite automáticamente la actualización a WebSocket y obtiene un certificado HTTPS para el dominio de señalización. En el cliente, conéctese a wss://signal.example.com y obtenga la configuración ICE con las credenciales TURN mediante una API autorizada o a través del mismo canal de señalización. Si el servidor de señalización está en otro nodo, podrá emitir credenciales de corta duración para Coturn sin problema.
Copias de seguridad y mantenimiento
Coturn en modo use-auth-secret no almacena usuarios, registros de llamadas ni datos multimedia. Por lo tanto, debe hacer copias de seguridad no del tráfico relay, sino de la configuración, los materiales TLS, los secretos, las reglas del firewall y los scripts de infraestructura. Si su backend almacena usuarios, salas, historial o grabaciones, haga una copia de seguridad de su base de datos mediante un proceso aparte.
Qué incluir en la copia de seguridad
/etc/turnserver.confy el archivo del secreto/etc/coturn/auth-secret;/etc/letsencrypt, si necesita restaurar rápidamente los certificados existentes;- las configuraciones de Caddy y de la aplicación de señalización;
- volcados de PostgreSQL, MySQL u otra base de datos de la aplicación backend;
- la lista de paquetes, las reglas de UFW y la documentación de los registros DNS;
- opcional: registros de Coturn con un período de conservación corto para investigar incidentes.
No guarde la única copia del secreto en el mismo VPS. Si pierde el secreto, puede generar uno nuevo, pero todas las credenciales activas dejarán de funcionar de inmediato. Es un escenario de emergencia admisible, pero es mejor gestionarlo de forma controlada.
Ejemplo de copia de seguridad con Restic
apt install -y restic
export RESTIC_REPOSITORY="s3:https://s3.example.net/turn-backups"
export RESTIC_PASSWORD_FILE="/root/.config/restic/password"
export AWS_ACCESS_KEY_ID="REPLACE_ME"
export AWS_SECRET_ACCESS_KEY="REPLACE_ME"
restic init
restic backup /etc/turnserver.conf /etc/coturn /etc/letsencrypt /etc/caddy
restic snapshots
Sustituya la dirección S3 y las credenciales. En producción, pase las variables mediante un archivo de entorno protegido y accesible solo para root o una unidad de systemd, en lugar de guardar las claves en el historial del shell. Otra opción es usar un VPS de backup independiente mediante SSH, BorgBackup o rsync sobre SSH con una clave limitada únicamente al comando de copia de seguridad.
Script y cron
cat > /usr/local/sbin/backup-coturn.sh <<'EOF'
#!/bin/sh
set -eu
. /root/.config/restic/env
restic backup /etc/turnserver.conf /etc/coturn /etc/letsencrypt /etc/caddy
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
EOF
chmod 700 /usr/local/sbin/backup-coturn.sh
cat > /etc/cron.d/backup-coturn <<'EOF'
17 3 * root /usr/local/sbin/backup-coturn.sh >> /var/log/backup-coturn.log 2>&1
EOF
El archivo /root/.config/restic/env debe tener permisos 600 y contener las variables de Restic. Una vez cada trimestre, pruebe la restauración en una máquina aparte: una copia de seguridad que no se ha probado mediante una restauración no es fiable.
Actualizaciones y ventana de mantenimiento
Puede instalar las actualizaciones de seguridad de Ubuntu con regularidad, pero actualizar Coturn, OpenSSL o reiniciar el servicio puede interrumpir las asignaciones relay activas. Para un servicio pequeño, elija una ventana de mantenimiento breve, avise a los usuarios con antelación y ejecute:
apt update
apt list --upgradable
apt upgrade -y
systemctl restart coturn
systemctl status coturn --no-pager
journalctl -u coturn -n 50 --no-pager
Para lograr alta disponibilidad, use al menos dos nodos TURN en distintas zonas y devuelva a los clientes varias URL en iceServers. Así podrá hacer las actualizaciones de forma escalonada: deje de emitir nuevas credenciales para un nodo, espere a que terminen las llamadas, actualícelo y vuelva a incorporarlo al grupo.
Troubleshooting + FAQ
¿Por qué el navegador no usa el candidato relay aunque Coturn esté en ejecución?
No siempre se trata de un error. WebRTC prefiere una ruta directa host o server-reflexive si funciona. Para comprobar TURN, pruebe con dos clientes en redes distintas, por ejemplo, con internet móvil y una red corporativa. En chrome://webrtc-internals, consulte el par de candidatos seleccionado. Si no aparecen candidatos relay, compruebe que la URL y las credenciales temporales sean correctas, revise el DNS, la disponibilidad de 3478/udp y las líneas de los registros de Coturn con errores de autenticación.
Error 401 Unauthorized o Wrong credentials al conectarse a TURN: ¿qué hacer?
Compruebe que el backend y Coturn utilicen el mismo static-auth-secret. El nombre de usuario debe contener una marca de tiempo Unix futura y la contraseña debe ser el resultado en Base64 de HMAC-SHA1 aplicado exactamente a la cadena username. Un error frecuente es usar HMAC-SHA256, codificación hexadecimal en lugar de Base64 o una marca de tiempo en milisegundos. Sincronice también la hora del servidor mediante systemd-timesyncd o chrony: Coturn rechazará las credenciales caducadas.
¿Por qué TURN funciona por UDP, pero no se conecta con turns:// en el puerto 5349?
Primero, compruebe openssl s_client con el parámetro -servername. Si no se puede leer el certificado, revise los permisos de privkey.pem, el grupo ssl-cert y el registro de journalctl -u coturn. A continuación, asegúrese de que 5349/tcp esté abierto en UFW y en el firewall externo del panel del proveedor. Compruebe que el nombre DNS del certificado coincida con el nombre de la URL TURN; de lo contrario, el navegador rechazará la conexión TLS.
¿Por qué las llamadas funcionan en casa, pero no desde una red móvil o corporativa?
La red doméstica puede permitir P2P, por lo que TURN no se utiliza en ese caso. En la red problemática, a menudo se bloquea UDP o se usa NAT simétrico. Asegúrese de proporcionar al cliente no solo turn: con UDP, sino también una variante TCP en 3478 y turns: en 5349. Compruebe que no-tcp-relay no esté habilitado si sus clientes necesitan específicamente relay TCP y no solo una conexión TCP al servidor.
¿Qué significa el error Allocate request timed out?
Normalmente, la solicitud llegó a Coturn, pero el servidor no pudo crear ni usar el socket relay. Compruebe external-ip, relay-ip, el rango min-port/max-port y que dicho rango esté permitido en UFW y en el firewall de red. Si el VPS está detrás de un NAT privado, indique obligatoriamente la correspondencia entre la IP pública y la privada con el formato external-ip=PUBLIC/PRIVATE. Compruebe también que el rango relay no sea demasiado estrecho y se haya agotado debido a un gran número de llamadas.
¿Qué configuración mínima de VPS es adecuada?
Para desarrollo, pruebas y unas pocas decenas de llamadas ocasionales, basta con 1 vCPU, 1 GB de RAM, 10 GB de SSD y una IPv4 pública. Para un servicio de producción pequeño, un mínimo razonable es 2 vCPU, 2 GB de RAM, 20 GB de SSD y un canal de 1 Gbit/s. Evalúe no solo los recursos de cómputo: TURN consume tráfico en ambas direcciones, así que el límite de gigabytes incluidos y la calidad de la red suelen ser más importantes que la RAM.
¿Qué elegir para esta tarea: VPS o un servidor dedicado?
Un VPS es adecuado para la mayoría de los proyectos WebRTC pequeños y medianos: Coturn no necesita mucho espacio en disco y es fácil de escalar añadiendo nuevos nodos. Elija un servidor dedicado si necesita gestionar una carga alta y estable, garantizar una tasa de paquetes predecible, manejar gigabits de tráfico relay o utilizar muchas IP públicas. Empiece con un nodo VPS monitorizado, recopile métricas de llamadas reales y pase a un servidor dedicado solo cuando haya confirmado una carga de red o de CPU suficiente para justificarlo.
¿Se puede usar el puerto 443 para TURN si ya está ocupado por un sitio HTTPS?
En una misma IP y un mismo puerto TCP no se puede atender directamente y a la vez un sitio HTTPS y TURN-TLS sin multiplexación L4 especial. La opción estándar y sencilla es HTTPS/WSS en el puerto 443 y TURN-TLS en el 5349. Si los usuarios están detrás de firewalls muy restrictivos, use una IP aparte para TURN en el puerto 443 o un nodo TURN independiente. No intente resolverlo con un proxy inverso HTTP convencional: TURN no es un protocolo HTTP.
Conclusiones y próximos pasos
Ahora tiene un servidor Coturn TURN/STUN con un rango relay limitado, un certificado TLS, protección de firewall y autenticación segura de corta duración. Esta configuración permite que los clientes WebRTC pasen de forma fiable a una ruta relay cuando no es posible establecer una conexión P2P directa.
- Integre la generación de credenciales REST en un backend autorizado y entréguelas únicamente a los participantes de una llamada activa.
- Añada supervisión de la disponibilidad de los puertos, la vigencia del certificado TLS, la CPU, el tráfico y el número de asignaciones.
- A medida que crezca la audiencia, despliegue varios nodos Coturn regionales y actualícelos gradualmente sin detener toda la red.