Generador de contraseñas seguras para Asterisk/Elastix

8 Sep

CapturaDice el dicho que una cadena es tan fuerte como su eslabón más débil, y en muchos de los casos, las contraseñas inseguras que ocupamos en las extensiones de nuestro conmutador son la principal causa por la que nos llevamos desagradables sorpresas como recibir cuentas millonarias porque un atacante ganó acceso a nuestro equipo y curso tráfico no autorizado con alto costo para nosotros.

Como instalar equipos basados en Asterisk es parte del pan de todos los días, optamos por crear un generador de contraseñas seguras que te permita de manera rápida:

  1. Crear un pool de cadenas de texto aptas para ser utilizadas como contraseñas.
  2. Que permita generar la configuración de un sistema con interfaz gráfica (por ejemplo: Elastix) de manera rápida y con la plantilla default creada, descargándola como un CSV listo para importar.

Hemos estado utilizando esta herramienta ya por varios meses, pero hoy la damos a conocer para que todos ustedes puedan aprovecharla. Para usarla, solo deben proporcionar 3 datos:

  1. La lista de extensiones sobre la cual generar las contraseñas. Pueden usar valores individuales (ej. 101, 102, 105, etc) o rangos (ej. 101-200).
  2. Una clave inicial que servirá como semilla para generar las contraseñas seguras.
  3. La longitud deseada para tus contraseñas.

El sistema te regresa una cadena de texto con el alfabeto 0-9a-zA-Z. No utilizamos caracteres especiales porque sabemos que hay algunos sistemas que no te los reconocen, así que preferimos irnos a la segura y desplegar lo universal.

La aplicación es libre y puedes utilizarlas las veces que necesites. La única restricción es que por cuestiones de rendimiento, solo puedes generar lotes de hasta 500 extensiones.

Puedes comenzar a utilizar esta herramienta desde la siguiente liga (nota: se encuentra hospedada en el dominio de Enlaza Comunicaciones).

¡Suerte!

Elastix Addon: EasyVPN

2 Jun

Easy VPN Logo.PNG.Hola, como ya lo venía diciendo en mi cuenta de Twitter, en Enlaza Comunicaciones hemos estado trabajando en un Addon para los usuarios de Elastix. Después de algunas semanas, finalmente ha sido publicado en el sitio de Elastix Addons y ya está disponible para su descarga e instalación desde su Elastix (PDF de instrucciones [4.2MB]).

¿Pero de que va este Addon? En Enlaza tomamos mucho en cuenta la seguridad de los PBX dado que sabemos que al día se reciben cientos de ataques a PBX por los puertos expuestos de SIP, IAX, SSH, entre otros. Es por esta razón que nosotros usamos, siempre que es posible, una conexión a través de OpenVPN tanto para administrar los sistemas a los que les damos soporte como para crear extensiones remotas.

Como la mayoría de ustedes saben y conocen, OpenVPN es una herramienta Open Source que nos permite crear VPNs seguras entre nuestros equipos, esta herramienta es la más popular en ambientes Unix para crear túneles seguros entre nuestras redes. Si bien existen miles de tutoriales en la WEB para crear los túneles y configuraciones de OpenVPN y seguramente existen ya muchos usuarios con esta herramienta instalada en sus PBX, nos decidimos a crear un front-end web intuitivo y fácil de usar para usuarios que prefieran lo visual(WEB) al texto(consola de Linux).

Con el addon EasyVPN podrán:

  • Crear la configuración de la VPN en tan solo 5 sencillos pasos.

  • Crear los certificados de los clientes con un par de clicks .

  • Ver y administrar los clientes conectados al momento.

  • Crear certificados para clientes Windows.
  • Crear certificados para clientes Linux.
  • Crear certificados para teléfonos Yealink.
  • Crear certificados para teléfonos SNOM.

Entre los beneficios de utilizar EasyVPN están:

  • Utilizar sólo un puerto para la comunicación desde el exterior. Ya no será necesario abrir o natear puertos en el firewall para servicios específicos (SIP, IAX, SSH, HTTPS, etc).
  • Toda la comunicación entre los clientes y el servidor estará cifrada, nadie podrá leer los paquetes que se transmitan.
  • Los accesos estarán controlados. El administrador sabrá quien está conectado y desde qué IP.
  • Ideal para troncalizar Asterisk en distintas ubicaciones físicas.
  • Utilizar OpenVPN Connect en iOS y Android para registrar extensiones remotas en smartphones y/o tablets.

Todo el feedback, sugerencias y reportes de bugs serán bien recibidos en el thread oficial «Nuevo Addon para Elastix EasyVPN» en los foros Asterisk México. Así que a probarlo a fondo y de ser posible reportar fallos.

Configurando OpenVPN en un teléfono Denwa DW-310P

21 Ago

denwa+openvpnUna funcionalidad muy bienvenida en los nuevos teléfonos de VoIP es la posibilidad de soportar la creación de una VPN, ya que de esta manera podemos asegurar el tráfico que pasa por nuestro teléfono y además, garantizar que no sufriremos de los problemas de NAT característicos de SIP ya que toda la voz pasará por una red «local» y no por un firewall que podría detener parte de lo que estamos enviando.

