Como les había anticipado en mi entrada anterior, en este articulo vamos a ver como instalar y configurar un servidor TURN para que los usuarios que se encuentren detrás de una NAT estricto, puedan acceder a las videoconferencias creadas con BBB y no tengan problemas de audio/video. El programa va instalado en un nuevo servidor y en mi caso he optado por Debian 11. Al servidor TURN se asignará un subdominio que en mi caso es turn.voztovoice.org que apuntará a las IPPublicas IPv4 y IPv6 del nuevo servidor. Iniciamos con actualizar el sistema:
apt update
apt upgrade
Continuamos con la instalación del programa, del cortafuegos ufw y del programa para crear los certificados con Let’s Encrypt:
apt install coturn ufw certbot
Creamos el certificado para el subdominio turn.voztovoice.org que luego se utilizará para la configuración de servidor TURN; para que se pueda crear sin problemas miramos si el puerto 80 está abierto en el cortafuegos:
ufw status numbered
en mi caso:
To Action From
-- ------ ----
[ 1] 22 ALLOW IN Anywhere
[ 2] 22 (v6) ALLOW IN Anywhere (v6)
pues lo añadimos:
ufw allow 80/tcp
luego creamos el certificado (PERSONALIZAR NOMBRE SUBDOMINIO Y CORREO ELECTRÓNICO):
certbot certonly --standalone -d turn.voztovoice.org -m campus@voztovoice.org
El resultado:

