miércoles, 7 de agosto de 2013

Servidor VPN en un Elastix. Agregando un nivel de seguridad adicional a las comunicaciones.

Para continuar con el tema de seguridades, y proteger las comunicaciones escribo este artículo.

Lo primero que voy a hacer es explicar como instalar un servidor openvpn en un Elastix. Se debe instalar el paquete openvpn y easy-rsa:

# yum install openvpn easy-rsa.noarch -y

Una vez instalados los paquetes, lo primero que se debe hacer es crear una CA (autoridad de certificación), para poder emitir certificados, tanto para el servidor como para el cliente.
Para esto hay que ir a la carpeta "/usr/share/easy-rsa/2.0". Una vez en este directorio se crea una carpeta en donde se almacenan los certificados:

# cd /usr/share/easy-rsa/2.0
# mkdir keys

Luego se debe editar el archivo "vars":

# vim vars

Se deben cambiar los parámetros:

export KEY_CONFIG="/usr/share/easy-rsa/2.0/openssl-1.0.0.cnf"
export KEY_DIR="/usr/share/easy-rsa/2.0/keys"

Que son los directorios en donde se encuentra el archivo de configuración de openssl, y en donde se van a guardar los certificados creados, respectivamente.
También se recomienda cambiar los valores de los campos país, provincia, entre otros.

Luego se ejecutan los siguientes comandos para crear la autoridad de certificación:

# source ./vars
# ./clean-all
# ./build-ca

El siguiente paso es crear los certificados para el servidor como para el cliente:

# ./build-key-server mi-elastix
# ./build-key cliente1
# ./build-key cliente2

El siguiente paso es crear la llave general para la encriptacion.

# ./build-dh

En el servidor los archivos de la carpeta "keys/":  "ca.crt" "dh1024.pem" "mi-elastix.crt" "mi-elastix.key" se deben copiar a la carpeta "/etc/openvpn".

En la carpeta anterior se debe crear el siguiente archivo:

# vim /etc/openvpn/server.conf

Que contiene lo siguiente:

port 1194
dev tap
ca /etc/openvpn/ca.crt
cert /etc/openvpn/mi-elastix.crt
key /etc/openvpn/mi-elastix.key

dh /etc/openvpn/dh1024.pem
server 10.88.0.0 255.255.255.0
ifconfig-pool-persist /etc/openvpn/ipp.txt
keepalive 10 120
cipher AES-128-CBC
comp-lzo
persist-key
persist-tun

status openvpn-status.log
verb 3

Se inicia el demonio openvpn:

# /etc/init.d/openvpn start

Para los clientes se deben copiar los archivos de la carpeta "keys/":  "ca.crt" "cliente1.crt" "cliente1.key" a la carpeta "/etc/openvpn" (en el caso de ser un linux el cliente).

Luego en se debe crear el siguiente archivo:

# vim /etc/openvpn/client.conf

Con el siguiente contenido:

dev tap
persist-tun
persist-key
cipher AES-128-CBC
tls-client
client
resolv-retry infinite
remote mi-ip 1194 udp
ca /yealink/config/openvpn/keys/ca.crt
cert /yealink/config/openvpn/keys/client1.crt
key /yealink/config/openvpn/keys/client1.key
comp-lzo


Y se inicia el demonio openvpn en el cliente.

Para el caso específico de teléfonos Yealink, se debe hacer lo que se indica en el siguiente enlace:

http://www.voztovoice.org/?q=node/476

Con la diferencia de que el archivo "vpn.cnf" debe contener lo detallado para el archivo "client.conf".

Una vez se sube la configuración al teléfono, el mismo establece la conexión al servidor VPN.

Se debe registrar la extensión apuntando a la dirección IP del servidor VPN, en este caso de la interfaz tap0. Por ejemplo la IP 10.88.0.1.

Si se hace una captura de tráfico, usando wireshark, unicamente se ve tráfico UDP desde el puerto 1194 del teléfono al puerto 1194 de la central y viceversa (no se podrá distinguir que se establece una llamada). Esta comunicación dificilmente será interceptada. Sobre esto se puede agregar SRTP, como se detalló en la entrada anterior, con lo que se agregaría un nivel de dificultad mas, si alguien quisiera interceptar las comunicaciones.

Espero sus comentarios.

martes, 6 de agosto de 2013

SRTP y TLS en Elastix Actualizado

Hace un tiempo escribí un artículo sobre SRTP y TLS en Elastix.
La ventaja de Elastix es que cuenta con el soporte necesario para soportar esta funcionalidad.
Lo primero que se debe hacer es editar el archivo "/var/www/html/admin/modules/core/functions.inc.php". Se recomienda hacer una copia del archivo antes de editarlo.

# vim /var/www/html/admin/modules/core/functions.inc.php

Aproximadamente en la línea 3800 se tiene lo siguiente:

array($account,'deny',$db->escapeSimple((isset($_REQUEST['deny']))?$_REQUEST['deny']:''),$flag++),                    array($account,'permit',$db->escapeSimple((isset($_REQUEST['permit']))?$_REQUEST['permit']:''),$flag++),
array($account,'disallow',$db->escapeSimple((isset($_REQUEST['disallow']))?$_REQUEST['disallow']:''),$flag++),
array($account,'allow',$db->escapeSimple((isset($_REQUEST['allow']))?$_REQUEST['allow']:''),$flag++)

Después de esas líneas se agrega lo siguiente:

array($account,'encryption',$db->escapeSimple((isset($_REQUEST['allow']))?$_REQUEST['allow']:''),$flag++),
array($account,'transport',$db->escapeSimple((isset($_REQUEST['allow']))?$_REQUEST['allow']:''),$flag++)

No olvidarse de agregar una coma al final de la línea que dice allow.

Y en la línea 6012 se tiene:

$tmparr['deny'] = array('value' => '0.0.0.0/0.0.0.0', 'level' => 1);
$tmparr['permit'] = array('value' => '0.0.0.0/0.0.0.0', 'level' => 1);

Agregar después de esas líneas lo siguiente:

$tmparr['encryption'] = array('value' => 'no', 'level' => 1);
$tmparr['transport'] = array('value' => 'udp', 'level' => 1);

Con esas dos modificaciones lo que se hace es agregar dentro del formulario html y del archivo sip_additional, que son utilizados para la configuración de extensiones, los campos encryption y transport.

Una vez hechos los cambios aparece lo siguiente:


El siguiente paso es la creación de una autoridad de certificación y los certificados tanto para el servidor como para el cliente. Para esto se utilizará los scripts que vienen dentro de la documentación de asterisk.
Estos scripts están en la carpeta "/usr/share/doc/asterisk-11.4/contrib/scripts"
Para generar el certificado de la CA como del servidor se ejecuta lo siguiente (dentro de la carpeta antes mencionada):

# mkdir certs


./ast_tls_cert -d certs -C mi-elastix.mi-dominio.lan -o mi-elastix.mi-dominio.lan

Para generar el certificado se recomienda hacerlo con el fqdn del servidor que en este caso es mi-elastix.mi-dominio.lan.
Para setear el fqdn en servidor se debe editar el archivo "/etc/hosts", y el archivo "/etc/sysconfig/network".
Los archivos quedarian de la siguiente forma:

# vim /etc/hosts

127.0.0.1      mi-elastix.mi-dominio.lan     mi-elastix       localhost.localdomain  localhost

# vim /etc/sysconfig/network

HOSTNAME=mi-elastix.mi-dominio.lan

Y para no reiniciar el servidor:

# hostname mi-elastix.mi-dominio.lan

Los nombres mi-elastix y mi-dominio deberan ser reemplazados por los valores correspondientes, de acuerdo al nombre de servidor y dominio en el cual funciona el servidor con Elastix.

Es recomendable añadir un A record al DNS interno, para que los hosts dentro de la red lan puedan resolver mi-elastix.mi-dominio.lan a la dirección IP del servidor Elastix.

Una vez generados los certificados tanto para la autoridad de certificación como para el servidor, se copian los siguientes archivos a la carpeta keys de asterisk:

# cp certs/ca.crt /var/lib/asterisk/keys# cp certs/mi-elastix.mi-dominio.lan.pem /var/lib/asterisk/keys

Se deben dar los permisos de lectura o cambiar de propietario a los archivos copiados a la carpeta keys de asterisk, para que asterisk los pueda cargar:

# chown -R asterisk:asterisk /var/lib/asterisk/keys/*

Luego vamos al explorador, ingresamos al Elastix y habilitamos el acceso al FreePBX no embebido, esto se lo hace yendo a la pestaña Security -> Advanced Options -> Enable access to FreePBX -> ON. Luego en una nueva pestaña del explorador se debe poner lo siguiente:

https://ip-del-elastix/admin

Aqui va a solicitar el usuario y contraseña para ingresar.

Una vez adentro de FreePBX no embebido, se debe ir a la sección (ubicada en la esquina superior izquierda) Tools -> Asterisk SIP Settings. Aquí se pueden editar las configuraciones generales para SIP. En la parte final hay una sección que dice Other SIP Settings, ahi ponemos lo siguiente:

tlsenable=yes
tlsbindaddr=0.0.0.0
tlsdontverifyserver=yes
tlscertfile=/var/lib/asterisk/keys/mi-elastix.mi-dominio.lan.pem
tlscafile=/var/lib/asterisk/keys/ca.crt

Y se aplican los cambios.
Para saber si los cambios se aplicaron correctamente se puede ver que asterisk ahora tambien escucha el puerto TCP 5061.

# netstat -atunp | grep asterisk

Para habilitar el soporte TLS para una extensión, en el campo transport se debe cambiar "udp" por "tls".
Para habilitar el SRTP, se cambia el campo encryption "no" por "yes".
Todo esto se hace en la configuración de la extensión haciendo los cambios detallados al comienzo de la entrada.

Por último se debe cambiar la configuración de los terminales.

Para el caso de los teléfonos Yealink, en la configuración de las cuentas Account -> Cuenta 1 -> Basic -> Transport -> TLS. Y en Account -> Cuenta 1 -> Advanced -> Voice Encryption (SRTP) -> On. También se debe cambiar el puerto de registro, en lugar del 5060 el 5061.

Para el caso de softphones, la configuración es similar. En la mayoria de casos se debe especificar que el puerto para el registro, que es el 5061.

En el caso de tener el BRIA, para el cliente Android, la configuración es sencilla. Para el cliente Windows, nos pide cargar un certificado, este certificado debe ser el mismo certificado generado para el servidor. Aqui es donde entra a trabajar el fqdn y el A record en el DNS, que son utilizados por el BRIA para la verificación del certificado.
Lo interesante del BRIA es que permite hacer video-llamada, y se encripta tanto el audio como el video. Lo malo es que se tiene que comprar una licencia para hacer video-llamadas.

Los teléfonos Grandstream soportan TLS y funcionan correctamente. Lo que no funciona correctamente es el SRTP, pero existe una solución, un parche para asterisk, eso significa que hay que recompilar asterisk, agregando el parche. El parche esta hecho para asterisk 1.8.4, por lo que habría que adaptarlo a la última versión disponible de asterisk para Elastix que es la 11.4. Si el tiempo me da, y se presenta la necesidad, estaré intentando parchar Asterisk, sino espero que alguién lo haga y lo comparta con todos.

Si tienen alguna duda, inquietud o corrección que hacer, estaré atento a lo que me digan.

Con esto espero solucionar el molesto asunto de tener que dar permisos para que se bajen el archivo functions.inc.php de los artículos anteriores.

Comenten que tal les parece el artículo.