En particular, las redes creadas sobre TLS (como es el caso de OpenVPN) son atractivas porque pueden levantarse completamente en software sin la necesidad de adquirir hardware externo para que se dedique a esto. Si bien las VPNs en hardware son de mayor rendimiento, la sencillez con la que podemos instalar un servicio de OpenVPN dentro del mismo servidor donde tenemos nuestro conmutador Asterisk hace que sea la opción más clara a seguir.

Existe en internet una gran cantidad de tutoriales que explican como configurar un teléfono Yealink con el servicio de OpenVPN. Sin embargo, existen otros teléfonos menos conocidos (y también más económicos) que ofrecen esta misma funcionalidad pero que hasta el momento, encontrar el procedimiento para configurar el servicio no había sido clara. Esperamos que con estos pasos que presentamos a continuación se aclaren muchas dudas.

En esta ocasión vamos a mostrar como configurar OpenVPN con un teléfono Denwa DW-310P (haremos un review próximamente del teléfono). Partiremos de los siguientes supuestos:

  • Ya tienes Asterisk instalado (no importa la versión).
  • El servicio de OpenVPN ya está instalado. Hay muchos tutoriales que te indican como hacerlo.
  • Entiendes que Asterisk posee 2 direcciones IP:
    • La «regular» que es la que usas para conexiones en tu misma red y/o fuera de la VPN.
    • La de la VPN, que es a la que apuntarán los equipos que se encuentren en un ambiente remoto.
  • El equipo donde estás trabajando es Windows.

Los pasos a seguir son muy sencillos:

  1. Descarga el archivo con los ejecutables para crear el security file que el teléfono tiene. Atención: es probable que un sistema antivirus catalogue su contenido como una amenaza, pero es normal.
  2. Descomprime el archivo. Te deberá quedar la siguiente estructura:
    1. bintoarray.exe
    2. OpenVpn.bat
    3. mkromfs.exe
    4. Directorio ‘config’ (está vacío)
  3. Dado que ya tienes tu servidor OpenVPN corriendo y estás familiarizado con el proceso, consigue los archivos necesarios para crear tu conexión VPN y ponlos en el directorio recién creado config siguiendo los siguientes nombres de archivo:
    1. ca.crt: El certificado de la entidad certificadora (CA)
    2. client.ovpn: Archivo de texto que contiene la configuración del cliente de OpenVPN (en Linux tendría extensión .conf o .cnf)
    3. client.crt: El certificado para el cliente
    4. client.key: La llave privada para el cliente
  4. Con los 4 archivos dentro del directorio config, dale doble-click al archivo OpenVpn.bat para ejecutarlo. Tras hacerlo, se generarán dos archivos: OpenVpn.bin OpenVpn.h.
  5. Entra a la interfaz web del teléfono. Dentro de las pestañas de Seguridad / Seguridad existe una sección que te permite «Actualizar archivo de seguridad». Entra a dicha opción y sube el archivo OpenVpn.bin que creaste con anterioridad.
  6. Cuando el archivo termine de subirse, en la parte inferior te aparecerán los nombres de los archivos originates (ca.crt, client.key, client.crt, client.ovpn), indicando que fueron reconocidos exitosamente (Recuerda: tu solo subes un archivo y en la pantalla aparecerán 4 diferentes).
  7. Con el archivo subido, acceder a Seguridad –> VPN –> Modo VPN. Habilitar el checkbox que dice «Habilitar VPN», seleccionar el uso de OpenVPN, guardar los cambios y reiniciar el teléfono.
  8. Tras reiniciar, si accedes a Seguridad –> VPN en la parte superior se te mostrará la IP que tu servidor de VPN le entregó al teléfono.

Con la VPN creada, la configuración del teléfono queda exactamente igual que como lo harías en cualquier otro caso:

  • Entras a la configuración de la cuenta.
  • Das de alta la IP de Asterisk, el usuario y la contraseña de tu cuenta SIP.
    • Recuerda: la IP de Asterisk ya no es la que usas normalmente, sino la que el equipo de Asterisk posee en el segmento de tu VPN.
  • Guardas y aplicas los cambios.

Desafortunadamente el teléfono donde validamos este procedimiento ya fue devuelto al proveedor, pero tan pronto tenga acceso a uno nuevamente tomaré unos screenshots del proceso para que no queden dudas.

¡Suerte!

Restringe el acceso a carpetas específicas usando Apache

18 Dic

url7[1]Nosotros nunca recomendamos exponer la interfaz web de tu conmutador (entiéndase: FreePBX/Elastix/Trixbox) bajo ningún motivo. Sin embargo, hay casos específicos en los cuales puede existir la necesidad de abrir el puerto HTTP/HTTPS para algunos servicios (ej. un CRM o alguna aplicación in house). Si esto debe de hacerse, es mejor hacerlo teniendo en cuenta algunas funciones básicas de seguridad.

Si aplicáramos lo que vimos en nuestros artículos del modelo de seguridad en Asterisk veremos que no es posible defender a nivel de firewall externo/iptables, ya que no hay una manera de permitir el paso solamente a ciertas carpetas. Para lograrlo, debemos hacer uso de la configuración de Apache la cual nos permite aplicar un mini firewall interno que solo permitirá a ciertas IPs ver ciertas páginas.

Primero, localicemos el archivo /etc/httpd/conf/httpd.conf (en algunos casos cambia de nombre a /etc/apache2/httpd.conf, así que hay que buscarlo con calma). Lo que buscamos es encontrar una directriz que permite el acceso por default a toda nuestra carpeta /var/www/html. El default en Elastix lo encuentran escrito así:

<Directory "/var/www/html">

#
# Possible values for the Options directive are "None", "All",
# or any combination of:
#   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important.  Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
    Options Indexes FollowSymLinks

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
    AllowOverride None

#
# Controls who can get stuff from this server.
#
    Order allow,deny
    Allow from all

</Directory>

Haciendo a un lado los comentarios, quedamos con estas instrucciones:

<Directory "/var/www/html">
SymLinksifOwnerMatch ExecCGI MultiViews
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

Queremos ponerle atención a las lineas de Order allow,denyAllow from all. Explicamos lo que quiere decir:

  • Order allow,deny quiere decir que las instrucciones están declaradas como Permite primero, niega después.
  • Allow from all es una cláusula que permite que todos vean todo (default), lo cual le quita todas las restricciones a los usuarios.

El primer paso consiste en cerrar todo y permitir el paso solamente a direcciones IPs de confianza. Esto lo podemos conseguir con lo siguiente:

<Directory "/var/www/html">
SymLinksifOwnerMatch ExecCGI MultiViews
    Options Indexes FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 192.168.1.0/24
    Allow from 127
    Allow from 10.200.1.0/24
</Directory>

¿Notan la diferencia? Ahora estamos negando el paso a todo y permitiendo solamente que las redes de confianza 192.168.1.0/24, 10.200.1.0/24 y la de loopback tengan acceso completo al servidor. En otras palabras: solo las redes locales van a poder entrar a la administración web completa.

Para crear ahora carpetas sin restricción (ej. que cualquier usuario interno o externo las pueda ver), las agregamos como directrices nuevas:

<Directory "/var/www/html/vtigercrm" >
   Order deny,allow
   Allow from all
</Directory>

Y ahora estamos permitiendo el acceso completo a esa carpeta en particular (nuestro CRM). Por cada carpeta debemos crear una directiva <Directory> que permita el acceso.

Recuerden reiniciar el servicio de Apache:

/etc/init.d/httpd restart

# Según nuestra distro, el servicio se llama Apache2
/etc/init.d/apache2 restart

De esta manera, si abrimos http://<direccion ip publica>/vtigercrm podremos ver el CRM de nuestro equipo, pero si tratáramos de ver nuestra interfaz de administración con http://<direccion ip publica>/adminhttp://<direccion ip publica>

Advertencia: Siempre asegúrate de probar tu configuración de seguridad antes de ponerla en producción. Nosotros nunca recomendamos exponer el puerto HTTP/HTTPS, ya que aunque al usar esta configuración no permites el paso a otros usuarios, no quiere decir que no haya vulnerabilidades en tu código mostrado por Apache, así que acepta el riesgo de exponer tu equipo así. Lo mejor que puedes hacer es crear un nuevo equipo que hostee tu aplicación y exponer ese, sin que tengas abierto lo mismo en tu conmutador.

¡Suerte!

Como bloquear extensiones al final del día (cerrar extensión cuando el trabajador se retira)

3 Dic

En ocasiones en nuestras oficinas (sobretodo en grandes corporativos), estamos sujetos a presupuestos de llamadas por mes. Esto quiere decir que recibimos una bolsa de minutos a ciertos destinos (para control de gastos) y debemos cuidarlos, ya que si nos los agotamos tendremos que hacer solicitudes de «crédito» interno y ante nuestros superiores parecería como que estamos desperdiciando dinero (llamadas) de la empresa.

Contemplando escenarios similares a este, podemos configurar Asterisk para que las extensiones de cada persona sean bloqueadas al momento en que la persona se retira a su casa. De esta manera, si alguien se queda cercano a su área de trabajo no podrá tomar su teléfono y hacer llamadas al exterior, reduciendo el crédito del trabajador que ya se fue (y ahorrándose el suyo). Al día siguiente, cuando el trabajador regresa, marca un código de desbloqueo junto con su contraseña y su teléfono vuelve a estar habilitado.

¿Cómo hacer eso?

Partiremos de los siguientes supuestos:

  • El contexto al que mis extensiones «normales» tienen derecho es el from-internal.
  • El código para bloquear la extensión (cuando el trabajador se va), será *51.
  • El código para desbloquear la extensión (cuando el trabajador regresa por la mañana), será *52.
  • Todas las extensiones deben tener un buzón asignado. El número de buzón debe ser el mismo que el de la extensión.
  • La marcación que negaremos será solamente la que corresponda a llamadas locales, larga distancia, celulares e internaciones (es decir, todas las que cuesten).
  • La sintaxis que estoy ocupando (same =>) es para Asterisk 1.6.2 o superior.

Toda la magia viene en el archivo extensions.conf (si usas Trixbox/Elastix/FreePBX, debes de hacerlo dentro del archivo extensions_custom.conf)