Let’s Encrypt, con que se ha creado el certificado, permite ejecutar uno script cada vez que se renueve un certificado. Utilizaremos esta característica para que se copien los archivos del certificado en una determinada carpeta y se cambien los permisos para que el usuario turnserver, el usuario con que arranca el servidor TURN, pueda acceder a ellos:
mkdir -p /etc/letsencrypt/renewal-hooks/deploy
nano /etc/letsencrypt/renewal-hooks/deploy/coturn
se copian las siguientes lineas y se PERSONALIZA EL DUBDOMINIO que aparece:
#!/bin/bash -e
for certfile in fullchain.pem privkey.pem ; do
cp -L /etc/letsencrypt/live/turn.voztovoice.org/"${certfile}" /etc/turnserver/"${certfile}".new
chown turnserver:turnserver /etc/turnserver/"${certfile}".new
mv /etc/turnserver/"${certfile}".new /etc/turnserver/"${certfile}"
done
systemctl kill -sUSR2 coturn.service
Se guardan los cambios y se cambiamos los permisos del archivo:
chmod 0755 /etc/letsencrypt/renewal-hooks/deploy/coturn
ya podemos pasar a la personalización del archivo de configuración del servidor TURN; lo abrimos:
nano /etc/turnserver.conf
y empezamos cambiando estas dos lineas:
#listening-port=3478
#tls-listening-port=5349
para que queden:
listening-port=3478
tls-listening-port=443
seguimos cambiando estas dos lineas:
#listening-ip=172.17.19.101
#relay-ip=172.17.19.105
para que queden (MODIFICAR IPPublicav4 y IPPublicav6 CON LA IP PUBLICA V4 Y IPPUBLICA V6 DEL SERVIDOR RESPECTIVAMENTE):
listening-ip=IPPublicav4
listening-ip=IPPublicav6
relay-ip=IPPublicav4
relay-ip=IPPublicav6
modificamos las dos lineas donde se configuran los puertos que utilizará el servidor TURN para redirigir el el flujo media:
#min-port=49152
#max-port=65535
para que queden:
min-port=32769
max-port=65535
se modifica la linea que sigue para activar un debug moderado:
#verbose
para que quede:
verbose
Las opciones que siguen permiten configurar el servidor TURN para que se pueda acceder solamente con una clave; esto para evitar que venga utilizado por otros usuarios y con otros possibles fines:
#fingerprint
#use-auth-secret
#static-auth-secret=north
#realm=mycompany.org
para que queden (PERSONALIZAR static-auth-secret Y realm):
fingerprint
use-auth-secret
static-auth-secret=1cdda865dcad48953a5e2ca03da5a8b8
realm=voztovoice.org
se modifican los parámetros que siguen para la configuración de la parte relacionadas con los certificados:
#cert=/usr/local/etc/turn_server_cert.pem
#pkey=/usr/local/etc/turn_server_pkey.pem
#cipher-list="DEFAULT"
#dh-file=<DH-PEM-file-name>
para que queden (PERSONALIZAR LAS PRIMERAS DOS LINEAS):
cert=/etc/turnserver/fullchain.pem
pkey=/etc/turnserver/privkey.pem
cipher-list="ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
dh-file=/etc/turnserver/dhp.pem
se configura para que los LOG del programa se guarden en un archivo dedicado, modificando estas dos lineas:
#log-file=/var/tmp/turn.log
syslog
para que queden:
log-file=/var/log/turnserver/turnserver.log
#syslog
Se desactiva la consola del servidor TURN, los protocolos tlsv1 y tlsv1.1 y el acceso desde IP utilizadas por el protocolo Multicast; esto modificando las siguientes lineas:
#no-cli
#no-multicast-peers
#no-tlsv1
#no-tlsv1
para que queden:
no-cli
no-multicast-peers
no-tlsv1
no-tlsv1
Se guardan los cambios y se crea el archivo dhp.pem:
mkdir -p /etc/turnserver
openssl dhparam -dsaparam -out /etc/turnserver/dhp.pem 2048
Se cambian los permisos del certificado que se acaba de crear:
chown turnserver:turnserver /etc/turnserver/dhp.pem
Para que el servidor TURN pueda escuchar sobre el puerto 443 TCP, puerto reservado a que no tienen acceso los programas que no se ejecutan con usuario root:
setcap cap_net_bind_service=+ep /usr/bin/turnserver
Se configura el archivo para la rotación de los archivos de LOG:
nano /etc/logrotate.d/coturn
Se copian las lineas que siguen:
/var/log/turnserver/*.log
{
rotate 7
daily
missingok
notifempty
compress
postrotate
/bin/systemctl kill -s HUP coturn.service
endscript
}
Se guardan los cambios y se crea la carpeta para los LOG como indicado en el archivo que se acaba de crear:
mkdir -p /var/log/turnserver
chown turnserver:turnserver /var/log/turnserver
Ejecutamos el archivo para mover los certificados ya que se ejecutará solamente cuando se renueven los certificados y nosotros los necesitamos ahora par poder iniciar el programa Coturn:
/etc/letsencrypt/renewal-hooks/deploy/coturn
Averiguamos que todos los certificados estén bien:

Abrimos los puertos configurados en el servidor TURN; para ver la configuración del Cortafuegos:
ufw status numbered
añadimos primero el puerto 443 udp/tcp utilizado por el protocolo TURN:
ufw allow 443/udp
ufw allow 443/tcp
y los puertos 3478:3479 utilizados por el protocolo STUN:
ufw allow 3478:3479/udp
ufw allow 3478:3479/tcp
luego los puertos utilizados para el flujo media:
ufw allow 32769:65535/udp
Iniciamos el servidor TURN:
systemctl start coturn
averiguamos que esté corriendo:
systemctl status coturn
* coturn.service - coTURN STUN/TURN Server
Loaded: loaded (/lib/systemd/system/coturn.service; enabled; vendor preset: enabled)
Drop-In: /etc/systemd/system/coturn.service.d
ââoverride.conf
Active: active (running) since Sat 2022-11-05 11:18:53 -05; 1h 1min ago
Docs: man:coturn(1)
man:turnadmin(1)
man:turnserver(1)
Main PID: 25786 (turnserver)
Tasks: 9 (limit: 19660)
Memory: 7.6M
CGroup: /system.slice/coturn.service
ââ25786 /usr/bin/turnserver --daemon -c /etc/turnserver.conf --pidfile /run/turnserver/turnserver.pid
Si quieren revisen el LOG. Ahora podemos pasar a la configuración de BBB para que aproveche el servidor TURN que se acaba de configurar. En el servidor donde se encuentra instalado:
cd /usr/share/bbb-web/WEB-INF/classes/spring/
creamos una copia del archivo original:
mv turn-stun-servers.xml turn-stun-servers.xml-orig
creamos uno nuevo:
nano turn-stun-servers.xml
copiamos las lineas que siguen (MODIFICAR turn.voztovoice.org CON SU SUBDOMINIO):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="stun0" class="org.bigbluebutton.web.services.turn.StunServer">
<constructor-arg index="0" value="stun:turn.voztovoice.org"/>
</bean>
<bean id="turn0" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="1cdda865dcad48953a5e2ca03da5a8b8"/>
<constructor-arg index="1" value="turns:turn.voztovoice.org:443?transport=tcp"/>
<constructor-arg index="2" value="86400"/>
</bean>
<bean id="turn1" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="1cdda865dcad48953a5e2ca03da5a8b8"/>
<constructor-arg index="1" value="turn:turn.voztovoice.org:443?transport=tcp"/>
<constructor-arg index="2" value="86400"/>
</bean>
<bean id="stunTurnService"
class="org.bigbluebutton.web.services.turn.StunTurnService">
<property name="stunServers">
<set>
<ref bean="stun0"/>
</set>
</property>
<property name="turnServers">
<set>
<ref bean="turn0"/>
<ref bean="turn1"/>
</set>
</property>
</bean>
</beans>
Guardamos los cambios y reiniciamos BBB:
bbb-conf --restart
para probar el servidor TURN, creamos uno script BASH con el siguiente contenido (PERSONALIZAR turn.voztovoice.org con su subdominio, secret con la clave configurada en el parametro static-auth-secret del archivo de configuración de Coturn):
nano prueba.sh
copiamos:
#!/bin/bash
HOST=turn.voztovoice.org
SECRET=1cdda865dcad48953a5e2ca03da5a8b8
time=$(date +%s)
expiry=8400
username=$(( $time + $expiry ))
echo
echo " https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/"
echo
echo URI : turn:$HOST:443
echo username : $username
echo password : $(echo -n $username | openssl dgst -binary -sha1 -hmac $SECRET | openssl base64)
echo
Guardamos los cambios y volvemos el archivo ejecutable:
chmod + prueba.sh
lo ejecutamos:
./prueba.sh
el resultado:
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
URI : turn:turn.voztovoice.org:443
username : 1667776448
password : wMV+2iWjEWqIsf67QvWut8qOzpo=
Accedemos a la URL indicada:
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
y rellenamos los campos como sigue:

Luego:

si aparece algo parecido:

Significa que el servidor STUN/TURN está funcionando correctamente.
Hemos terminado.