Modelo de seguridad en Asterisk (parte 3 de 3)

8 Mar

Fuente: http://static.internetblog.org.uk/files/manjail.jpg


Llegamos al final de nuestras entregas discutiendo el modelo de seguridad de Asterisk. En la primera parte discutimos sobre la seguridad antes de llegar al conmutador, normalmente a cargo del firewall de nuestro acceso a internet. En la segunda partehablamos sobre como autenticar a los usuarios para permitirles acceder a nuestro sistema. En esta tercera entrega hablaremos sobre como limitar las características de los usuarios que ya se encuentran autenticados dentro de Asterisk.

Seguridad de operación

Existen errores en versiones anteriores de algunas interfases gráficas (léase: Elastix) que nos permitían leer la lista completa de extensiones del conmutador y sus contraseñas aún si el usuario no pasaba la autenticación de administrador. Esto quiere decir que a pesar de cerrar nuestra interfaz administrativa y que nadie pueda modificarla, al tener los usuario/contraseñas podría tomar un teléfono, registrarlo con estos datos y empezar a hacer llamadas. Peor aún: podría vender estos datos para que algún tercero haga llamadas ilegalmente desde nuestro equipo. Asumiendo que ya cometimos los errores de las otras 2 etapas, ¿cómo podemos evitar (o al menos reducir) el daño inminente?

El primer paso, es limitar los accesos de las extensiones de acuerdo a lo que deban hacer. Por ejemplo, es probable que la recepcionista necesite poder llamara a locales, LD y celulares. Sin embargo, ¿por qué la extensión que está en la cafetería tendría la necesidad de marcar hacia afuera? Limitar esto es muy sencillo haciendo uso de contextos:

[codesyntax lang=”bash” title=”extensions.conf”]

[internas]
exten => _XXXX,1,Dial(SIP/${EXTEN})

[locales]
include => internas
exten => _ZXXXXXXX,1,Dial(DAHDI/g0/${EXTEN})

[largadistancia]
include => locales
exten => _01NXXXXXXXXX,1,Dial(DAHDI/g0/${EXTEN})

[/codesyntax]

En este ejemplo, tenemos 3 contextos: [internas], [locales] y [largadistancia]. Cada uno incluye al anterior y además, agrega un grado más de permisos. La idea es que al configurar cada usuario SIP/IAX de nuestro sistema, limitemos los accesos que cada uno tenga, sabiendo que cada uno solo puede marcar estrictamente a lo que nosotros le permitimos, además de tener la facilidad de que al conceder un permiso superior, daremos acceso a lo anterior.

Es altamente recomendable que si no hacemos llamadas internacionales, entonces… ¡no las habilitemos! Si sabemos que nuestros negocios se centran en territorio nacional y quizá llamadas a EUA/Canadá, limitemos agregando el _001NXXXXXXXXX, pero no agreguemos algo tan general como permitir _00., que estaríamos dándole la oportunidad al atacante de que use el mundo entero. Recuerden que limitar las posibilidades improbables reduce el probable riesgo.

Una manera mucho más elegante sería hacer uso de Realtime para que al marcar, se consulte la BD para determinar si tenemos permisos de marcar a ese destino o no, y en base a eso reaccionar. Dado que Realtime es un poco más avanzado, lo veremos más adelante en otro artículo.

El segundo paso consistiría en poner limitantes no al teléfono sino a la persona. La manera de hacer esto sería obligar a quien marca a proporcionarnos un código que le autorice a marcar a ese destino. Si alguien puede marcar por nuestro sistema, al menos obliguemoslo a que se sepa las contraseñas de los usuarios. Usando el mismo ejemplo anterior, lo podríamos hacer así:

[codesyntax lang=”php” title=”extensions.conf”]

[internas]
exten => _XXXX,1,Dial(SIP/${EXTEN})

[locales]
include => internas
exten => _ZXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN})

[largadistancia]
include => locales
exten => _01NXXXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN})

[macro-salida]
exten => s,1,Authenticate(/etc/asterisk/pinset)
exten => s,n,Dial(${ARG1} )
exten => s,n,Hangup

[/codesyntax]

En el ejemplo de arriba estamos introduciendo un nuevo elemento, un macro que nos permitirá hacer 2 pasos en uno solo: la autenticación y luego la marcación. De acuerdo al ejemplo, cualquiera podria marcar extensiones locales sin restriccion (al final de cuentas, son gratis). Sin embargo, si trata de marcar a llamadas locales o larga distancia se le pedirá al usuario que ingrese un código (el cual estaría escrito dentro del archivo /etc/asterisk/pinset). Si el usuario no proporciona la contraseña correcta, la llamada termina.

Los 2 esquemas que hemos mencionado (contextos y contraseñas) deberían impedir que algo malo pase. Sin embargo, si en el peor de los casos alguien logra penetrar todo lo anterior, limitemos la cantidad de daño recibido. ¿Cómo? Limitando la cantidad de llamadas simultáneas que puede hacer. Este paso es sumamente importante ya que, para empezar, nadie tiene por que poder hacer 20 llamadas simultáneas, ¿o si?

