Instalación de FreeSWITCH como Servidor VoIP en Linux

FreeSWITCH es una plataforma de comunicaciones de código abierto extremadamente potente que soporta SIP, WebRTC, conferencias y telefonía avanzada. Esta guía cubre la instalación de FreeSWITCH en Linux, la configuración de SIP, planes de marcado, soporte WebRTC y alta disponibilidad para entornos de producción.

Requisitos Previos

  • Ubuntu 20.04/22.04 o Debian 11/12 (recomendado)
  • Mínimo 2 GB de RAM, 4 GB recomendado para producción
  • Acceso root o sudo
  • Puertos: 5060/UDP-TCP (SIP), 5080/UDP-TCP (SIP externo), 8021/TCP (ESL), 16384-32768/UDP (RTP)

Instalación de FreeSWITCH

FreeSWITCH ofrece paquetes oficiales para Debian/Ubuntu:

# Importar la clave GPG de FreeSWITCH
wget -O /usr/share/keyrings/freeswitch-archive-keyring.gpg \
  https://files.freeswitch.org/repo/deb/debian-release/freeswitch-archive-keyring.gpg

# Añadir el repositorio de FreeSWITCH (Debian 12)
echo "deb [signed-by=/usr/share/keyrings/freeswitch-archive-keyring.gpg] \
  https://files.freeswitch.org/repo/deb/debian-release/ bookworm main" \
  > /etc/apt/sources.list.d/freeswitch.list

# Actualizar e instalar FreeSWITCH
apt update
apt install -y freeswitch freeswitch-meta-all

# Verificar la instalación
freeswitch -version

Para compilar desde el código fuente en CentOS/Rocky:

# Instalar dependencias de compilación
dnf install -y git autoconf automake libtool gcc gcc-c++ make \
  openssl-devel pcre-devel libedit-devel sqlite-devel ldns-devel \
  libyuv-devel opus-devel libvpx-devel libjpeg-turbo-devel

# Clonar el repositorio de FreeSWITCH
git clone https://github.com/signalwire/freeswitch.git /usr/src/freeswitch
cd /usr/src/freeswitch
git checkout v1.10

# Compilar e instalar
./bootstrap.sh -j
./configure
make -j$(nproc)
make install
make sounds-install moh-install

Configuración Básica de SIP

Los archivos de configuración están en /etc/freeswitch/:

# Estructura principal de configuración
ls /etc/freeswitch/
# freeswitch.xml  dialplan/  directory/  sip_profiles/  autoload_configs/

# Editar el perfil SIP interno (extensiones locales)
nano /etc/freeswitch/sip_profiles/internal.xml

Configura las extensiones de usuario en el directorio:

# Crear un usuario SIP básico
cat << 'EOF' > /etc/freeswitch/directory/default/1001.xml
<include>
  <user id="1001">
    <params>
      <!-- Contraseña para registro SIP -->
      <param name="password" value="MiContraseña123"/>
      <param name="vm-password" value="1234"/>
    </params>
    <variables>
      <variable name="toll_allow" value="domestic,international,local"/>
      <variable name="accountcode" value="1001"/>
      <variable name="user_context" value="default"/>
      <variable name="effective_caller_id_name" value="Usuario 1001"/>
      <variable name="effective_caller_id_number" value="1001"/>
    </variables>
  </user>
</include>
EOF

Configuración del perfil SIP externo:

# Editar el perfil externo para troncales SIP
nano /etc/freeswitch/sip_profiles/external.xml
<!-- Añadir gateway para troncal SIP -->
<gateway name="mi_proveedor_sip">
  <param name="username" value="mi_usuario"/>
  <param name="password" value="mi_contraseña"/>
  <param name="proxy" value="sip.proveedor.com"/>
  <param name="register" value="true"/>
  <param name="caller-id-in-from" value="false"/>
</gateway>

Planes de Marcado

El dialplan controla cómo se enrutan las llamadas:

# Editar el plan de marcado predeterminado
nano /etc/freeswitch/dialplan/default.xml

Ejemplos de extensiones en el dialplan:

<!-- Extensión para llamadas entre usuarios internos -->
<extension name="Local_Extension">
  <condition field="destination_number" expression="^(10[01][0-9])$">
    <!-- Marcar al usuario interno -->
    <action application="bridge" data="user/$1@${domain_name}"/>
  </condition>
</extension>

<!-- Extensión para llamadas salientes por troncal -->
<extension name="Llamadas_Salientes">
  <condition field="destination_number" expression="^9(\d{9})$">
    <!-- Redirigir por la troncal del proveedor SIP -->
    <action application="bridge" data="sofia/gateway/mi_proveedor_sip/$1"/>
  </condition>
</extension>

<!-- IVR simple de bienvenida -->
<extension name="IVR_Bienvenida">
  <condition field="destination_number" expression="^5000$">
    <action application="answer"/>
    <action application="playback" data="/usr/share/freeswitch/sounds/es/bienvenida.wav"/>
    <action application="hangup"/>
  </condition>
</extension>

Soporte WebRTC

FreeSWITCH soporta WebRTC para llamadas desde el navegador:

# Instalar el módulo mod_verto para WebRTC
# Verificar que está habilitado en modules.conf.xml
grep -n "mod_verto" /etc/freeswitch/autoload_configs/modules.conf.xml

