SSD Nodes Learn 🎉 VPS desde $5.50/mes
Guías Matt ConnorPor Matt Connor

Servidor VoIP autohospedado con Asterisk y FreePBX

Configura Asterisk o FreePBX en tu VPS con troncales SIP, puertos RTP y reglas de firewall para reducir escaneos y detectar el inicio del fraude telefónico.

Qué es un servidor VoIP autohospedado

Un servidor VoIP autohospedado es un servidor SIP que se ejecuta en un VPS bajo su control. Las llamadas se enrutan mediante su propio equipo en lugar de mediante un servicio telefónico alojado. VoIP (voz sobre IP) transporta el audio como paquetes UDP. SIP (protocolo de inicio de sesión) gestiona la señalización que establece y termina una llamada. El audio no se transmite mediante SIP. Este hecho causa la mayoría de los problemas que se describen a continuación.

Un sistema funcional tiene cuatro componentes.

  • El software PBX (centralita privada). Asterisk es la opción habitual. Contiene las extensiones y el dialplan.
  • Los endpoints. Son teléfonos de escritorio o softphones que se registran en el PBX con un nombre de usuario y un secreto.
  • El troncal SIP. Es una cuenta de pago con un proveedor que conecta su sistema a la red telefónica pública y alquila números de teléfono reales.
  • La ruta de medios. Los flujos RTP (protocolo de transporte en tiempo real) transportan el audio mediante sus propios puertos UDP.

Autohospedar el PBX no significa autohospedar los números de teléfono. Los números los proporciona un operador, y usted sigue pagando por cada número y por cada minuto. Lo que administra directamente es el enrutamiento de llamadas, el buzón de voz, las grabaciones y la lista de extensiones. También es responsable de la seguridad de un servicio que los atacantes intentan comprometer para obtener dinero.

¿Qué puertos necesita un servidor VoIP autohospedado?

La señalización SIP usa el puerto 5060 para UDP y TCP, y el puerto 5061 para SIP sobre TLS (seguridad de la capa de transporte). Esos puertos sólo transportan el establecimiento de las llamadas. El audio de cada llamada usa un flujo UDP independiente, enviado a un puerto tomado del rango RTP. Asterisk incluye un ejemplo de rtp.conf que establece rtpstart=10000 y rtpend=20000, y los valores predeterminados compilados son 5000 y 31000. Cada llamada usa dos puertos de ese rango: uno para RTP y otro para RTCP (protocolo de control RTP).

Esta separación es la causa de la mayoría de los primeros fallos. La llamada se conecta, ambos teléfonos muestran que está respondida y ninguna de las partes oye nada porque el firewall permite 5060 y descarta todos los paquetes RTP. La señalización y los medios son flujos independientes, por lo que necesitan reglas de firewall independientes. Si esta distinción es nueva para usted, conviene leer cómo funcionan los puertos y los sockets de escucha en Linux antes de abrir ningún puerto.

Reduzca el rango antes de abrirlo. Veinte mil puertos son muchos más de los que necesita un sistema pequeño. Como cada llamada usa dos puertos, un rango de doscientos permite mantener cien llamadas simultáneas.

[general]
rtpstart=10000
rtpend=10200

Aplíquelo con sudo asterisk -rx "core reload".

¿Debe instalar Asterisk o FreePBX?

Asterisk es el motor. Se configura mediante archivos de texto en /etc/asterisk y el plan de marcación se escribe manualmente. FreePBX es una interfaz web escrita en PHP y JavaScript que funciona sobre Asterisk, genera esos archivos y añade módulos para el buzón de voz y las colas de llamadas.

En un VPS, la diferencia importante es quién controla el equipo. En agosto de 2026, el instalador oficial de FreePBX 17 espera un sistema Debian 12 sin modificaciones e instala Asterisk, un servidor web, un servidor de base de datos y PHP. Si lo ejecuta en un equipo que ya aloja otros servicios, el resultado será problemático. Asigne a FreePBX su propio VPS.