[from-internal-custom]
; Estos son los patrones para hacer las llamadas
; Si necesitas cerrar más patrones, agrégalos siguiendo el mismo formato
exten => _ZXXXXXXX,1,Macro(permitir)
same => n,Goto(from-internal-additional,${EXTEN},1)
exten => _04[45]ZXXXXXXXXX,1,Macro(permitir)
same => n,Goto(from-internal-additional,${EXTEN},1)
exten => _01ZXXXXXXXXX,1,Macro(permitir)
same => n,Goto(from-internal-additional,${EXTEN},1)
exten => _00ZXXXXXXXX.,1,Macro(permitir)
same => n,Goto(from-internal-additional,${EXTEN},1)

; Este es el código de bloqueo. Es lo que el trabajador marca antes de retirarse
exten => *51,1,Noop(Bloqueando ${CALLERID(num)})
;same => n,VMAuthenticate(${CALLERID(num)})     ; Descomenta esta línea si quieres pedir contraseña también al bloquear
same => n,Set(DB(bloqueo/${CALLERID(num)})=1)
same => n,Playback(vm-goodbye)
same => n,Hangup
; Este es el código de desbloqueo. Es lo que marca a la mañana siguiente
exten => *52,1,Answer
same => n,VMAuthenticate(${CALLERID(num)})
same => n,Noop(${DB_DELETE(bloqueo/${CALLERID(num)})})
same => n,Playback(auth-thankyou)
same => n,Hangup

; El macro-permitir es lo que valida si una extensión tiene o no activada el bloqueo
[macro-permitir]
exten => s,1,Noop(Revisando permisos de ${CALLERID(num)})
same => n,GotoIf($[${DB_EXISTS(bloqueo/${CALLERID(num)})}]?Bloquear:Permitir)
same => n(Bloquear),Noop(Deteniendo el paso de ${CALLERID(num)})
same => n,Playback(pbx-invalid)  ; Reemplazar por cualquier archivo de sonido deseado
same => n,Congestion()
same => n(Permitir),Noop(Permitiendo el paso de ${CALLERID(num)} --> ${MACRO_EXTEN})

