Es posible que alguna vez hayas querido poder acceder a un dispositivo de tu casa cuando estás fuera, ya sea una Raspberry Pi, una webcam, o incluso el smartplug que controla tu tostadora…
Para solucionar este problema puedes tomar varios caminos.
Usar un servicio de DNS dinámica como no-ip
Ventajas:
- No requiere invertir dinero o muy poco
- Es muy fácil de implementar
Inconvenientes:
- Si usas una cuenta gratuita, tendrás que reactivarla todos los meses. Se soluciona pagando 😉
- Tendrás que abrir y redirigir puertos en tu router para cada dispositivo/servicio que quieras acceder. Esto es un poco peligroso, porque abre potenciales puertas a hackers que quieran quemar tus tostadas
- Si cambias de ISP/Router, tienes que recordar abrir todos los puertos en tu nuevo router
- Muchos de los datos que intercambies pueden ser interceptados
Crear nuestro propio servidor VPN
La otra solución, de la que hablaremos aquí, se trata de crear nuestro propio servidor VPN, en mi caso he aprovechado mi Droplet de DigitalOcean (Ubuntu 16.04).
Ventajas:
- Todos los equipos conectados a la VPN se podrán comunicar entre si sin necesidad de abrir puertos y sin importar donde como estén conectados a Internet.
- Se reducen los riesgos de seguridad, aunque no desaparecen.
- Todas las comunicaciones son cifradas, nadie podrá ver lo que estás haciendo, o casi…
Inconvenientes:
- Necesitas un servidor con buen ancho de banda. Si tienes fibra óptica puedes usar una Raspberry Pi
- Hay que manejar certificados, que se deben instalar en cada dispositivo
- Es necesario instalar un cliente VPN en cada dispositivo
- En el caso de DigitalOcean, tienes límites de transferencia de datos mensual.
Téngase en cuenta que la intención no es acceder a Internet a través de la VPN, puesto que tengo un droplet muy limitado, con tan solo 1000 GB de cuota mensual, y porque lo único que quiero es una red «local» virtual. Si quieres una VPN para acceder a Internet puedes usar servicios de pago como IPVanish.
Este post ha sido realizado basado en mi experiencia con DigitalOcean, aunque no puedo garantizar que sea 100℅ válido para otros proveedores, estoy seguro de que mayormente los pasos serían los mismos en cualquier servidor con Ubuntu 16.04.
Instalar servidor OpenVPN
Nos conectamos por ssh a nuestro servidor e instalamos OpenVPN y easy-rsa. El primero es el servidor VPN en si y el segundo es una herramienta que usaremos para generar nuestros certificados de cliente y servidor con mas facilidad.
$ sudo -i
# apt-get update
# apt-get install openvpn easy-rsa
Generar Autoridad de Certificación (CA)
OpenVPN usa conexiones seguras TLS/SSL, lo que hace que nuestros datos estén a salvo de mirones, pero añade complejidad a la hora de configurar el servidor y los clientes.
Los datos son cifrados usando certificados que deben ser instalados en el servidor y los clientes. Todos los certificados deben ser firmados por una Autoridad de Certificación (CA). En nuestro caso, nuestro servidor será nuestro CA, por lo que comenzamos generando nuestro CA.
Lo primero es configurar las variables de nuestro CA, por lo que abrimos el fichero /etc/openvpn/easy-rsa/vars
:
# cp -r /usr/share/easy-rsa/ /etc/openvpn
# cd /etc/openvpn/easy-rsa
# nano vars
Y editamos esta sección para tenga nuestros datos:
export KEY_COUNTRY="ES"
export KEY_PROVINCE="TF"
export KEY_CITY="Los Llanos de Aridane"
export KEY_ORG="LinuxGnuBlog"
export KEY_EMAIL="linuxgnublog@gmail.com"
export KEY_OU="LinuxGnuBlog"
En el mismo fichero, un poco más abajo, editamos el KEY_NAME, en este caso lo llamaremos «server», por simplicidad:
export KEY_NAME="server"
Ahora que tenemos nuestra variables rellenadas, podemos guardar y cerrar el fichero y proceder a generar nuestro CA:
# source vars
# ./clean-all
# ./build-ca
El último comando hará varias preguntas a las que hay que responder simplemente pulsando ENTER, pues las respuestas ya las pusimos en las variables.
Generar los certificados y claves del servidor
# ./build-key-server server
Este comando hará varias preguntas a las que hay que responder de nuevo pulsado ENTER, salvo las dos últimas, que son de si o no, en las que hay que reponder pulsando ‘y’ y luego ENTER.
Certificate is to be certified until Jan 13 19:54:34 2027 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Generaremos clave Diffie-Hellman:
# ./build-dh
Copiamos las claves y certificados:
# cp keys/ca.crt keys/ca.key keys/server.crt keys/server.key keys/ta.key keys/dh2048.pem ..
Configurar el servidor
En esta parte vamos a hacer algo que normalmente no se suele hacer. OpenVPN puede funcionar sobre UDP o TCP, el primero es más rápido, pero si nuestra conexión a Internet es de mala calidad, no podemos usarlo debido a la pérdida de paquetes.
Por eso voy a explicar como crear un servidor UDP y otro TCP, si solo quieres UDP, no sigas los pasos para TCP o viceversa.
Antes de nada creamos este directorio, que nos permitirá especificar IP estáticas para algunos clientes (por ahora no lo usaremos):
# mkdir /etc/openvpn/static-clients
Servidor UDP
Creamos el fichero de configuración:
# nano /etc/openvpn/udp.conf
Ponemos los siguientes parámetros dentro:
port 1194 proto udp dev tun0 ca ca.crt cert server.crt key server.key dh dh2048.pem cipher AES-128-CBC auth SHA256 topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt client-config-dir /etc/openvpn/static-clients push "route 10.8.1.0 255.255.255.0" push "route 0.0.0.0 0.0.0.0 vpn_gateway 999" client-to-client keepalive 10 120 comp-lzo user nobody group nogroup persist-key persist-tun status openvpn-udp-status.log verb 3
Servidor TCP
Creamos el fichero de configuración:
# nano /etc/openvpn/tcp.conf
Ponemos los siguientes parámetros dentro:
port 1195 proto tcp dev tun1 ca ca.crt cert server.crt key server.key dh dh2048.pem cipher AES-128-CBC auth SHA256 topology subnet server 10.8.1.0 255.255.255.0 ifconfig-pool-persist ipp.txt client-config-dir /etc/openvpn/static-clients push "route 10.8.0.0 255.255.255.0" push "route 0.0.0.0 0.0.0.0 vpn_gateway 999" client-to-client keepalive 10 120 comp-lzo user nobody group nogroup persist-key persist-tun status openvpn-tcp-status.log verb 3
Configurar el firewall
Los droplets de DigitalOcean vienen con ufw activado por defecto, por lo que si no le indicamos que queremos abrir los puertos que necesita OpenVPN, no podemos conectarnos:
Para abrir los puertos UDP:
# ufw allow 1194/udp
# ufw allow out on tun0
# ufw allow in on tun0
Para abrir los puertos TCP:
# ufw allow 1195/tcp
# ufw allow out on tun1
# ufw allow in on tun1
Y en el caso de que hayas decidido ir a por los dos, también deberemos admitir comunicación entre la dos redes, pues los clientes UDP estarán en una red diferente a la de los clientes TCP:
# ufw route allow in on tun0 out on tun1 to any
# ufw route allow in on tun1 out on tun0 to any
Ahora editamos el /etc/sysctl.conf
:
# nano /etc/sysctl.conf
Y buscamos la siguiente línea y la descomentamos:
net.ipv4.ip_forward=1
Iniciar OpenVPN
Por último, solo queda reiniciar nuestro servidor VPN:
# systemctl daemon-reload
# systemctl restart openvpn
# exit
Conectar un cliente
Ya estamos listos para empezar a conectar nuestros clientes a la VPN, para ello tendremos que generar un certificado para cada uno en usando el servidor y luego instalarlo en cliente.
Generar certificados para el cliente
Nos conectamos por ssh a nuestro servidor y tecleamos lo siguiente:
$ sudo -i
# cd /etc/openvpn/easy-rsa/
# source vars
# ./build-key elias-pc
De nuevo. este comando hará varias preguntas a las que hay que responder de nuevo pulsado ENTER, salvo las dos últimas, que son de si o no, en las que hay que reponder pulsando ‘y’ y luego ENTER.
Certificate is to be certified until Jan 13 20:12:43 2027 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Copiamos los certificados a un lugar desde el que poder recuperarlos fácilmente desde nuestro cliente:
$ sudo -i # cp keys/ca.crt /tmp # cp keys/elias-pc.{key,crt} /tmp # chown elias:elias /tmp/ca.crt
# chown elias:elias /tmp/elias-pc.{key,crt}
Instalar OpenVPN
A partir de ahora, todos los comandos son en el lado del cliente, como super usuario, no te confundas y los introduzcas en tu servidor, porque vas formar un lío curioso.
En el lado del cliente también tendremos que instalar OpenVPN, solo que en este caso lo configuraremos para funcionar como cliente en lugar de como servidor.
# apt-get update
# apt-get install openvpn
Instalar certificados en el cliente
Recuperamos los certificados desde el servidor
# scp -P PUERTO-SSH USUARIO@IP_SERVIDOR:/tmp/ca.crt /etc/openvpn/
# scp -P PUERTO-SSH USUARIO@IP_SERVIDOR:/tmp/elias-pc.{key,crt} /etc/openvpn/
Creamos el archivo de configuración:
# nano /etc/openvpn/elias-pc.conf
Escribimos lo siguiente:
client route-nopull route 10.8.0.0 255.255.255.0 route 10.8.1.0 255.255.255.0 dev tun0 proto udp remote IP-SERVIDOR 1194 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert elias-pc.crt key elias-pc.key cipher AES-128-CBC auth SHA256 remote-cert-tls server comp-lzo verb 3
Conectar cliente
Tan simple como ejecutar:
# systemctl daemon-reload
# systemctl restart openvpn
Y ya está todo listo, a estas alturas deberías tener tu servidor funcionando y tu pc conectado, si quieres conectar mas equipos solo tienes que repetir los pasos para conectar un cliente.
Liamngls
Interesante 🙂
Elías R.M.
Muchas gracias Liamngls
Saludos
victorhck
muy bueno!
Elías R.M.
Muchas gracias victorhck
Saludos
Pedro
Artículo muy completo, me ha sido de gran utilidad. Muchas gracias y espero sigas publicando artículos de esta calidad.
Elías R.M.
Muchas gracias Pedro,
Haremos todo lo posible por mantener el nivel o, mejor aun, incrementarlo 😉
Saludos
Roberto
Muy bueno y detallado. Gracias!
Elías R.M.
Muchas gracias Roberto
Saludos
Juan
No voy a comprar en DigitalOcean, gracias. A otra cosa, mariposa.
Elías R.M.
Hola Juan,
Aunque el post se centra en DigitalOcean, el proveedor que yo uso y mejor conozcono, no deja de ser un servidor con Ubuntu 16.04.
Estoy seguro de que esta información es válida en un 90℅ para cualquier servidor de esas características, como Linode o cualquier VPS.
Gracias por tu comentario.
Saludos
Doro
Buen artículo,
Hecho en falta forzar la versión mínima del certificado para que no hagan downgrade y limitar los chiper-suites. Hago un pequeño aporte relacionado con este asunto:
https://doro.es/configurar-servidor-openvpn-con-tlsv1-2-chroot-hardening/#Forzar TLSv1.2 o superior
Saludos.
Elías R.M.
Hola Doro,
Muchas gracias por tu comentario y aporte, actualizaré el post desde que tenga un rato.
Saludos
Emanuel Almonte
Excelente aporte, un saludo; muchas gracias por tu tiempo.
Tengo una duda; el direccionamiento IP que demuestras en el archivo de configuración /etc/openvpn/udp.conf y /etc/openvpn/tcp.conf
¿son las direcciones de mi red o son standard?
Muchas gracias!!
Zagur
Bueenas!
Interesante el artículo, aún así, no se si conocéis StrongSwan… Sirve para crear una VPN en GNU/Linux con la implementación de IPsec cosa que le da más seguridad aún. Tiene buena pinta, hace meses probando el tema este de las VPN lo estuve configurando. Como que ya no tengo blog (por el momento) no hice ningún tutorial, aún así, me sirvió mucho este tutorial y la documentación de StrongSwan por si os lo queréis mirar. Siempre va bien tener alternativas para todo 😛 https://clouding.io/kb/configurar-servidor-vpn-l2tpipsec-psk-con-ubuntu/
Un saludo,
Zagur
José Miguel
Gracias por el aporte, todos son bienvenidos.
Saludos.