wget https://github.com/FreePBX/sng_freepbx_debian_install/raw/master/sng_freepbx_debian_install.sh -O /tmp/sng_freepbx_debian_install.sh
sudo bash /tmp/sng_freepbx_debian_install.sh

El registro de instalación se guarda en /var/log/pbx/freepbx17-install.log. Es el primer lugar que debe revisar cuando el script se detiene antes de terminar.

FreePBX controla los archivos de configuración que genera. Si edita pjsip.conf manualmente en un equipo con FreePBX, el cambio desaparecerá la próxima vez que la interfaz web escriba ese archivo. FreePBX lee archivos independientes cuyo nombre contiene _custom para la configuración escrita manualmente, y no modifica esos archivos.

La disyuntiva real es esta. FreePBX proporciona una interfaz web y expone una página de inicio de sesión del sistema telefónico en Internet. Asterisk sin esa capa no tiene ninguna superficie web, y cada ajuste es una directiva documentada que puede leer en un archivo y conservar en git. Si instala FreePBX, restrinja su puerto web a su propia dirección o acceda mediante una VPN, porque una interfaz de administración para una PBX es un objetivo con acceso directo a recursos económicos.

Nota sobre las versiones, correcta en agosto de 2026: Asterisk 22 es la versión actual de soporte a largo plazo, publicada en octubre de 2024 y con actualizaciones de seguridad hasta octubre de 2028. Asterisk 23 es la versión estándar. Ubuntu 24.04 incluye Asterisk 20.6.0 en el repositorio universe.

Instalar Asterisk en Ubuntu 24.04

El paquete de la distribución es la opción más rápida. Ubuntu lo adapta y se inicia automáticamente con systemd.

sudo apt update
sudo apt install -y asterisk
sudo asterisk -rx "core show version"

Compilar desde el código fuente permite obtener en su lugar la versión actual con soporte a largo plazo.

sudo apt update
sudo apt install -y build-essential wget
cd /usr/local/src
sudo wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-22-current.tar.gz
sudo tar -xzf asterisk-22-current.tar.gz
cd asterisk-22.*
sudo contrib/scripts/install_prereq install
sudo ./configure
sudo make menuselect
sudo make -j"$(nproc)"
sudo make install
sudo make samples
sudo make config
sudo ldconfig

install_prereq install instala las dependencias de compilación para su distribución, y install_prereq test muestra los comandos que ejecutaría sin modificar nada. make menuselect abre el selector de módulos, donde se habilita codec_opus en Codec Translators. Ejecute make samples sólo en una instalación nueva, porque escribe la configuración de ejemplo en /etc/asterisk. make config instala el script de inicio en /etc/init.d/asterisk, y systemd lo ejecuta mediante su capa de compatibilidad con SysV, por lo que sudo systemctl enable --now asterisk funciona después.

Independientemente de la opción elegida, sudo asterisk -rvvv se conecta al daemon en ejecución y proporciona la CLI. Ejecutar core show version allí muestra lo que se instaló realmente.

Configurar un troncal SIP y una extensión

PJSIP es el controlador de canal SIP de Asterisk actual. Su configuración se encuentra en /etc/asterisk/pjsip.conf y se compone de secciones pequeñas y tipadas que se referencian entre sí por nombre. Las secciones de distintos tipos pueden compartir un nombre, por eso todos los bloques siguientes se llaman mytrunk.

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0

[mytrunk]
type=registration
outbound_auth=mytrunk
server_uri=sip:sip.example.com
client_uri=sip:1234567890@sip.example.com
retry_interval=60

[mytrunk]
type=auth
auth_type=userpass
username=1234567890
password=REPLACE_WITH_A_LONG_RANDOM_SECRET

[mytrunk]
type=aor
contact=sip:sip.example.com:5060

[mytrunk]
type=endpoint
context=from-trunk
disallow=all
allow=ulaw
outbound_auth=mytrunk
aors=mytrunk