Una breve explicación de lo que hace cada cosa:

  • Los patrones de ZXXXXXXX, 01ZXXXXXXXXX, 04[45]ZXXXXXXXXX y 00ZXXXXXX. son para controlar las llamadas locales, larga distancia nacional, celulares y LD internacional respectivamente. Si tienes más patrones de marcación o destinos que desees bloquear (por ejemplo, alguna marcación corta por telular), necesitas agregar el patrón correspondiente siguiendo el mismo formato (tras cada patrón debe haber una continuación same => n,Goto(from-internal-additional,${EXTEN},1) que te permite continuar con el contexto from-internal-additional.
  • *51 y *52 son, como habíamos comentado, los códigos para bloqueo/desbloqueo respectivamente. Puedes reemplazar los Playbacks por lo que tu elijas para dar diferentes mensajes
  • El [macro-permitir] es el que checa el contenido del Asterisk DB. Si la familia bloqueo/CALLERID existe, entonces no se le permiten las llamadas. Si no existe, el macro permite el paso y la llamada continúa de manera normal.
  • Las autenticaciones se hacen con la misma contraseña del buzón de voz, así cada quien tiene la suya, es actualizable por el usuario y solo funciona dentro de su mismo teléfono.
  • Si deseas desbloquear manualmente alguna extensión (ej. alguien olvidó su contraseña), solo debes ejecutar database del bloqueo <ext> dentro del *CLI.

Con esto lograremos que al cierre del turno, el trabajador pueda bloquear su teléfono y reactivarlo a la mañana siguiente con solo ingresar su contraseña.

Debo agregar que funciona tan bien que anoche que lo implementé dejé cerrada mi extensión y hoy no me permitía hacer llamadas, hasta que marqué *52 e introduje mi contraseña nuevamente.

¡Suerte!

Permitiendo llamadas no autenticadas del exterior (con restricciones)

26 Abr

Fuente: http://www.datacenta.com/Pictures/stop.jpg

En este blog y en muchos otros se ha discutido el uso de aplicaciones como fail2ban para impedir ataques de fuerza bruta combinado junto con iptablespara denegar el acceso a fuentes no autorizadas. Existe un caso especial que es cuando tenemos que aceptar las llamadas anónimas del exterior sin importar desde donde se originen, y ese es el caso del que voy a comentar a continuación.

Recibir llamadas anónimas no es malo, pero hay que saber lo que se hace y tomar las precauciones necesarias. Al permitir las llamadas entrantes desde cualquier fuente estamos permitiendo que cualquiera nos contacte via IP, para que así el interesado no tenga que paga costos de LD, ni tampoco tenga que hacer algún setup muy elaborado en su conmutador. Ofrecer un peer de autenticación a cada usuario sería un poco difícil, ya que lo que se espera de estos escenarios es que la comunicación sea en un solo sentido (de afuera nos marcan a nosotros hacia adentro) y también, buscas hacerla lo más fácil de marcar para el usuario final.

En nuestro caso, nosotros permitimos llamadas provenientes del exterior pero solo hacia nuestras extensiones internas. De esta manera, no hay costos relacionados con ataques porque las llamadas nunca vuelven a salir hacia la PSTN. Solo pueden comunicarse a nuestras extensiones internas y DIDs. El único problema, es que a veces los equipos que atacan piensan que al no negar las llamadas, vamos a permitirlas salir, así que nos mandan intentos de ataques de unas 40 llamadas simultáneas, lo que hace que nuestros teléfonos comiencen a sonar una y otra vez.

Para evitar que nuestro conmutador se atiborre de llamadas que no deseamos, pero que al mismo paso permita las llamadas que si queremos, debemos permitir lo siguiente desde nuestro GUI:

  • Permitir llamadas anónimas: si

Y luego hacemos esta combicación de plan de llamadas personalizado y fail2ban (estamos usando FreePBX). Dentro del archivo extensions_custom.conf ponemos:

[ext-did-post-custom]
exten => _X.,1,Macro(contador,${SIPCHANINFO(peerip)},3)
exten => _X.,n,Goto(ext-did-catchall,${EXTEN},1)

[macro-contador]
exten => s,1,GotoIf($[${GROUP_COUNT(${ARG1})}<=${ARG2}]?Permite)
exten => s,n,Noop(LLAMADAS EXCEDIDAS POR ${ARG1}. BLOQUEANDO)
exten => s,n,Congestion()
exten => s,n(Permite),Set(GROUP(${CDR(uniqueid)})=${ARG1})

Lo que estoy haciendo aquí es que siempre que reciba una llamada en mi FreePBX que no esté especificada hacia una extensión y/o DID que tenga dado de alta, el contexto [ext-did-post-custom] lo procesará y hará un análisis del número máximo de llamadas simultáneas que debe permitir.

  • Si se exceden 3 llamadas de acuerdo al ejemplo, debo cortar el paso y enviar un mensaje a consola que diga «LLAMADAS EXCEDIDAS»
  • Si no se excede, permito el paso enviando la llamada hacia la cláusula default [ext-did-catchall]
  • Si recibo llamadas desde una fuente «no autorizada» hacia un número que si existe en mi sistema, el contexto [ext-did] lo procesará de manera normal
  • Si el origen ya fuera autorizado, caerá en el contexto que sea que yo le haya especificado y hará caso omiso de esta configuración

Tras hacer la modificación correspondiente y recargar, el mensaje de «LLAMADAS EXCEDIDAS» ya aparece en mis logs. Ahora debo modificar mi fail2ban para que tome en cuenta este texto y bloquee a nivel de firewall a aquellos que nos manden llamadas en bruto.

Basándome en el artículo de fail2ban anterior que publicamos hace unos meses, modifico el /etc/fail2ban/filter.d/asterisk.conf para que quede así:

failregex = Registration from '.*' failed for '(:[0-9]{1,5})?' - Wrong password
Registration from '.*' failed for '(:[0-9]{1,5})?' - No matching peer found
Registration from '.*' failed for '(:[0-9]{1,5})?' - Device does not match ACL
Registration from '.*' failed for '(:[0-9]{1,5})?' - Username/auth name mismatch
Registration from '.*' failed for '(:[0-9]{1,5})?' - Peer is not supposed to register
LLAMADAS EXCEDIDAS DESDE (:[0-9]{1,5})?
NOTICE.* failed to authenticate as '.*'$
NOTICE.* .*: No registration for peer '.*' (from )
NOTICE.* .*: Host failed MD5 authentication for '.*' (.*)
VERBOSE.* logger.c: -- .*IP/-.* Playing 'ss-noservice' (language '.*')
LLAMADAS EXCEDIDAS POR

Si el fail2ban atrapa estas líneas, bloqueará al host por el tiempo que le hayamos especificado en el archivo jail.conf.

Debo destacar que este es un caso muy especial que pocos querrán utilizar, pero es bueno saber que se puede ser precavido y a la vez, flexible con el uso de tu conmutador. Dado que permitir llamadas anónimas expone tu conmutador, la responsabilidad de este código recae en quien lo usa, por lo que no debes aplicarlo si no estas seguro de que es lo que hará.

¡Suerte!

Explotando vulnerabilidades en teléfonos autenticados: Yealink

24 Abr

Actualización 30/julio/2013: Podemos confimar que al usar el firmware más reciente en este momento (9.70.0.140) la funcionalidad de marcación sin autenticación que provocaba este problema de seguridad viene desactivado, y es necesario configurar el teléfono con la IP autorizada que podrá hacer uso del API, por lo que este problema ya no existe. Sin embargo, nunca está de más asegurar su red y cambiar las contraseñas default del teléfono para impedir cualquier acceso no autorizado.

Yealink T20P: teléfono básico

Hace unos días recibí una llamada de uno de mis clientes. La historia comienza con una de las frases que menos me gusta escuchar en mi medio:

– Christian, ¿puedes venir? Nos hackearon el conmutador de la oficina…

Acudí en menos de una hora al sitio (yo no tenía acceso remoto y ni siquiera tenía conocimiento de este equipo) y me dí a la labor de revisar los logs para tratar de reconstruir el caso. Sin embargo, me encontré con lo siguiente:

  • El equipo tenía servicios de iptables y fail2ban protegiéndolo
  • Las contraseñas de SIP eran seguras
  • No se recibían conexiones ni por SIP ni por HTTPS del exterior
  • Todas las llamadas habían sido originadas desde una extensión
  • Apache no tenía registros de IPs externas, tampoco Asterisk.

Todo parecía indicar que hubiera sido un inside job, y en efecto (al menos parcialmente), así fue.

Por más que busqué no encontré señales de como había logrado entrar, pero las llamadas estaban en el CDR y en el gateway SIP que terminaba la comunicación. ¿Qué ocurrió entonces?

De pronto, el empleado al que pertenece el teléfono cuya cuenta SIP ocasionó todas las llamadas, exclamó lo siguiente:

– Mi teléfono ha estado raro. Varias veces en la mañana estuvo «marcando solo» y yo solamente escuchaba una grabación a veces de que la llamada no había podido ser completada

Momento… ¿marcando solo? ¿Desde cuando los teléfonos se marcan solos? Se trataba de un Yealink T20, el cual es un modelo extremadamente sencillo y económico. ¿Qué funcionalidad podría tener que hiciera que marcara solo?

La respuesta es: los Yealink ofrecen la posibilidad de marcación automática a través de una simple y sencilla petición HTTP que requiere autenticación, pero si nunca cambian la contraseña de usuario y administrador del teléfono (lo cual casi nadie hace), cualquiera puede hacer que el teléfono marque solo hacia cualquier destino.

Si tienen un teléfono Yealink consigo (cualquier modelo), prueben hacer esto en su casa/oficina:

Supongamos que la IP de nuestro Yealink sea 192.168.1.101. Asumimos que en nuestro Asterisk existe un plan de marcación que nos permite marcar larga distancia. Imaginemos el número 018881234567. Ahora bien, abran el siguiente URL en su navegador favorito (recuerden cambiar los valores según corresponda):

http://user:user@192.168.1.101/cgi-bin/ConfigManApp.com?Id=34&Command=1&Number=018881234567&Account=0

¿Y qué ocurre? Simple y sencillamente, su teléfono marcará por ustedes hacia el número indicado usando la primer cuenta que tengan configurado en él. Si Asterisk no los autentica a nivel de usuario, ustedes tienen un severo problema de seguridad ya que cualquier persona podría manipular su teléfono para marcar hacia donde le viniera en gana.

Y bien, ¿qué pasa si abren el URL repetidas ocasiones? Fácil. El teléfono marcará una y otra vez a ese número sin colgar las otras llamadas. De manera que un solo teléfono podría hacer 100 llamadas a Afghanistan, Sierra Leona o cualquier otro destino caro del mundo. Esto es muy fácil de lograr con un script en Linux que invoque al wget. Lo demostré en laboratorio y creanme, los resultados asustan.

Imaginen por un momento que alguien tuviera acceso a su red interna, pero no conoce las contraseñas de los teléfonos. Con este truco no es necesario saberlas, ya que el teléfono se encuentra ya autenticado en su red interna y por lo tanto, las llamadas saldrán aún si ustedes confían en que su firewall no recibirá conexiones del exterior.

Por tal motivo, si ustedes deciden abrir erróneamente los puertos en su firewall y exponen la configuración del teléfono, le están abriendo la puerta a alguien a que haga cientos de llamadas sin autorización. En la historia que les acabo de contar, alguien aprovechó esta vulnerabilidad e hizo más de 40,000 minutos de llamadas a los destinos más caros del mundo en tan solo 12 horas, y sin tener que usar su ancho de banda para generar esas llamadas.

Piénsenlo muy bien antes de que expongan equipos al internet. Hay un mundo peligroso allá afuera, y si no se protegen, más temprano que tarde acabarán siendo víctimas de la cyber delincuencia.

¡Suerte!

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!

Modelo de seguridad en Asterisk (parte 2 de 3)

6 Mar

El día de ayer publicamos la primera de esta serie de entregas que buscan concientizar sobre los 3 diferentes niveldes de seguridad en un conmutador IP como lo es Asterisk. Discutimos sobre la seguridad de acceso al sistema, que es la primer barrera contra la quenos anfrentamos al acceder al equipo. Para esta entrega hablaremos del segundo nivel de seguridad, es decir: los atacantes ya pueden llegar hasta el equipo, ¿cómo podemos defendernos de lo que nos pueden hacer?

Seguridad de autenticación

Como mencioné en el párrafo anterior, esta es la segunda capa de protección contra atacantes externos: ya penetraron nuestra red, ya pueden «ver» nuestro conmutador. ¿Quiere eso decir que estamos a su merced? Obviamente no, pero debemos tener algunos aspectos muy importantes en cuenta para que esto no nos pase. De entre los puntos a mencionar, resaltemos estos:

  • Listas de acceso para usuarios SIP/IAX
  • Contraseñas SIP/IAX seguras
  • Defensa contra fuerza bruta

Listas de acceso

Esta es, sin duda, la característica mas evitada en seguridad de Asterisk: configurar listas de acceso que hagan una coincidencia con los dispositivos que deben/pueden registrarse en nuestro sistema, limitando el acceso a ciertas extensiones desde ciertas IPs.

Por ejemplo: si nuestra red interna está en el segmento 192.168.1.0/24, ¿por qué razón habríamos de permitir que la extensión que pertenece a la sala de juntas se registre desde la IP 189.200.45.13? Las listas de acceso nos permiten restringir desde que IP puede un dispositivo registrarse o hacer llamadas con nosotros. Esta es la única manera que tienen de hacer que solo ciertas extensiones puedan ser usadas desde afuera de nuestra red (usuarios móviles), mientras que el resto no (usuarios locales)

Las listas de acceso en Asterisk se configuran usando los campos de permit y deny dentro ya sea de la sección [general] o bien dentro de la configuración de cada usuario (esto aplica para sip.conf y para iax.conf). Tomen en cuenta que el orden si importa y que la metodología default es un permit any. Esto quiere decir que si no negamos la autenticación, se le permite el paso a todo. Observen el siguiente ejemplo:

[codesyntax lang=»ini»]

[100]
username=100
type=friend
context=default
secret=aBcDeF12345!
deny=0.0.0.0/0.0.0.0
permit=192.168.1.1/255.255.255.0

[/codesyntax]

 

En este ejemplo, la regla de deny=0.0.0.0/0.0.0.0 está negando el paso a todo, ya continuación el permit=192.168.1.1/255.255.255.0 está permitiendo el paso solamente a aquellos dispositivos que se encuentren dentro de la red 192.168.1.x. Tengan mucho cuidado ya que si invertimos el orden de declaración:

[codesyntax lang=»ini»]

[100]
username=100
type=friend
context=default
secret=aBcDeF12345!
permit=192.168.1.1/255.255.255.0
deny=0.0.0.0/0.0.0.0
[/codesyntax]

Al final, el deny (que es lo último declarado) prevalecerá, y dado que 0.0.0.0/0.0.0.0 hace match con todo, estamos negando el paso a todos (haciendo que la extensión no sirva).

También pueden usar la notación CIDR, por lo que pueden declarar un rango de red como 192.168.1.1/24 y es igual que 192.168.1.1/255.255.255.0.

Recuerden que al declarar el permit/deny dentro de [general] están habilitando esa regla para todos, pero si solo colocan reglas de permit individuales dentro de cada usuario, abrirán ese usuario solamente. Esta es la única manera que tendrán de permitir el acceso remoto a usuarios SIP/IAX específicos, negando la posibilidad a todos los demás. Esto resulta muy conveniente porque no exponen todas sus extensiones, sino solo las estrictamente necesarias.

Al tener que descuidar y permitir el paso a ciertos usuarios, deben asegurarse de que las contraseñas de aquellos usuarios a los que les permiten acceder desde el exterior son suficientemente seguras, y de ahí viene el siguiente punto.

 

Contraseñas SIP/IAX seguras

Un motivo que muchos administradores tienen para dejar contraseñas inseguras es por facilitarse la labor al momento de configurar sus dispositivos SIP. Lo que muchas personas desconocen es que las contraseñas SIP/IAX se hicieron para tener que teclearlas una única vez, y esto es cuando configuramos el dispositivo (de hecho, si hacemos la configuración por provisionamiento TFTP nunca tendremos que teclearlas, pero ese es material para otro artículo). Si la contraseña solo deble escribirse o copiarse una única vez, entonces no existe razón para aprovechar y echarle un poco más de tiempo en usar contraseñas que sean tan seguras que un sistema de fuerza bruta no pueda romper.

Existen muchos mecanismos sencillos para generar contraseñas aleatorias. Quizá uno disponible que cualquier sistema con Linux tendría (con el paquete de openssl instalado):

[codesyntax lang=»bash» title=»Desde el Linux CLI:»]

# Esto generará 20 contraseñas aleatorias de 12 caracteres
for i in {1..20}; do openssl rand -base64 12; done

[/codesyntax]

Podemos fácilmente cambiar el 20 por cualquier otro número y generar un pool de contraseñas aleatorias que podemos ocupar para nuestras extensiones, asegurándonos con esto de que nuestras contraseñas sean totalmente seguras.

También tomemos en cuenta peores casos: si no colocamos una contraseña en una cuenta IAX estaremos abriendo la posibilidad de que cualquier entidad que llegue a nuestro equipo aún y si no proporciona contraseña sea autenticado inmediatamente. Esto es por la propiedad de IAX que se basa totalmente en la contraseña para realizar la autenticación de un dispositivo. Si no llenamos este campo, cualquiera se podrá autenticar como tal, aún y sin proporcionar ningún dato.

El hecho de tener contraseñas seguras impedirá que los atacantes entren a nuestro sistema. Sin embargo, no impedirá que lo intenten. Aquí está la última parte de este rompecabezas:

 

Defensa contra fuerza bruta

Es un hecho: si nuestro equipo debe estar expuesto porque nuestros usuarios así lo requieren, entonces tarde o temprano será atacado. El ataque puede verse en la forma de cientos de intentos de registro que intentarán adivinar nuestra contraseña segura definida en el punto anterior. A pesar de que sabemos que nunca la encontrarán, tantos cientos (o miles) de intentos pueden generar un ataque DoS en nuestro conmutador. ¿Cómo defendernos ante esto?

La respuesta es un sencillo (pero eficiente) programa llamado fail2ban. El fail2ban es una herramienta que analiza logs de intentos de ataque y bloquea selectivamente por iptables a la IP que origina estos ataques. Es como traer la seguridad de acceso cuando alguien ya entró a nuestro equipo pero se delató proporcionando contraseñas equivocadas. Veanlo como el personal de seguridad que te saca del lugar por comportarte mal, permitiéndote bloquearlo a nivel de firewall por unos minutos, horas o de manera permanente, todo depende de como lo configures.

Si estás interesado en ver como puedes configurar fail2ban y los filtros que puedes aplicar, puedes consultar el artículo que escribí hace unos meses.

 

Con esto cubrimos el segundo nivel en esta serie de entregas. En la siguiente discutiremos sobre la manera en como autenticar no a los dispositivos, sino a los usuarios, que son los últimos elementos en la cadena de seguridad de nuestro sistema.

¡Suerte!

Modelo de seguridad en Asterisk (parte 1 de 3)

5 Mar

Fuente: http://upload.wikimedia.org/wikipedia/commons/5/5b/Firewall.png

Desafortunadamente y como hemos comentado en otros posts, la seguridad en Asterisk es algo que se ha visto sobrevalorado por la sencillez y rapidez que trae el dejar un sistema que funciona en unas cuantas horas a partir de una distribución todo integrado, pero que es inseguro por descuidos del administrador.

¿Cómo puede alcanzarse la seguridad al 100% del conmutador? La respuesta es no se puede. Sin embargo, lo que si podemos hacer es llevar nuestro sistema a un nivel de seguridad que haga que aquel que intente penetrarlo sin autorización tenga que invertir más tiempo del que está dispuesto a ceder.

Para explicar mejor esto, definiremos el modelo de seguridad de Asterisk en 3 niveles:

  1. Seguridad externa (acceso al sistema)
  2. Seguridad de autenticación
  3. Seguridad de operación

Seguridad externa

Todo acceso al sistema desde fuentes externas (WAN) debe estar restringido a través de un firewall. Idealmente, usaríamos un firewall en hardware, pero si nuestro proveedor nos entrega una IP directa y la configuramos en nuestro equipo, podemos hacer uso de iptables.

Cuando decidimos que puertos abrir en nuestro firewall, debemos hacernos las siguientes preguntas:

  • ¿Habrá extensiones externas?
  • ¿Habrá alguna administración externa del conmutador?
  • ¿Existe algún proceso externo que controle el conmutador (manager interface)?

El tema de las extensiones externas es delicado, ya que es una parte fundamental de las ventajas de Asterisk pero al mismo tiempo es lo que permite el mal uso del conmutador. Si no pensamos tener extensiones externas, los puertos UDP 5060 y 4569 (SIP e IAX) deben estar cerrados. Si no abrimos los puertos, nadie ajeno al sistema, aún sabiendo las contraseñas de las extensiones podrá hacer llamadas. Al cerrar los puertos, cortamos el cable de acceso, y nada puede pasar. Es por eso que esta es la parte más importante de seguridad del sistema.

Si nos encontramos bajo el escenario que debemos tener extensiones externas, tenemos que asegurarnos que el nivel de seguridad secundario sea bueno, ya que al conceder acceso a entidades externas, debemos dejar la responsabilidad de la seguridad a las capas interiores. De esto nos encargaremos en la parte 2 de este artículo.

Nota: Al momento de hacer un register hacia una entidad SIP/IAX2 externa estaremos abriendo una sesión a través del firewall, lo que permitiría a esta entidad enviarnos llamadas a pesar de que el firewall esté cerrado. Hay que tomar esto en cuenta pues si alguien tuviera acceso administrativo a nuestro equipo podria generar un register hacia su propio conmutador y con ello, enviarnos llamadas en sentido inverso. El caso es muy raro, pero puede ocurrir. Ténganlo en cuenta.

Si necesitamos contar con administración remota del equipo debemos decidir correctamente que tipo de seguridad proveer. Si utilizamos alguna interfaz gráfica como FreePBX nunca, pero nunca debemos abrir el puerto HTTPS (TCP 443). Abrir el puerto 443 permitiria que cualquier vulnerabilidad de nuestra web, ya sea por FreePBX, Webmin, phpMyAdmin o cualquier otra interfaz que nos exponga contra atacantes externos.

Sobre este punto debo decir que dadas múltiples vulnerabilidades que han sido encontradas en interfaces gráficas, ningún administrador que considere su trabajo digno dejaría expuesto el puerto de HTTPS. Si acaso se necesita (para la administración), lo correcto es usar un túnel SSH o mejor aún, una conexión por VPN (sobre este último punto, si creamos una VPN podríamos no tener que abrir ni un solo puerto entrante en el firewall, por lo que este resultaría el caso más seguro de todos).

Por último, si tuviéramos necesidad de controlar Asterisk a través del Manager Interface (AMI), es necesario saber que toda la comunicación por este puerto siempre viaja sin encriptación, por lo que si alguien intercepta los paquetes del AMI podría fácilmente controlar completamente nuestro conmutador, creando extensiones o solicitando llamadas de la nada. El puerto que se ocupa para esta comunicación es el 5038 TCP y por lo tanto, nunca deberíamos dejarlo expuesto en nuestro firewall.

 

Este es el final de la primera de tres entregas sobre el modelo de seguridad de Asterisk. En las siguientes 2 partes haremos mención de como configurar ACLs dentro de Asterisk para asegurar el acceso, así como las opciones que debemos tomar en cuenta al momento de generar contraseñas seguras para acceso a nuestros usuarios SIP/IAX.

Recuerden que también pueden dejarnos sus comentarios a través de Twitter o Facebook.

¡Suerte!