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 ingeniero 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 18 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, así como servicios de interpretación simultánea y traducción.