# Configurar Verto para WebRTC
nano /etc/freeswitch/autoload_configs/verto.conf.xml
<configuration name="verto.conf" description="Verto Endpoint">
  <settings>
    <!-- Puerto WebSocket para WebRTC (sin cifrado) -->
    <param name="bind-local" value="0.0.0.0:8081"/>
    <!-- Puerto WebSocket seguro (WSS) para producción -->
    <param name="bind-local" value="0.0.0.0:8082" secure="true"/>
  </settings>
  <profiles>
    <profile name="default-v4">
      <param name="bind-local" value="0.0.0.0:8081"/>
      <param name="force-register-domain" value="${domain}"/>
      <param name="secure-combined" value="/etc/freeswitch/tls/wss.pem"/>
    </profile>
  </profiles>
</configuration>
# Generar certificado TLS para WebRTC
/usr/share/freeswitch/scripts/gentls_cert.sh

# Aplicar la configuración en FreeSWITCH
fs_cli -x "reload mod_verto"

Conferencias y Salas de Audio

# Configurar salas de conferencia
nano /etc/freeswitch/autoload_configs/conference.conf.xml
<!-- Perfil de conferencia básico -->
<profile name="default">
  <param name="domain" value="$${domain}"/>
  <!-- Música en espera mientras no hay participantes -->
  <param name="moh-sound" value="$${hold_music}"/>
  <!-- Tono al entrar/salir de la conferencia -->
  <param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
  <param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
  <!-- Calidad de audio -->
  <param name="rate" value="48000"/>
  <param name="interval" value="20"/>
</profile>

Añadir sala de conferencia al dialplan:

<!-- Sala de conferencia en extensión 9001 -->
<extension name="Sala_Conferencia">
  <condition field="destination_number" expression="^9001$">
    <action application="answer"/>
    <action application="conference" data="sala_general@default"/>
  </condition>
</extension>

Scripting con Lua

FreeSWITCH integra Lua para lógica de negocio avanzada:

# Crear un script Lua para IVR dinámico
cat << 'EOF' > /usr/share/freeswitch/scripts/ivr_menu.lua
-- Script Lua para menú IVR interactivo
session:answer()
session:sleep(1000)

-- Reproducir mensaje de bienvenida
session:streamFile("/usr/share/freeswitch/sounds/es/bienvenida.wav")

-- Capturar la selección del usuario (máximo 1 dígito, timeout 5 segundos)
local digito = session:getDigits(1, "#", 5000)

if digito == "1" then
    -- Transferir al departamento de ventas
    session:transfer("1001", "XML", "default")
elseif digito == "2" then
    -- Transferir al soporte técnico
    session:transfer("1002", "XML", "default")
else
    -- Colgar si no hay selección válida
    session:hangup()
end
EOF

Llamar al script desde el dialplan:

<extension name="IVR_Lua">
  <condition field="destination_number" expression="^8000$">
    <action application="lua" data="ivr_menu.lua"/>
  </condition>
</extension>

Alta Disponibilidad

Para producción con alta disponibilidad usando dos nodos:

# Instalar y configurar Keepalived para IP flotante
apt install -y keepalived

cat << 'EOF' > /etc/keepalived/keepalived.conf
vrrp_instance VI_FREESWITCH {
    state MASTER          # BACKUP en el servidor secundario
    interface eth0
    virtual_router_id 51
    priority 100          # 90 en el servidor secundario
    authentication {
        auth_type PASS
        auth_pass freeswitch_ha
    }
    virtual_ipaddress {
        192.168.1.100/24  # IP virtual compartida
    }
    notify_master "/usr/local/bin/freeswitch_master.sh"
    notify_backup "/usr/local/bin/freeswitch_backup.sh"
}
EOF

systemctl enable keepalived
systemctl start keepalived

Solución de Problemas

# Conectar a la consola de FreeSWITCH
fs_cli

# Activar logging detallado en la consola
/log 7

# Monitorear registros SIP en tiempo real
fs_cli -x "sofia status"

# Verificar el estado de un gateway SIP
fs_cli -x "sofia status gateway mi_proveedor_sip"

# Ver llamadas activas
fs_cli -x "show calls"

# Verificar que los módulos necesarios están cargados
fs_cli -x "module_exists mod_sofia"

# Revisar los logs del sistema
journalctl -u freeswitch -f

# Capturar tráfico SIP para depuración
tcpdump -i eth0 -w /tmp/sip_capture.pcap port 5060

FreeSWITCH no inicia:

# Verificar permisos de archivos de configuración
chown -R freeswitch:freeswitch /etc/freeswitch /var/lib/freeswitch

# Iniciar en modo de depuración
freeswitch -nobackground -loglevel debug

Conclusión

FreeSWITCH es una solución VoIP de nivel empresarial que proporciona flexibilidad total para implementar desde centralitas telefónicas simples hasta plataformas de comunicación complejas con WebRTC y conferencias. La clave del éxito es una buena comprensión del dialplan XML y el uso de módulos especializados según las necesidades del proyecto. Con la configuración adecuada de TLS y alta disponibilidad, FreeSWITCH puede ser la base de un servicio de voz productivo y resiliente.