Curso Asterisk (VI): Lidiando con el NAT

El enemigo público número uno del protocolo SIP son las tablas NAT. El NAT es la principal causa de problemas a la hora de montar nuestro servidor Asterisk. Desafortunadamente para nosotros, debido a la falta de IPs públicas de IPv4, lo normal en nuestros hogares es que estemos detrás de un NAT. Por lo tanto, si queremos montar nuestro Asterisk dentro de casa, tendremos que pelearnos con él.

Si haciendo pruebas se obtienen alguno de estos resultados, casi seguro que estemos experimentando problemas derivados de estar dentro de una red privada con NAT:

  • Audio sólo en un sentido
  • Ausencia total de audio en ambos sentidos
  • No puedes recibir llamadas
  • Las llamadas se cortan transcurridos 10-30 segundos desde el establecimiento

 Los escenarios posibles son los siguientes:

  • El servidor está detrás de un NAT
  • Sólo un extremo está detrás de un NAT
  • Ambos extremos están detrás de un NAT
  • Ambos extremos y el servidor están detrás de un NAT

El escenario más complicado es el último, donde uno de los extremos de la conversación está detrás de un NAT, el otro extremo está detrás de otro NAT diferente, y el servidor está detrás de un tercer NAT.

Las soluciones que se encuentran por Internet en ocasiones resultan confusas, incorrectas o incompletas. Personalmente me ha costado mucho tiempo y esfuerzo dar con la solución definitiva. Afortunadamente para vosotros, una vez que tienes el conocimiento no es tan complicado aplicarlo. Lo vamos a ver en dos apartados: solucionar los problemas de los extremos, y solucionar los problemas del servidor.

Extremos detrás de un NAT

Deberemos añadir las siguientes dos líneas en la sección [general] de la configuración SIP de nuestro Asterisk:

[general]
nat=force_rport,comedia
directmedia=no

;resto de configuración general

Y punto. No tiene más misterio.

Servidor detrás de un NAT

Tenemos que hacer dos cosas. Por un lado, debemos abrir en el router los puertos necesarios hacia la IP de nuestro servidor Asterisk.

Para ello, debemos consultar el contenido de «/etc/asterisk.rtp.conf» y fijarnos en los valores de los parámetros «rtpstart» y «rtpend». Por ejemplo:

[general]
; Ejemplo de configuración de RTP
rtpstart=10000
rtpend=20000

Según el ejemplo, debemos abrir en nuestro router el rango de puertos 10000-20000/UDP, además del 5060/UDP correspondiente al protocolo SIP. Consulta el manual de tu router para saber cómo abrir puertos hacia la IP de tu servidor Asterisk.

Por otro lado, necesitaremos un servicio de DNS dinámico del tipo No-IP o FreeDNS. Si no sabes cómo hacerlo, en Internet hay numerosas guías que lo explican muy bien.

Vamos a suponer que tenemos un dominio «ejemplo.no-ip.org» correctamente configurado, y que el rango privado de IPs de nuestra red es del tipo «192.168.0.x».  Deberemos añadir las siguientes líneas en la sección [general] de la configuración SIP de nuestro Asterisk:

[general]
externhost=ejemplo.no-ip.org
externrefresh=600
localnet=192.168.0.0/255.255.255.0

;resto de configuración general

Gracias a esta configuración, nuestro servidor Asterisk sabe cuándo las peticiones surgen desde dentro de la propia red privada del servidor, y cuándo provienen del exterior. En este último caso, en lugar de encapsular la IP privada del servidor en los paquetes SIP, utiliza la IP pública a la que apunta el dominio especificado. De esta manera, el extremo obtiene la IP de contacto correcta y puede responder correctamente al servidor.

Ejemplo completo

Supongamos lo siguiente:

  • Queremos poder contactar con extremos que estén detrás de un NAT
  • Nuestro servidor Asterisk está detrás de un NAT
  • El rango de IPs privadas de nuestro servidor Asterisk es de la forma 192.168.0.x
  • Tenemos un dominio DNS dinámico «ejemplo.no-ip.org» correctamente configurado con la IP pública de nuestro Asterisk

Para cumplir con estos objetivos, deberíamos añadir las siguientes líneas a la sección «general» de nuestra configuración SIP:

[general]
;NAT
externhost=ejemplo.no-ip.org
externrefresh=600
localnet=192.168.0.0/255.255.255.0
nat=force_rport,comedia

;resto de configuración general

Consideraciones adicionales

  • Si los clientes disponen de ellas, conviene activar las opciones STUN e ICE.

Índice del Curso Asterisk:

20 comentarios en “Curso Asterisk (VI): Lidiando con el NAT

  1. Parece que me has leído el pensamiento al escribir esta entrada XD.
    Quería comentarte un problemilla de «one way audio» que se me presentó ayer a ver si podrías indicarme por donde van los tiros. Te intento explicar primero como es el esquema de red que tengo montado para ponernos en situación:

    – Red local con servidor asterisk y conexión directa a Internet a través de un router ADSL. No se permite el registro de clientes desde fuera de la red, con lo que solo se pueden hacer llamadas entre extensiones internas y llamadas salientes a través de operadores VoIP.

    Bien, configuro en asterisk un peer con el operador adamvozip (uno que tengo hace años), llamo a un fijo y hablo sin problemas. Oigo y me oyen.

    Configuro en asterisk un peer con freevoipdeal, llamo a un fijo y oigo a la persona, pero el del fijo no me oye a mi (WTF!). Intento hacer lo mismo con una cuenta de voipbuster y obtengo el mismo resultado. No me oyen.

    Hay cosas que no me cuadran. Primero, por que con un operador no tengo problemas de audio y con otro si, si estoy en la misma red local, con la misma conexión a Internet e incluso configurado en la misma extensión interna. Segundo, como es posible que el problema de audio sea desde dentro hacia fuera de la red local y no a la inversa que sería casi lo mas lógico. Tengo que decir que para ninguno de los 3 operadores tenía configurado el nat=force_rport,comedia, pero vuelvo a repetir que con el operador adamvozip si me funcionó.

    Te pego a continuación la configuración general y del peer.

    [general]
    udpbindaddr=0.0.0.0:5060
    context=default
    srvlookup=yes
    allowguest=no
    alwaysauthreject=yes
    register => xxxx@voipbuster

    [voipbuster]
    type=peer
    host=sip1.voipbuster.com
    username=xxxx
    fromuser=xxxx
    secret=yyyy
    fromdomain=sip1.voipbuster.com
    disallow=all
    allow=alaw
    canreinvite=no
    insecure=port,invite
    dtmfmode=rfc2833

    —————
    Saludos.

  2. Hola Joaquín,

    Es una cosa extraña que sea el otro extremo el que no te oiga a ti. En cualquier caso, si sigues los pasos de esta entrada debería funcionarte bien. La configuración que has puesto del proveedor la veo correcta, así que debe ser un problema del NAT sí o sí. Asegúrate de lo siguiente:

    1) Tener correctamente abierto el puerto 5060 y el rango 10000-20000 en tu router hacia la IP interna de tu Asterisk. El rango 10000-20000 se utiliza para el transporte de los streams de audio por RTP, y el 5060 es el de SIP. Todos ellos son UDP.

    2) Añadir la línea «nat=force_rport,comedia» en la sección «[general]» de tu sip.conf

    3) Configurar un dominio dinámico del tipo No-Ip, y añadir las líneas externhost, externrefresh y localnet a tu sip.conf según tu configuración de red

    4) Reiniciar completamente tu Asterisk después de hacer los cambios del paso 3

    Un saludo.

  3. Bueno, he estado haciendo pruebas estos días y esto se ha convertido en un expediente X. Te cuento:

    Todas las pruebas que expuse en mi comentario anterior las he estado haciendo llamando a mi fijo que es de la compañía Jazztel (no es línea VoIP, es analógica). Bien, usando Voipbuster como proveedor para llamar se dan todas estas condiciones sin modificar la configuración anterior:

    – Si llamo a mi fijo de Jazztel solo obtengo audio del lado de voipbuster
    – Si llamo a un móvil obtengo audio en los dos sentidos (WTF?)
    – Si llamo a un fijo de Telefónica obtengo audio en los dos sentidos (WTF?¿?¿?¿?)

    ¿Puede ser que Jazztel tenga alguna incompatibilidad con el codec alaw que usa voipbuster? Porque como comenté anteriormente, con el proveedor VoIP adamvozip no tuve problema de audio con el fijo de Jazztel. La verdad es que no se me ocurre otra cosa, esto es un misterio….

  4. Mi hermano Lo felicito por tan excelentes Posts me he leido todos las publicaciones que tienes de Asterisk y ha sido el lugar donde he encontrado todo lo mejor explicado posible….

    He puesto en practica todos tus consejos y y me han funcionado… sin embargo
    tengo un inconveniente.
    Te escribo desde Colombia y como muchas compañías en el mundo aca hay una que ofrece un servicio de cuenta SIP al adquirir los servicios lo cual es muy ventajoso debido a que uno puede configurar esa cuenta con su celular o en cualquier parte y poder recibir llamadas en cualquier parte del mundo.

    Hemos querido configurar esta cuenta que nos da la compañía en un Asterisk, para poder optimizar los recursos. He instalado una maquina virtual con centos 6.5 y asterisk 1.8.26, He podido registrar la cuenta sip (de una manera particular), creado las extenciones y creado un dial plan sencillo pero a la hora de hacer una llamada no me sale, se queda mudo. Leyendo este post configuré el NAT puesto que estoy trabajando dentro de mi pc con Vbox tanto el servidor como el cliente (en windows). usando Zoiper como softphone.

    Esta compañia entrega un softphone con el que funciona a las mil maravillas pero por el asterisk no he podido.

  5. Gracias por tus comentarios, Emmanuel.

    Comentas que has podido registrar tu cuenta SIP en Asterisk de una manera muy particular. ¿Es posible que tu proveedor esté estableciendo limitaciones para el uso de centralitas de tipo Asterisk? ¿Qué proveedor utilizas? Si puedes, pega aquí tu configuración de sip.conf eliminando usernames y passwords.

    Un saludo.

  6. Se me ha olvidado incluir la directiva «directmedia=no» en la configuración de NAT para extremos. Sin esa directiva, Asterisk intentará renegociar los streams RTP de audio para que los extremos se comuniquen directamente. Esto en general es una buena idea, ya que evitamos que el audio pase por Asterisk, reduciendo el uso de ancho de banda del servidor y la latencia de la comunicación. Sin embargo, causa problemas cuando alguno de los extremos está detrás de un NAT.

    Añadid «directmedia=no» en la sección [general] y probad de nuevo.

  7. Axel una duda…. a ver porque puede pasar.

    Caso: Terminal movil que accede por 3G a traves de NAT al servidor.

    Si la llamada la hago desde el movil hacia un telefono dentro de la red del servidor, sin problemas.

    Pero si la llamada la hago desde un telefono local hasta el movil, la llamada entra en el movil, y se establece, pero no se escucha nada en ambos sentidos. Me fijo en el cliente del terminal local que es un Zoiper en WINDOWS y lo que se ve es que no negocia el CODEC. He probado con otros clientes y ocurre lo mismo.

    Debe de ser algo de NAT pero a saber. Se te ocurre algo?

  8. Puede ser que en la configuracion de extension del usuario, haya que definir de alguna manera que es un usuario que no en la red local?

    Saludos!

  9. El uso de SIP desde 3G suele dar problemas porque, en las tarifas de datos para móviles, los proveedores suelen meter a los clientes detrás de otro NAT. Esto tiene su sentido, ya que evita que un atacante sea capaz de consumirte tu bono mensual de datos enviándote paquetes, pero tiene el inconveniente de que complica determinados usos. Por ejemplo, PepePhone ofrece dos APNs diferentes, uno con NAT (recomendado para móviles), y otro con IP pública (recomendado sólo para pinchos 3G).

    En tu caso, mira a ver si el cliente de VoIP que utilizas en el móvil soporta las características STUN e ICE, y si es así, actívalas. Pon también «directmedia=no» en la sección «[general]» de sip.conf, y comprueba que las listas de codecs en tu softphone, en Asterisk y en tus proveedores tengan al menos un codec en común. Si no, no podrá negociar el audio.

    Un saludo.

  10. Pedazo de respuesta Axel. ya probare. Saludos y me encantaria leerte articulos tecnicos de otros temas, que seguro tienes ahi guardado.

  11. Axel muchas gracias por tu documento. Me ha sido clave para hacer todo lo que quería con Asterisk.
    Solo tengo una cosa pendiente que es la identificación de llamadas entrantes con Movistar FTTH. la verdad que no es un problema de Asterisk pues tampoco funciona con un cliente SIP conectado directamente. y sí que funciona en el teléfono analógico conectado directamente a la ONT.
    no sé si se os ocurre algo.

  12. Muchas gracias por la explicacion! pude solucionar un problema de NAT que impedia que cuando ingresara la llamada tuviera audio.

    Generalmente las configuraciones que he realizado siempre he utilizado los parametros de externip y localnet y funcionaba de forma correcta, apra este caso puntual no me funcionaba y realice la configuracion con los paramteros:

    nat=force_rport,comedia
    directmedia=no

    Funciono de maravilla, mil gracias por el aporte.

  13. He seguido tu manual paso a paso.
    Las llamadas entre extensiones funcionan muy bien, tanto por wifi como por 3G.

    Lo único que no consigo realizar es sacar las llamadas por mi proveedor. Este no tiene user ni password para autentificar.

  14. Sólo puedes poner la IP del servidor si es estática. En ese caso, utilizarías el parámetro «externip» y te ahorrarías bastantes complicaciones. Además, es el escenario ideal para servidores en producción.

    Si la IP es dinámica, entonces vas a necesitar obligatoriamente un dominio y algún mecanismo de actualización de la IP sobre el mismo (tipo No-IP o FreeDNS). En ese caso utilizarías los parámetros «externhost» y «externrefresh».

    Un saludo.

  15. buenos dias gracias amigo por tu ayuda …ya logre conectar un cliente sip desde una red diferente , ahora el problema es que cuando descuelgo el softphone no me escuchan ni los logro escuchar. ¿ a que crees que se deba ? algun codec de audio o algun puerto?

  16. Buen dia, muy buenas tus explicaciones.

    Mi problema es el siguiente, te escribo desde México, tengo el PBX central en las oficinas del cliente con IP fija, conecto una extensión remota a través de un ADSL, y al llamar no tengo audio en ambos sentidos, incluso si marco *97 o *65 para corroborar que tengo audio, no tengo ningun audio y en el log veo lo siguiente:

    [2015-08-11 18:33:26] VERBOSE[24414] loader.c: — Reloading module ‘res_rtp_asterisk.so’ (Asterisk RTP Stack)
    [2015-08-11 18:33:28] VERBOSE[2227][C-00000036] netsock2.c: == Using SIP RTP TOS bits 184
    [2015-08-11 18:33:28] VERBOSE[2227][C-00000036] netsock2.c: == Using SIP RTP CoS mark 5

    De antemano gracias y saludos…

  17. saludos necesito ayuda urgente tengo 2 suredes 192.168.1.0/24 172.17.0.0/24 y necesito que con el software brial profesional se puedan ver el video o escuchar, desde la subred 172 me puedo registrar bien y me conecto a traves de un firewall al elastix pero cuando hago una llamada desde la red 172 a cualquier extension que esta en al 192 automaticamente la llamada se establece pero cuando le doy star video no se escucha nada ni se establece comunicacion de audio y video, por favor ayudar urgente para establecer audio y video entre las 2 subredes la velocidad de conexion es a 256 kb. Saludos ayuda urgente por favor..

  18. Buenas tardes, tengo una centra elastix en una raspberry pi y tengo un problema con el ivr. Cuando llamo desde afuera a la central cae la llamada pero se queda muda no escucho el audio del ivr. ¿como puedo solucionar esto?

  19. Amigo, te cuento que tengo un red 192.168.0.x/24 con una central Elastix 192.168.1.9 y todo trabaja sin novedad. Hace dos semanas hicimos una vpn con una de nuestras filiales colocando un router en nuestra red con la ip 192.168.1.11 y del otro lado otro router con la ip 192.168.10.1, colocamos y configuramos los teléfonos con las IP’s del rango 192.168.10.x, pero estos lastimosamente solo pueden hacer llamadas y no recibirlas, cuando se intenta llamar a la extensión nos da un cógo de error 701, por favor si tienes alguna idea acerca de esto te lo agradecería.
    Muchas gracias.
    Slds

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *