4 de mayo de 2016

OpenVPN: Conectando pfSense con Endian UTM

Últimamente el tema va de firewalls y conexiones VPN, en cuanto al blog se refiere, y en este caso se trata de conectar una máquina pfSense contra un Endian UTM utilizando OpenVPN ya que ambas distribuciones lo incorporan por defecto. En mi caso, pfSense es una distribución que conozco hace más tiempo pero Endian hasta hace poco no he tenido el gusto de conocerlo y no me ha decepcionado.

Endian es un proyecto Open Source que nació en el año 2003 por un grupo de profesionales y entusiastas de las telecomunicaciones y Linux que tenían una idea fija: "Desarrollar un Gestor Unificado de Amenazas (UTM) Open Source que fuese el más poderoso del mundo y fácil de usar" (Traducción libre de lo que aparece en la historia de la compañia).

En nuestro caso se trata de montar un servidor OpenVPN en un Endian y para ello utilizaré la versión 3.0.5-beta1 pero el proceso es el mismo para la anterior release (3.0.0), ambas disponibles desde la página de descarga de la Comunidad. El cliente de pruebas será pfSense pero a diferencia de la entrada anterior, utilizaré la versión 2.3 que ha sido publicada a principios de mes pasado.


En esta nueva RC de pfSense hay un cambio generacional que incorpora muchas novedades como la actualización de la GUI a una interfaz Bootstrap dinámica con AJAX mucho más moderna, la gestión de paquetes ahora es controlada completamente por pkg favoreciendo la actualización por partes del software, NGINX como servidor Web, PHP 5.6, y otros tantos cambios como la eliminación del servidor VPN PPTP, el cifrado WEP para los AP, TLS 1.0 para el servidor Web, cifrado DES para conexiones IPsec, etc. Todos los detalles en el changelog. A lo que venimos...

En el menú superior del Endian, vamos a la parte de VPN y tras habilitar el servidor seleccionamos como método de autenticación Certificado X.509 y para el certificado dejamos la opción Usar certificado seleccionado. Al ser de una máquina de pruebas utilizaré tanto la CA como el certificado por defecto para las configuraciones, en un entorno real habría que crear nuestra propia CA y el certificado asociado a la misma.


Tras guardar y aplicar cambios, especificamos la IP en la que escuchará el servicio y el puerto, que por defecto es el 1194, asi como el tipo de interfaz: TUN o TAP y el protocolo. En mi caso son interfaces tipo TUN y sólamente hay que especificar la red para la VPN: 10.8.0.0/24.


Incluso tenemos opciones avanzadas con las que configurar rutas, DNS, nombre de dominio así como otras opciones para nuestros clientes.


Tras hacer todas las configuraciones y volver a guardar y aplicar cambios (lo pongo en negrita porque son apartados de configuración independientes), tenemos nuestro servidor OpenVPN listo y funcional.


Ahora pasaremos a crear el certificado para el cliente y para ello en el menú de la izquierda accedemos al apartado Certificados. Como comentaba antes, por defecto nos crea una CA y un certificado que es usado para el servidor HTTPS y es el mismo que voy a utilizar para el servidor OpenVPN. En este punto, cabe destacar que por defecto también nos crea una Lista de Revocación de Certificados (CRL) por si se da el caso que necesitemos dar de baja algún certificado.


Pulsando en Añadir nuevo certificado pasamos a un formulario en el que escribiremos los datos del propietario del mismo, nuestro cliente pfSense, siendo imprescindibles los campos: Nombre común y la contraseña que protege la lectura del certificado en formato PKCS12.


Una vez creado el certificado, en la lista de los mismos tenemos una serie de herramientas en la columna Acciones. De izquierda a derecha: La primera de ellas nos muestra información del certificado, la segunda nos descarga solamente el certificado en formato PEM, la tercera en formato PKCS12 que es la que nos interesa ya que también incluye el certificado de la CA y la clave privada, con la cuarta eliminamos la clave privada y con la última revocamos el certificado.


Tras haber generado el certificado para nuestro cliente tenemos que prepararlo para poder utilizarlo en nuestro pfSense. Como había comentado, nos descargaremos el certificado en formato PKCS12 y extraeremos de él los datos de la CA, el certificado y la clave privada en formato PEM con el comando:

openssl pkcs12 -in pfSense.home.labcert.p12 -out pfSense.home.labcert.pem -nodes


Después de extraer los datos del certificado descargado del servidor, pasamos a realizar la configuración en el cliente. Para ello accedemos a System > Cert. Manager y lo primero que tenemos que hacer, como ya hicimos en la entrada anterior, es crear la CA de nuestro Endian en el pfSense.


Pulsamos en Add y entramos en el formulario para importar un certificado ya creado: Import an existing Certificate Authority. Damos un nombre descriptivo al certificado y en el campo Certificate data pegamos los datos del certificado de la CA.


En mi caso, el certificado PEM que hemos extraido del Endian me lo ha estructurado de la siguiente manera: Cert. cliente, Cert. CA, Key cliente. Con una serie de campos antes de los bloques BEGIN/END con los datos del certificado o de la clave privada según sea el caso.


