Un día, harto de tener que abrir puertos y más puertos para cada cosa que quería hacer con el servidor Linux que tengo en casa, se me ocurrió hacer algo para poder conectarme directamente a ésa máquina y tener todos los servicios a mi disposición sin tener que crearlos uno a uno. La solución estaba clara, establecer una VPN contra ese servidor y automáticamente tendría acceso a todos los servicios disponibles. El problema principal a la hora de establecer esta red virtual era que tenía que ser sencilla, rápida de crear y, sobre todo, no necesitar software adicional ya que así podría utilizarla desde cualquier ordenador en cualquier localización. Es más, si me lo montaba bien tendría un sistema perfecto para dar soporte remoto a mis hermanas a través de VNC sin tener que abrirles esos puertos 😉 .
Por defecto todos los equipos Windows traen de serie un cliente VPN que puede contectarse a redes privadas virtuales, pero no de cualquier tipo, sólo PPTP. Podríamos haber escogido otro sistema basado en IPsec o incluso OpenVPN, pero necesitaríamos software adicional además de cerficados en ámbos extremos de la VPN, lo que no cumpliría los requisitos que nos habíamos impuesto. PPTP es un protocolo desarrollado por Microsoft (por eso viene de serie con Windows) y, gracias a eso, ha tardado mucho en haber un cliente (y más aún un servidor) que funcione bajo Linux. No es el más seguro de los protocolos de VPN 😛 pero dejémoslo en que cumple sus funciones.
La idea es, por tanto, montar un servidor PPTP bajo Linux. Una vez tengamos el servidor veremos como conectar tanto desde Linux como desde Windows. Aunque la idea de este artículo parte de un entorno doméstico es completamente aplicable a pequeñas empresas que necesiten dar acceso remoto a sus empleados sin complicarles la vida ni realizar grandes desembolsos en routers dedicados o en un servidor Windows (entendiendo esto como una máquina con algún Windows Server 😉 .
Servidor PPTP bajo Linux
Vamos a enrevesar un poco más nuestro servidor. Para da más versatilidad haremos que la autentificación de los usuarios se realice a través de un servidor Radius que posteriormente podemos utilizar para autenticar cualquier otro servicio que se nos ocurra (ftp, email, hotspot inalámbrico…).
Creo que aún es muy sencillo, vamos a complicarlo más aún. El servidor Radius autenticará, así mismo, contra una base de datos MySQL, con lo que tendremos un sistema muy facil de administrar sin tener que estar tocando archivos de texto para crear usuarios nuevos. El escenario es, por tanto PPTP+Radius+MySQL.
Como software vamos a utilizar:
Para instalar el software, en mi caso, nada más sencillo. Primero instalamos el repositorio yum de PopTop:
rpm -Uvh http://poptop.sourceforge.net/yum/stable/fc7/pptp-release-current.noarch.rpm
Y ya podemos instalar todo el software:
yum --enablerepo=poptop-stable install freeradius freeradius-mysql radiusclient pptp pptpd
Creo que con eso sería suficiente y tendríamos todo lo necesario. Asumimos, por supuesto, que ya tienes MySQL instalado.
Antiguamente era más complicado instalar PopTop ya que había que parchear el kernel, pero hoy en día, si tu núcleo es superior a 2.6.15 (si no lo es, ¿a qué esperas para actualizarlo?), no es necesario este paso. De todos modos, si tuvieses que hacerlo, es totalmente seguro, yo mismo lo hice durante mucho tiempo. En la web de PopTop tienes las instrucciones para hacerlo.
Suponiendo que hemos instalado correctamente todo el software sin ningún problema, ya sólo nos queda configurar todos y cada uno de los pasos que conforman nuestro servidor VPN.
Configurando PopTop
Lo primero que debes hacer es decidir que direccionamiento utilizarás en tu VPN. En mi caso tengo uno independiente de todo lo demás (192.168.3.0), así puedo gestionarlo a mi antojo, permitiendo o denegando lo que se me ocurra de una manera sencilla. A continuación indico los archivos de configuración a toquetear y como tengo los míos.
/etc/pptpd.conf
[osus@servidor ~]# cat /etc/pptpd.conf
option /etc/ppp/options.pptpd
localip 192.168.3.1-5
remoteip 192.168.3.6-10
El parámetro localip tendrá las IP’s que utilizará tu servidor como locales cada vez que reciba una conexión mientras que en remoteip indicarás las que va a dar dinámicamente a los clientes. Tendrás que poner un rango lo suficientemente amplio como para cubrir las posibles conexiones simultáneas que puedas tener.
/etc/ppp/options.pptpd
[osus@servidor ~]# cat /etc/ppp/options.pptpd
name pptpd
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
require-mppe-128
proxyarp
lock
nobsdcomp
novj
novjccomp
nologfd
plugin radius.so
Sería recomendable que consultases las páginas man para saber qué hace cada parámetro.
Como véis, al final de todo indicamos al servidor PPTP que utilice el pluggin para Radius, así que configuremos todo lo relativo a Radius.
Configurando FreeRadius
/etc/raddb/clients.conf
[osus@servidor ~]# cat /etc/raddb/clients.conf
client 127.0.0.1 {
secret = TUCLAVESECRETA
shortname = localhost
}
Debemos indicar, para cada servidor Radius que tenemos, una clave de conexión y el nombre del mismo. La clave deberán utilizarla los clientes radius para consultar al servidor. Lo normal en un entorno como el nuestro es que el servidor Radius sea el mismo donde reside el servidor VPN.
El siguiente archivo es el más importante ya que se indica a FreeRadius que autentifique las peticiones contra un servidor MySQL. Como es muy largo pondré solamente las partes relevantes:
/etc/raddb/radiusd.conf
mschap {
authtype = MS-CHAP
use_mppe = yes
require_strong = yes
}
authorize {
preprocess
mschap
suffix
eap
sql
}
authenticate {
Auth-Type MS-CHAP {
mschap
}
eap
}
preacct {
preprocess
suffix
files
}
accounting {
detail
acct_unique
sql
}
session {
sql
}
En /etc/raddb/sql.conf debes configurar correctamente el acceso a tu base de datos MySQL, servidor, usuario, clave y base de datos que veremos un poco más adelante.
Configurando el cliente Radius
/etc/radiusclient/servers
[osus@servidor ~]# cat /etc/radiusclient/servers
localhost TUCLAVESECRETA
Donde la clave es la misma que pusiste en /etc/raddb/clients.conf y localhost la dirección de tu servidor si es distinto al que tiene el pptpd.
En /etc/radiusclient debes tener el archivo dictionary.microsoft. Creo recordar que tuve algunos problemas con él, por si acaso dejo el que tengo ahora mismo que no es el que venía por defecto.
En /etc/radiusclient/radiusclient.conf asegurate que tienes los siguientes parámetros apuntando a la IP de tu servidor Radius si no es el mismo donde reside el servidor VPN:
authserver localhost
acctserver localhost
Si son distintos a localhost, no te olvides de configurarlos aquí.
Creando la base de datos MySQL
Llegamos al último paso.
Crea una nueva base de datos (create database radius) y un usuario con permisos sobre ella. Recuerda configurar ahora /etc/raddb/sql.conf con estos datos.
Ahora crea la estructura de la base de datos. Con el paquete FreeRadius viene la estructura que necesitas.
mysql radius < /usr/share/doc/freeradius-1.1.3/examples/mysql.sql
El paso que viene a continuación siempre lo ignoran cuando alguien explica cómo configurar FreeRadius contra MySQL y creedme que no es nada intuitivo.
¿Cómo se rellenan las tablas de autentificación?
Buena pregunta Manel 😛 .
- Tabla radcheck: mantiene las cuentas de usuario con los siguientes campos:
- UserName: nombre de usuario.
- Attribute: Password (literalmente, no la clave del usuario sino la palabra Password).
- op: == (dos signos de igual).
- Value: clave del usuario.
- Table radreply: contiene parámetros de inicialización de los clientes que se conectan. Aquí yo configuro las IP’s que quiero dar a determinados clientes por cuestiones de comodidad. Además indico que sólo voy a permitir una conexión simultánea con el mismo usuario.
- UserName: nombre de usuario que estás configurando (según lo introducido en la tabla radcheck).
- Attribute: la palabra Framed-IP-Address ó Simultaneous-Use, según indiques la IP a asignar a ese usuario o el número máximo de sesiones con el mismo nombre.
- op: = (un sólo signo igual)
- Value: 192.168.3.99 (la IP que quieras) ó el número máximo de conexiones simultáneas con el mismo usuario.
- Table usergroup: agrupa los usuarios en grupos.
- UserName: nombre de usuario
- GroupName: nombre de grupo.
La tabla radact contiene el log de actividad del servidor, sesiones iniciadas, duración, etc.
Últimos pasos
Recuerda que debes abrir en tu router y/o firewall el puerto 1723 para que permita conexiones entrantes ya que es el usado por el protocolo PPTP.
Aunque como veremos más adelante podemos auditar las conexiones al servidor Radius (y por ende al servidor VPN) puede ser interesante tener un mecanismo de aviso de que un cliente se ha conectado. Una forma de hacerlo es consultando las interfaces de red disponibles en el servidor (ifconfig), habrá tantos pppX como usuarios activos. Pero hay otro método que te permite recibir, por ejemplo por email, un aviso cada vez que un usuario conecta o desconecta.
Cada vez que se levanta una interfaz ppp se ejecuta el script /etc/ppp/ip-up.local con todos los parámetros relativos a esa conexión, ip remota, local, interfaz… Igualmente cuando se desconecta se lanza /etc/ppp/ip-down.local. Solo debemos adaptar este script a nuestras necesidades. Estos scripts reciben todos los parámetros necesarios para identificar al usuario. Haríamos algo así, por ejemplo para ip-up.local.
#!/bin/sh
if [ "$5" == "192.168.3.10" ]
then
cliente="pepito"
fi
echo "Conexion VPN
Interfaz: $1
VPN Local: $4
VPN Remota: $5
IP Remota: $6
1: $1
2: $2
3: $3
4: $4
5: $5
6: $6
" | mail -s "Conexion VPN - $cliente" [email protected]
De este modo recibirías un email cada vez que un usuario levanta un tunel VPN con tu servidor y sabrías qué ip tiene el usuario y, si le has otorgado una IP fija en la configuración de Radius, sabrás qué usuario es, en este caso “pepito“.
Con ip-down.local harías un script semejante sólo que en vez de Conexión VPN en el asunto del email pondríamos Desconexión VPN. Los parámetros son exactamente los mismos.
Estos scripts podemos aprovecharlos también para crear/modificar/eliminar determinadas rutas en función de los túneles creados.
El propio paquete pptpd te habrá instalado el script de inicio necesario, en mi caso /etc/init.d/pptpd. Sólo debo añadirlo a la secuencia de arranque del runlevel de mi servidor y automáticamente estará siempre disponible el servicio.
En teoría, todas las vpn’s que se hagan contra el servidor tienen enrutamiento entre sí, es decir, podrías llegar desde un cliente a otro pasando por el servidor sin toquetear nada más. Digo en teoría porque esa es la función del parámetro proxyarp que configuramos hace un rato. Puede que este enrutamiento no sea suficiente y que necesites que los clientes VPN puedan acceder a otras subredes de tu infraestructura. Puedes hacerlo como quieras, incluso configurar un bridge, pero para estas cosas nada mejor que iptables.
Supongamos un escenario en el que tenemos una lan local de la que forma parte nuestro servidor (direccionamiento 192.168.0.0) y la nueva red que creamos para las VPN’s (direccionamiento 192.168.3.0). Para permitir el enrutamiento completo entre las dos redes haríamos algo como:
#!/bin/sh
echo 1 >/proc/sys/net/ipv4/ip_forward
LAN="192.168.0.0/16"
VPN2="192.168.3.0/24"
iptables -A FORWARD -s $LAN -d $VPN2 -j ACCEPT
iptables -A FORWARD -s $VPN2 -d $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -d $VPN2 -j MASQUERADE
Sencillo. Si sólo quisiésemos que ciertos usuarios accediesen a la red local modificaríamos la variable VPN2 por la IP que radius le da al usuario.
FreeRadius desde un entorno web, dialup_admin
Vale, es cierto, es un auténtico coñazo gestionar FreeRadius y todos sus parámetros, así que, que mejor que un sencillo entorno web para la gestión de usuarios y visualización de actividad y log del sistema. Esta utilidad es dialup_admin. No me detendré en su instalación ya que creo que se sale fuera de este artículo y, además, es una sencilla aplicación web sin mucha dificultad.
Con esta herramienta será mucho más sencillo crear usuarios y sus propiedades y hacer un seguimiento de los que están conectados, periodos de conexión que han tenido, etc.
Estableciendo la VPN desde Windows
Sencillísimo. Desde Conexiones de red, se crea una conexión nueva, escoges Conectarse a la red de mi lugar de trabajo y prácticamente sólo queda introducir el host o IP de tu sevidor VPN y conectarse. Recomiendo desmarcar la opción Usar puerta de enlace predeterminada en la red remota en las propiedades de esta nueva conexión, Funciones de red, Protocolo TCP/IP, Opciones avanzadas, de otro modo todo el trafico de Internet normal lo harás a través de la VPN.
Si todo va bien conectarás a tu servidor y tendrás acceso al mismo como si estuvieses en tu propia red local.
Estableciendo la VPN desde Linux
Desde Linux es un pelín más complicado ya que, como casi siempre, hay que hacer la configuración a mano. Existe una utilidad gráfica que permite crear las conexiones de un modo similar a Windows, pero prefiero explicar cómo hacerlo desde la consola por si tu máquina no tiene entorno gráfico.
[osus@servidor ~]# cat /etc/ppp/options.pptp
lock
noauth
refuse-eap
refuse-chap
refuse-mschap
nobsdcomp
nodeflate
Ahora indicamos el usuario y la contraseña que se utilizará para conectar. IdentificadorRed será el nombre que le demos a la conexión, puede ser lo que quieras.
[osus@servidor ~]# cat /etc/ppp/chap-secrets
usuario IdentificadorRed clave *
Ahora creamos la configuración para la conexión que vas a crear con el IdentificadorRed que comentamos antes. En TUIP debes poner el host o ip de tu servidor VPN.
[osus@servidor ~]# cat /etc/ppp/peers/IdentificadorRed
remotename IdentificadorRed
linkname IdentificadorRed
ipparam IdentificadorRed
pty "pptp TUIP --nolaunchpppd "
name usuario
require-mppe
require-mschap-v2
refuse-eap
refuse-pap
refuse-chap
refuse-mschap
#demand
holdoff 5
persist
maxfail 0
ipcp-accept-remote
ipcp-accept-local
noauth
192.168.3.1:192.168.3.254
Aquí hay dos opciones interesantes:
- persist: vuelve a crear el tunel automáticamente si se cortase por alguna razón de manera que permanece siempre activo.
- demand: crea automáticamente el tunel cuando se accede a la IP del servidor o a alguna otra que esté enrutada a través de este tunel, mientras no se necesite permanece inactivo. Obviamente no debe estar en modo persist, de otro modo estará siempre activa.
Finalmente creamos un sencillo script de arranque para poder lanzarla automáticamente o simplemente para no tener que recordar los parámetros.
[osus@servidor ~]# cat /etc/init.d/IdentificadorRed
#!/bin/sh
case "$1" in
start)
echo -n "Iniciando VPN IdentificadorRed "
echo
touch /var/lock/subsys/pptpd
/usr/sbin/pppd call IdentificadorRed logfd 1 updetach &
;;
stop)
echo -n "Parando VPN IdentificadorRed: "
echo
kill -TERM `head -n 1 /var/run/ppp-IdentificadorRed.pid`
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0
Y eso es todo amigos. Me ha costado bastante más de lo previsto escribir este artículo ya que a medida que lo iba redactando me iba saltando nuevos recuerdos sobre detalles que se deberían nombrar.
Tened en cuenta que mi experiencia con PPTP se remonta cinco años atrás con lo que puede ser que algún detalle haya cambiado los últimos años. Después de aquel primer servidor VPN el año pasado migramos el sistema operativo a Centos5 y al configurar de nuevo el servidor VPN dejamos prácticamente todos los parámetros como estaban. No creo que tengáis ningún problema a la hora de solucionar algún pequeño detalle que pueda surgir.