[mytrunk]
type=identify
endpoint=mytrunk
match=sip.example.com

El objeto registration envía el REGISTER que indica al proveedor dónde debe entregar sus llamadas. El objeto identify permite asociar una llamada entrante del proveedor con este endpoint según la dirección de origen; normalmente, el proveedor publica varias direcciones que deben incluirse allí. El registro saliente y el endpoint son objetos independientes de forma intencionada: uno indica al proveedor dónde está usted y el otro determina qué ocurre con las llamadas.

Un teléfono de escritorio necesita tres objetos más.

[6001]
type=endpoint
context=internal
disallow=all
allow=ulaw
auth=auth6001
aors=6001
direct_media=no

[auth6001]
type=auth
auth_type=userpass
username=6001
password=REPLACE_WITH_A_LONG_RANDOM_SECRET

[6001]
type=aor
max_contacts=1

direct_media=no mantiene a Asterisk en la ruta de medios. Si se omite, Asterisk intentará que los dos endpoints envíen RTP directamente entre sí, lo que falla cuando el teléfono está detrás de NAT (traducción de direcciones de red) en un router doméstico. Nunca haga que el secreto coincida con el número de extensión. El ejemplo original usa password=6001 para la extensión 6001 para facilitar su lectura, y los escáneres prueban primero exactamente ese patrón.

El dialplan de /etc/asterisk/extensions.conf determina qué puede hacer cada contexto.

[internal]
exten => 6001,1,Dial(PJSIP/6001,20)
exten => _9X.,1,Dial(PJSIP/${EXTEN:1}@mytrunk,60)

[from-trunk]
exten => 1234567890,1,Dial(PJSIP/6001,20)
same => n,Hangup()

Esos dos contextos son un límite de seguridad. from-trunk gestiona las llamadas entrantes del proveedor y sólo puede hacer sonar la extensión 6001. No puede acceder al patrón _9X., por lo que una llamada externa no puede volver a marcar hacia fuera a través de su troncal. Si combina los contextos, habrá creado la ruta clásica para el fraude telefónico: un desconocido llama a su número, el dialplan realiza una llamada saliente con su cuenta y usted paga el coste.

Aplique la configuración y compruébela.

sudo asterisk -rx "pjsip reload"
sudo asterisk -rx "pjsip show registrations"
sudo asterisk -rx "pjsip show endpoints"

pjsip show registrations debería mostrar mytrunk con el estado Registered. Rejected significa que el proveedor rechazó sus credenciales. Unregistered significa que su REGISTER no recibe respuesta, así que revise el firewall a continuación.

Reglas del firewall para SIP y RTP

La señalización y los medios requieren un tratamiento diferente porque conllevan riesgos distintos. Restrinja 5060 a las direcciones que use realmente su proveedor y a las redes donde estén sus teléfonos.

sudo ufw allow proto udp from 203.0.113.10 to any port 5060
sudo ufw allow proto tcp from 203.0.113.10 to any port 5060
sudo ufw allow 10000:10200/udp
sudo ufw status verbose

El rango RTP es la parte que no puede restringir tanto, porque los medios suelen llegar desde una dirección diferente de la señalización. Solicite a su proveedor las subredes de medios y restrinja el acceso a ellas si las publica. Mantenga el rango tan reducido como lo requiera su hora de mayor actividad. Las políticas predeterminadas, el orden de las reglas y el resto del modelo de ufw se explican en la guía básica del firewall ufw para un VPS.

Compruebe también IPv6. Si IPV6=no está establecido en /etc/default/ufw, ufw no filtra IPv6, por lo que un daemon enlazado a :: será accesible mediante IPv6 sin aplicar ninguna de las reglas anteriores. Abrir puertos para IPv6 con ufw explica las diferencias entre ambas familias. La mayoría de los proveedores también ofrecen un firewall de red independiente en el panel de control. Ese firewall se aplica antes de que los paquetes lleguen al VPS, por lo que el puerto debe estar abierto en ambos lugares.