Clave privada solo hay una asi que con esa no hay problemas y para los certificados solo tenemos que fijarnos en el campo subject que indica el propietario del mismo ya que el issuer siempre va a ser igual, la CA de nuestro Endian.

Una vez guardados cambios, podemos pasar a importar el certificado y la clave privada para el cliente OpenVPN. Para ello desde el mismo administrador de certificados, pulsamos en la pestaña Certificates y en Add para crearlo dándole un nombre descriptivo y copiando los datos del certificado y de la clave privada del mismo.


Tras guardar cambios, ya podemos pasar a configurar el cliente desde el menú superior accediendo a VPN > OpenVPN y después en la pestaña Clients. El modo de servidor es SSL/TLS, el protocolo UDP, tipo TUN para la interfaz vitual y la WAN como la interfaz física que queremos utilizar del firewall. Además de ello, tendremos que especificar la dirección IP y el puerto donde tratará de conectarse el cliente.


Le damos un nombre descriptivo a la configuración del cliente y pasamos a la parte de autenticación.


Como en nuestro caso se realiza a través de certificados, obviamos los campos Username y Password y nos centramos en la parte de Cryptographic Settings. Tenemos que deshabilitar la autenticación TLS dado que no está configurada en el servidor, el certificado de la CA es el del Endian que es el único que tenemos y el certificado del cliente es el que acabamos de crear.


Haciendo un poco de memoria de la entrada anterior, OpenVPN por defecto utiliza el cifrado Blowfish por lo que también deberemos cambiarlo en la configuración del cliente.


Ya por último cambiar el tipo de compresión a Enabled with Adaptive Compression.


Una vez guardados los cambios se establece la conexión entre los peers y si todo ha salido correctamente deberíamos verlo en Estado > Conexiones VPN de nuestro Endian.


Bien, una vez he tenemos conexión entre las máquinas vamos a pasar a ver los logs para corregir errores o alertas. Revisando el log del servidor vemos como se inicializa el servicio y nos encontramos la primera advertencia:

WARNING: file "/var/efw/vpn/ca/certs/192.168.173.243key.pem" is group or others accessible.


Nos conectamos por SSH al Endian y nos dirigimos a la ruta en cuestión, /var/efw/vpn/ca/certs, y comprobamos que efectivamente la clave privada tiene permisos de lectura y escritura para el propietario, root, pero también de lectura para el grupo y el resto.


El servicio se ejecuta con el usuario openvpn y si tratamos de cambiarlo a nobody se ejectuta pero da unos errores a la hora de borrar archivos temporales. Como el usuario openvpn tiene las mismas limitaciones que nobody, he cambiado el propietario y el grupo y le he quitado el permiso de lectura al grupo y al resto.


Tras reiniciar el servicio con el comando jobcontrol restart openvpnjob, el servicio se ejectuta correctamente sin dicha advertencia pero salta la notificación de la ejecución de scripts personalizados y por defecto está en 3 al igual que pasaba en pfSense.


Cambiando dicho valor a 2 en el archivo de plantilla /etc/openvpn/openvpn.conf.tmpl sigue apareciendo el mensaje pero no permitiremos el pase de contraseñas como variables de entorno.


En el log del pfsense nos aparece una advertencia ya conocida de la entrada anterior:

WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.


Para quitar dicha advertencia deberemos añadir en la configuración avanzada de nuestro cliente la opción: ns-cert-type server.


Ya para ir acabando, en ambos equipos aparecen mensajes de alerta informando que no hay concordancia entre el tamaño máximo de paquetes (MTU) tanto de la interfaz virtual, tun_mtu, como del total del enlace, link_mtu. La advertencia en cuestion en el lado del clientes es:

WARNING: 'link-mtu' is used inconsistently, local='link-mtu 1542', remote='link-mtu 1574'
WARNING: 'tun-mtu' is used inconsistently, local='tun-mtu 1500', remote='tun-mtu 1532'.


Se trata de una advertencia que comentan en la documentación oficial (Al final del todo) de Endian, pero que me queda con la mosca detrás de la oreja... En ella dicen que utilizan la directiva mssfix de OpenVPN para anunciar a los clientes tamaño máximo de MTU que deben utilizar, que por defecto y por compatibilidad se establece en 1500 bytes.

"The Endian UTM Appliance sets a limit of 1450 bytes to the size of the VPN’s MTU, to prevent problems with the common MTU value used by the ISP, which is 1500."

Pero revisando el archivo de plantilla que utiliza Endian para generar el fichero de configuración, /etc/openvpn/openvpn.conf.tmpl, nos encontramos la directiva tun-mtu-extra con valor 32.


Para solucionar dicha alerta, en el lado del servidor podemos comentar simplemente la línea dentro del fichero de configuración que amplia el tamaño de los paquetes.


O en el lado del cliente podremos utilizar las directivas tun-mtu y tun-mtu-extra para que haya concordancia entre el tamaño que espera el servidor y el que tiene configurado el cliente.


En cualquier caso, tanto si modificamos la configuración del servidor como del cliente deberíamos de tener conexión entre las máquinas y sin ningún error o advertencia en los logs.


Un saludo, Brixton Cat.