Para hacer esto, reaprovechemos el ejemplo anterior:

[codesyntax lang=”php” title=”extensions.conf”]

[internas]
exten => _XXXX,1,Dial(SIP/${EXTEN})

[locales]
include => internas
exten => _ZXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN},2)

[largadistancia]
include => locales
exten => _01NXXXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN},1)

[macro-salida]
exten => s,1,GotoIf($[${GROUP_COUNT(${CALLERID(num)})}>=${ARG2}]?Permite)
exten => s,n,Congestion()
exten => s,n(Permite),Set(GROUP(${CDR(uniqueid)})=${CALLERID(num)})
exten => s,n,Authenticate(/etc/asterisk/pinset)

exten => s,n,Dial(${ARG1} )
exten => s,n,Hangup

[/codesyntax]

Notarán que el macro se ha hecho bastante más complejo. Hay una buena razón para esto:

Hemos agregado al Macro la posibilidad de determinar cuantas llamadas simultáneas activas tiene un usuario en un momento dado, y si se excede de esta cantidad, corta la llamada.

Observen esta línea:

[codesyntax lang=”php”]

exten => _ZXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN},2)

[/codesyntax]

El 2 que está al final de la línea es la cantidad máxima de llamadas a ese tipo de destino que estamos permitiendo. En el ejemplo anterior, permitimos que alguien marque hasta 2 llamadas locales al mismo tiempo, pero solo puede marcar a una LD. No sería muy difícil seguir este patrón para limitar el acceso internacional, pero eso se los dejo a ustedes para que practiquen.

 

Conclusiones

Si sumamos todas las barreras que hemos puesto con estos 3 niveles de seguridad, al final obtenemos:

  • Cerrar el acceso por firewall externo a nuestro conmutador
  • Detener el acceso al conmutador por firewall interno (iptables)
  • Acortar el rango de IPs desde las que pueden registrarse los usuarios SIP/IAX
  • Bloquear a aquellos usuarios que intenten fuerza bruta contra nosotros
  • Activar solo el plan de llamadas  necesario
  • Restringir  al usuario dependiendo de si sabe la contraseña correcta para el destino o no
  • Reducir la cantidad de llamadas simultáneas que el usuario puede hacer

Lo mejor de estas reglas es que son acumulables. Mientras más de ellas usemos lograremos un conmutador más y más seguro. Inclusive si consideramos que llevar a cabo todas resulta difícil, aplicar tantas como se pueda nos garantizará que estaremos restringiendo la posibilidad de que algo salga mal.

Créanme: vale más invertir tiempo en tomar en cuenta estos pasos en lugar de tener que pagar la cuenta final.

¡Suerte!

Christian Cabrera

Soy un ingenieron en comunicaciones con especial interés en el área de voz sobre IP y tecnologías sobre información. He usado Asterisk de manera diaria desde hace más de 12 años.En el 2011 co-fundé Enlaza Comunicaciones, una empresa que se especializa en brindar servicios profesionales de consultoría sobre voz sobre IP basadas en Asterisk.

  • Adriana

    portsentry ayuda a evitar el barrido de puertos… primer punto de ataque

  • Kato Katarsis

    Muy intersante articulo. Justo lo que estaba buscando. Y aqui viene mi consulta a quien pueda darme una mano en como resolverla de la mejor manera.
    Estoy migrando a un nuevo asterisk (Elastix) en un datacenter y quiero hacer las cosas bien… estoy pasando de un asterisk que estaba levantado en forma simple con un cablemodem de IP fija, pero que estaba abierto al exterior ya que hay telefonos IP remotos y tambien moviles.
    Ahora el problema que siempre tuve sin mucha importancia hasta el momento eran los ataques de fuerza bruta con testeo de passwords para Registrarse con SIP.
    Dado que necesito tener clientes SIP conectados en forma externa y que estos tienen IP dinamica y no tienen la posibilidad de hacer VPN, se me ocurre que la mejor configuración seria ademas de pasar por firewall:

    1- Levantar el servicio SIP en otro puerto que no sea 5060, un puerto alto.
    2- Utilizar contraseñas lo mas seguras posibles
    3- Utilizar fail2ban para frenar los brute force attacks. (conocen si puedo hacer algo parecido sobre pfSense?)

    Creo que no puedo utilizar en este caso:

    – ACLs (por ser clientes con IPs dinamicas)
    – Cerrar el port 5060 (ya que los clientes SIP son externos)

    Muchas gracias de antemano por su colaboracion y muy bueno el informe!

    Saludos
    Juan Pablo

    • Juan Pablo,

      Todos los puntos que sugieres son buenos, y es lo que yo haría. También estás correcto sobre las limitantes que no podrías realizar. Quizá la más segura de todas las medidas que tomas sea quitar el 5060 y usar uno diferente y alto. Si no escoges un puerto que se ocupe para otro servicio, la probabilidad de que alguien se tome la molestia de escanear todos los puertos que tengas abierto “a ver” cual pega, es muy remota. Si a esto le agregas las contraseñas seguras y el uso de fail2ban, prácticamente tendrás un sistema inviolable.

      Saludos,