El ataque de fuerza bruta y el fraude de tarificación en SIP no son problemas opcionales

Si se expone el puerto 5060 en una dirección pública, empiezan los escaneos. El patrón es constante: solicitudes REGISTER e INVITE desde muchas direcciones de origen que prueban números de extensión habituales con secretos habituales. Asterisk registra cada fallo con este formato.

Request 'REGISTER' from '<sip:1000@198.51.100.20>' failed for '198.51.100.20:5060' (callid: 5f1a5c0d) - No matching endpoint found

La razón para dedicarle un esfuerzo real es económica. Una extensión robada se utiliza para realizar llamadas internacionales costosas, a menudo a números de tarificación especial que pagan una parte al atacante. La factura la paga usted porque las llamadas utilizan sus credenciales. El ataque funciona a la velocidad de una máquina y normalmente se ejecuta durante la noche.

Hay seis controles obligatorios, no medidas de endurecimiento opcionales.

  • Nunca cree una extensión cuyo secreto sea su propio número o una palabra corta. Genere uno con openssl rand -base64 24 y péguelo.
  • Mantenga desactivadas las llamadas entrantes anónimas. PJSIP rechaza las llamadas no identificadas de forma predeterminada y sólo las acepta si crea un endpoint llamado anonymous. No lo cree.
  • Mantenga separado el contexto del trunk de cualquier contexto que pueda realizar llamadas salientes, como se muestra arriba.
  • Restrinja la señalización por dirección de origen, tanto en ufw como en el firewall de red de su proveedor.
  • Establezca un límite de gasto con su proveedor de SIP trunk y desactive los destinos internacionales a los que nunca llama. Este es el único control que limita la pérdida cuando fallan los demás.
  • Ejecute fail2ban contra el registro de Asterisk.

Asterisk también puede generar un evento de seguridad después de recibir varias solicitudes no coincidentes desde una misma dirección. La sección [global] de pjsip.conf acepta unidentified_request_count, cuyo valor predeterminado es 5, y unidentified_request_period, cuyo valor predeterminado es 5 segundos. En conjunto, esto significa que cinco solicitudes no coincidentes desde una dirección dentro de un intervalo de cinco segundos generan un evento de seguridad que fail2ban puede utilizar.

Bloquee los escáneres con fail2ban

fail2ban incluye un jail asterisk ya preparado. Cubre los puertos 5060 y 5061, lee /var/log/asterisk/messages y usa maxretry = 10 de forma predeterminada. El jail permanece desactivado hasta que lo habilita en /etc/fail2ban/jail.local.

[asterisk]
enabled = true
maxretry = 5
findtime = 600
bantime = 86400
sudo systemctl restart fail2ban
sudo fail2ban-client status asterisk

Un resultado correcto muestra el archivo de registro del jail y el número de direcciones bloqueadas actualmente. En un puerto 5060 público, ese número deja de ser cero en menos de un día. El filtro incluido coincide con los avisos No matching endpoint found anteriores y también con las líneas SecurityEvent estructuradas de Asterisk. Esos eventos se envían a un canal de registro independiente que aparece comentado en /etc/asterisk/logger.conf. Actívelo allí y añada el archivo a logpath del jail si quiere incluirlos.

[logfiles]
console => notice,warning,error
messages.log => notice,warning,error
security.log => security

Recargue el registrador con sudo asterisk -rx "logger reload". El filtro también incluye un journalmatch para asterisk.service, por lo que puede usar un backend de journal si prefiere no conservar archivos de registro. La instalación, la estructura de jail.local y la eliminación del bloqueo de una dirección que haya bloqueado por error se explican en la guía de fail2ban para Ubuntu 24.04.

Latencia y elección del códec en un VPS distante

La distancia geográfica determina el retardo y no puede eliminarse mediante configuración. ITU-T G.114 recomienda mantener el retardo unidireccional por debajo de 150 ms para una conversación normal y considera que hasta unos 400 ms sigue siendo utilizable. El audio del teléfono llega al VPS y después sale hacia el proveedor de troncales, por lo que un VPS situado en la región incorrecta recorre esa distancia dos veces. Sitúelo cerca de los teléfonos o del proveedor. Si ambas opciones entran en conflicto, prefiera situarlo cerca de los teléfonos, porque ese tramo suele usar Internet de consumo, donde la fluctuación del retardo suele ser mayor.

La elección del códec determina el ancho de banda de cada llamada. Todos los códecs de esta sección envían un paquete cada 20 ms, es decir, 50 paquetes por segundo. Cada paquete incluye 40 bytes de cabeceras IP, UDP y RTP además de la carga de audio.

ChartBandwidth per concurrent call, one direction, 20 ms packets
The data behind this chart
[
  {
    "label": "G.711 ulaw",
    "payload_kbps": 64,
    "ip_kbps": 80
  },
  {
    "label": "G.722",
    "payload_kbps": 64,
    "ip_kbps": 80
  },
  {
    "label": "Opus at 24 kbps",
    "payload_kbps": 24,
    "ip_kbps": 40
  },
  {
    "label": "G.729",
    "payload_kbps": 8,
    "ip_kbps": 24
  }
]

G.711 ulaw es el valor predeterminado en la mayoría de las troncales. Su carga útil es de 64 kbps y, con las cabeceras, una llamada activa consume 80 kbps en cada dirección. Opus a 24 kbps requiere 40 kbps, mientras que G.729 reduce el consumo a 24 kbps, a cambio de calidad de audio y tiempo de CPU. Estas cifras son cálculos de cabeceras, no mediciones: tasa de carga útil más 40 bytes por paquete a 50 paquetes por segundo. El encapsulado de Ethernet o VLAN añade un poco más de tráfico en el cable.

La transcodificación consume CPU. Si los teléfonos y la troncal usan ulaw, permita sólo ulaw y Asterisk pasará el audio sin modificarlo. Opus funciona bien en enlaces con pérdidas, pero la transcodificación entre Opus y G.711 requiere el módulo externo codec_opus. Debe seleccionarlo en make menuselect y no se compila de forma predeterminada.

Qué falla y qué texto verá

La llamada conecta, pero nadie oye nada. No llegan paquetes RTP. Confirme que el rango de rtp.conf coincide con el rango que abrió en el firewall y, mientras realiza una llamada, supervise los paquetes con sudo tcpdump -ni any udp portrange 10000-10200. Si no llega ningún paquete, el firewall o el firewall de red de su proveedor los está descartando.

El audio funciona en una sola dirección. Un extremo está enviando RTP a una dirección que no puede recibirlo. Es un problema de direcciones, no de puertos. Si su VPS tiene la dirección pública directamente en su interfaz, no necesita configurar NAT. Si el proveedor asigna al VPS una dirección privada con una asignación pública uno a uno, establezca la dirección pública en el transporte e indique el rango privado en local_net.

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
local_net=10.0.0.0/8
external_media_address=198.51.100.5
external_signaling_address=198.51.100.5

No matching endpoint found en el registro. La solicitud no coincidió con ningún endpoint por dirección IP ni por nombre de usuario. Esto es normal cuando procede de un escáner, y fail2ban lo gestionará. Si procede de su propio proveedor, significa que la sección identify no incluye la dirección desde la que le llaman.

El estado del registro es Rejected. El proveedor rechazó las credenciales de la sección auth. Ejecute pjsip set logger on en la CLI, supervise un REGISTER y su respuesta, y compare client_uri y username con los valores que le proporcionó el proveedor.

No aparece nada útil en el registro. Asterisk escribe de forma predeterminada los mensajes de nivel notice y superiores en messages.log. Aumente el nivel con core set verbose 4 y pjsip set logger on mientras reproduce el problema. Después, desactive ambas opciones, porque el registrador SIP escribe cada paquete.

Antes de exponerlo

Una PBX no es igual que los demás servicios que aloja usted mismo. Una aplicación web averiada deja una página fuera de servicio. Una PBX averiada puede generar una factura telefónica en cuestión de horas mientras usted duerme. Ejecútela en un VPS dedicado, restrinja 5060 a direcciones conocidas, asigne un secreto aleatorio a cada extensión y establezca un límite de gasto en la cuenta del trunk. El resto del servidor necesita la misma configuración de referencia que cualquier servidor expuesto, descrita en esta revisión de la seguridad real del alojamiento VPS.

FAQ

¿Qué puertos debo abrir para un servidor VoIP autohospedado?

El puerto 5060 para la señalización SIP mediante UDP y TCP, el puerto 5061 si usa SIP mediante TLS y un rango de puertos UDP para los medios RTP. El archivo de ejemplo rtp.conf de Asterisk usa del 10000 al 20000, y los valores predeterminados compilados son del 5000 al 31000. Cada llamada consume dos puertos del rango, por lo que un rango de doscientos puertos admite cien llamadas simultáneas. Abra el rango RTP como UDP y restrinja 5060 a las direcciones de su proveedor y a sus propias redes, en lugar de dejarlo abierto a todos.

¿Debo instalar Asterisk por separado o usar FreePBX?

Instale Asterisk sin una capa adicional cuando quiera una superficie de ataque reducida, archivos de configuración que pueda conservar en git y esté dispuesto a escribir el dialplan. Instale FreePBX cuando quiera una GUI para extensiones, buzón de voz y colas de llamadas. En agosto de 2026, el instalador de FreePBX 17 espera una máquina Debian 12 sin modificaciones e instala Asterisk, un servidor web, un servidor de base de datos y PHP, por lo que debe asignarle un VPS propio. FreePBX vuelve a generar los archivos de configuración que administra, por lo que las modificaciones manuales deben hacerse en sus archivos _custom.

¿Por qué no hay audio después de conectar la llamada?

La señalización funcionó, pero los medios no. SIP estableció la llamada en el puerto 5060 y el audio usa un flujo UDP independiente hacia un puerto del rango RTP que algún componente está descartando. Compruebe que el rango de rtp.conf coincida con el rango abierto en el firewall y revise tanto el firewall de red de su proveedor como el del servidor. Ejecute sudo tcpdump -ni any udp portrange 10000-10200 durante una llamada: si no hay paquetes, están bloqueados antes de llegar.

¿Cómo detengo los ataques de fuerza bruta contra SIP y el fraude de tarificación?

Asigne a cada extensión un secreto largo y aleatorio. No use uno que coincida con el número de la extensión. Mantenga separado el context usado por su trunk de cualquier context que pueda realizar llamadas salientes, para que una llamada entrante no pueda volver a salir usando su cuenta. Restrinja el puerto 5060 a las direcciones de su proveedor. Habilite el jail asterisk en fail2ban, que lee /var/log/asterisk/messages y bloquea las direcciones que producen No matching endpoint found fallos. Después, establezca un límite de gasto y bloquee los destinos internacionales no utilizados con su proveedor, porque ese es el único control que limita la pérdida si todo lo demás falla.

¿Un VPS en una región distante perjudica la calidad de las llamadas?

Sí, porque el audio recorre dos tramos: del teléfono al VPS y del VPS al proveedor del trunk. ITU-T G.114 recomienda una latencia unidireccional inferior a 150 ms, y un VPS mal ubicado puede consumir la mayor parte de ese margen sólo por la distancia. Elija una región cercana a los teléfonos, porque ese tramo suele utilizar Internet de consumo, donde la fluctuación es mayor. La elección del códec no corrige la latencia; sólo cambia el ancho de banda. Por tanto, G.729 ahorra bytes, pero no resolverá una ruta de 200 ms.

#voip#asterisk#freepbx#sip#self-hosting