Conexión OpenVPN en Windows Server y Mikrotik con migración a Linux

¡Saludos!

En algún momento, cada empresa necesita de manera repentina acceso remoto.
Casi todos los profesionales de TI enfrentan la necesidad de organizar acceso remoto a sus redes.

A mí, como a muchos otros, esta necesidad me llegó con una urgencia del tipo 'ayer'. Después de analizar los pros y los contras, y tras investigar toneladas de información y rascar un poco en la teoría, decidí comenzar la instalación.

Por razones de seguridad, elegí OpenVPN en la siguiente implementación: establecí una máquina virtual en un servidor con sistema operativo Windows Server 2012, también con Windows Server 2012, y en ella, a su vez, un servidor OpenVPN que emitía y firmaba certificados.

Para mayor comodidad, lo llamaremos 'servidor de certificación'. A continuación, tomé el certificado del servidor, lo introduje en Mikrotik, y en el propio enrutador Mikrotik levanté OpenVPN con cuentas y perfiles. También utilicé el servidor de certificación para generar el certificado del cliente.

La implementación, por supuesto, era deficiente, y aunque en ese momento mi experiencia en estos temas era, digamos, insuficiente en cuestiones de seguridad, no era la peor solución.

Esta conexión funcionó durante un tiempo y se me dio una nueva tarea: migrar el servidor de certificación a Linux, manteniendo la conexión con Mikrotik — los clientes no deberían verse afectados.

En ese momento, mis conocimientos sobre Linux se limitaban a Ubuntu 16.04 LTS con interfaz gráfica, que se utilizaba como terminal para conectarse por RDP al servidor de Windows. Es decir, sudo apt-get -f install -y, y nada más.

Tras investigar qué sistema operativo de la familia Linux era más estable y prometedor para mi organización, me decidí por CentOS 7 Minimal.

Primero decidí profundizar en la teoría para entender cómo funcionaba todo esto. Miré tutoriales en el canal www.youtube.com/channel/UCKdRgZWgy42YxoFcTJ30LTA (No es publicidad, simplemente fue el primer canal que encontré). Una chica con una voz agradable me introdujo en los fundamentos de la operación en el sistema elegido.

Para comenzar, abrí Hyper-V en mi computadora, instalé CentOS 7 Minimal, creé un usuario Admin durante la instalación y cerré completamente el ssh para root. Despidiéndome de la hermosa pantalla multicolor, me sumergí en el mundo blanco y negro del terminal.

No creo que tenga sentido describir el proceso de instalación del software; es mejor centrarme en los problemas que surgieron y para resolver los cuales tuve que escribir un pequeño script (lo encontrarás al final. Puedes encontrar información sobre cada una de las utilidades en internet, pero en ese momento, cuando estaba realizando todo esto, ese script aún no existía, todo se hacía por primera vez, a ciegas y al azar).

En el script intenté automatizar la instalación de las utilidades mínimamente necesarias para el servidor, desactivar Selinux, conectar el repositorio Epel, instalar OpenVPN, etc. A continuación el script en sí, es simple, pero se puede utilizar. No lo desglosaré, pero si alguien lo necesita, escríbame y responderé.

Después de usar el script, tendrás un servidor OpenVPN ya configurado, parpadeando con una luz verde.

#!/bin/bash
cd /etc/sysconfig/
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' selinux
sudo setenforce 0
cd /home/Admin
sudo yum update -y
sudo yum install epel-release -y
sudo yum install mc -y
sudo yum install nano -y
sudo cp /usr/share/mc/syntax/sh.syntax /usr/share/mc/syntax/unknown.syntax
sudo yum install chrony -y
sudo systemctl start chronyd
sudo systemctl enable chronyd
sudo yum install net-tools -y
sudo yum install iftop -y
sudo yum install htop -y
sudo yum install lsof -y
sudo yum install dos2unix -y
sudo yum install wget -y
sudo yum install tcpdump -y
sudo yum install openvpn -y
wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.3/EasyRSA-3.0.3.tgz
sudo tar -xvzf EasyRSA-3.0.3.tgz
sudo chown -R Admin:Admin /var/log
sudo chmod 755 /var/log
mkdir /var/log/openvpn
mkdir /etc/openvpn/ccd	
sudo chown -R Admin:Admin /etc/openvpn/ccd
sudo chown -R Admin:Admin /var/log/openvpn
chmod 755 /etc/openvpn/ccd
chmod 755 /var/log/openvpn
echo >/var/log/openvpn/openvpn-status.log
echo >/var/log/openvpn/openvpn.log
sudo chown -R Admin:Admin /etc/resolv.conf
chmod 755 /etc/resolv.conf
echo  nameserver 8.8.8.8 >>/etc/resolv.conf
cd /etc/openvpn/ 
sudo /home/Admin/EasyRSA-3.0.3/easyrsa init-pki
sudo chown -R Admin:Admin /etc/openvpn
chmod 755 /etc/openvpn
 echo  set_var EASYRSA_DN "org" >/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_COUNTRY "RU" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_KEY_SIZE 4096 >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_PROVINCE "LIP" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_CITY "Lipetsk" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_ORG "Cool-Admin" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_EMAIL "xxx.ru" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_OU "Our_ORG" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_REQ_CN "changeme" >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_CERT_EXPIRE 3650 >>/home/Admin/EasyRSA-3.0.3/test
 echo	set_var EASYRSA_DH_KEY_SIZE=2048 >>/home/Admin/EasyRSA-3.0.3/test
sudo /home/Admin/EasyRSA-3.0.3/easyrsa build-ca nopass
sudo /home/Admin/EasyRSA-3.0.3/easyrsa build-server-full Serv nopass
sudo /home/Admin/EasyRSA-3.0.3/easyrsa build-client-full Client1 nopass
sudo /home/Admin/EasyRSA-3.0.3/easyrsa --vars=vars gen-dh
sudo /home/Admin/EasyRSA-3.0.3/easyrsa --vars=vars gen-crl
 mkdir keys
sudo chown -R Admin:Admin /etc/openvpn/keys
chmod 755 /etc/openvpn/keys
sudo cp /etc/openvpn/pki/ca.crt /etc/openvpn/keys
sudo cp /etc/openvpn/pki/dh.pem /etc/openvpn/keys
sudo cp /etc/openvpn/pki/crl.pem /etc/openvpn/keys
sudo cp /etc/openvpn/pki/issued/Serv.crt /etc/openvpn/keys
sudo cp /etc/openvpn/pki/private/Serv.key /etc/openvpn/keys
echo port 443 						>/etc/openvpn/server.conf
echo proto udp					>>/etc/openvpn/server.conf
echo dev tun						>>/etc/openvpn/server.conf
echo ca /etc/openvpn/keys/ca.crt			>>/etc/openvpn/server.conf		
echo cert /etc/openvpn/keys/Serv.crt			>>/etc/openvpn/server.conf
echo key /etc/openvpn/keys/Serv.key		>>/etc/openvpn/server.conf
echo dh /etc/openvpn/keys/dh.pem			>>/etc/openvpn/server.conf
echo crl-verify /etc/openvpn/keys/crl.pem		>>/etc/openvpn/server.conf
echo client-config-dir /etc/openvpn/ccd		>>/etc/openvpn/server.conf
echo topology subnet					>>/etc/openvpn/server.conf
echo server 172.21.0.0 255.255.255.0		>>/etc/openvpn/server.conf
echo route 172.21.0.0 255.255.255.0			>>/etc/openvpn/server.conf
echo push "dhcp-option DNS 8.8.8.8"		>>/etc/openvpn/server.conf
echo push "dhcp-option DNS 8.8.4.4"		>>/etc/openvpn/server.conf
echo keepalive 10 120				>>/etc/openvpn/server.conf
echo persist-key					>>/etc/openvpn/server.conf
echo persist-tun					>>/etc/openvpn/server.conf
echo status /var/log/openvpn/openvpn-status.log	>>/etc/openvpn/server.conf
echo log-append /var/log/openvpn/openvpn.log	>>/etc/openvpn/server.conf
echo verb 2						>>/etc/openvpn/server.conf
echo mute 20						>>/etc/openvpn/server.conf
echo daemon						>>/etc/openvpn/server.conf
echo mode server					>>/etc/openvpn/server.conf
echo user nobody					>>/etc/openvpn/server.conf
echo group nobody					>>/etc/openvpn/server.conf
sudo chown -R Admin:Admin /etc/sysctl.conf
chmod 755 /etc/sysctl.conf
echo net.ipv4.ip_forward=1 >>/etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
sudo systemctl enable openvpn@server
sudo systemctl start openvpn@server
sudo systemctl status openvpn@server

La instalación de OpenVPN no fue del todo exitosa.

Sin saber sobre las peculiaridades de la política de derechos en los sistemas Linux, perdí mucho tiempo estudiando los registros y asignando los permisos requeridos a todos los archivos.

Cuando el botón de OpenVPN se volvió verde, me alegré mucho, pero resultó que eso era solo el comienzo. De manera ingenua, pensé en reemplazar los certificados raíz y el archivo crl.pem, esperando que todo funcionara. Al final, necesité transferir los siguientes archivos del servidor a Windows:

Serv.crt — Certificado del servidor
Serv.key — Clave del servidor
Ca.crt — Certificado raíz
Ca.key — Clave raíz
Crl.pem — Archivo de certificados revocados
Dh.pem — Clave de Diffie-Hellman
Index.txt — Archivo con información sobre los certificados actuales
Serial — también es responsable de la validez de los certificados

También se necesitó la carpeta certs_by_serial, el archivo vars, y todas las claves y certificados de los clientes.
En Mikrotik, los certificados permanecieron en su lugar, por lo que todo funcionó.

Los problemas surgieron cuando intenté revocar el certificado; esto no funcionó en absoluto — el archivo index.txt debía ser convertido a formato unix, y yo no lo hice de inmediato. Utilicé la herramienta dos2unix.

Ahora los certificados podían ser revocados, pero continuaron funcionando sin problemas, porque Mikrotik no sabía que habían sido revocados y necesitaba de alguna manera informarle.

Después de leer las instrucciones y consultar con Alexander ERI (¡muchas gracias!), he levantado un servidor web Apache en el servidor de certificación y he publicado un archivo de certificados revocados. He cerrado completamente el acceso a él, excepto al archivo publicado desde una ip específica.

En el terminal de Mikrotik, en la pestaña /System/Certificates/CRL, he indicado la ruta al crl.pem publicado. Aquí es importante aclarar que Mikrotik acepta solo http y una dirección absoluta para la pestaña CRL, es decir, debe verse aproximadamente así: 127.0.0.1/crl/1.crl
Todo funcionó, al menos para las versiones 6.4.2.x de RouterOS, pero las configuraciones del cliente tenía que crearlas manualmente, lo cual me resultaba molesto y causaba muchos inconvenientes. Cuando, después de una semana, necesitaba crear configuraciones para alrededor de 50 clientes, decidí acelerar este proceso y para ello utilicé un fragmento de script ajeno que encontré en la web.

El script funciona así: después de ejecutarlo, especificamos el "nombre del cliente", respondemos a la pregunta "¿instalar contraseña o no?", después de esto recuperamos el archivo de configuración "cliente.ovpn" ya preparado, con los certificados y configuraciones integradas. Para usarlo, hay que estar en /etc/openvpn. Comentaré las líneas donde es necesario reemplazar la ruta por la propia. También es necesario crear un archivo con las configuraciones del cliente, para que el script las incluya en el proceso de creación de la configuración.

#!/bin/bash
function newClient () {
	echo ""
	echo "Tell me a name for the client."
	echo "Use one word only, no special characters."

	until [[ "$CLIENT" =~ ^[a-zA-Z0-9_]+$ ]]; do
		read -rp "Client name: " -e CLIENT
	done

	echo ""
	echo "Do you want to protect the configuration file with a password?"
	echo "(e.g. encrypt the private key with a password)"
	echo "   1) Add a passwordless client"
	echo "   2) Use a password for the client"

	until [[ "$PASS" =~ ^[1-2]$ ]]; do
		read -rp "Select an option [1-2]: " -e -i 1 PASS
	done

	#cd /etc/openvpn/easy-rsa/ || return
	case $PASS in
		1)
		sudo /home/admin/EasyRSA-3.0.3/easyrsa build-client-full "$CLIENT" nopass
		;;
		2)
		echo "You will be asked for the client password below"
			./easyrsa build-client-full "$CLIENT"
		;;
	esac
# Generates the custom client.ovpn
	cp /etc/openvpn/client-template.txt "$home/home/admin/IT/Temp/$CLIENT.ovpn" 
#Директория в которой хранится файл с настройками клиента.
#Директория, в которой сформируется файл конфигурации
	{
		echo "<ca>"
		cat "/etc/openvpn/pki/ca.crt" #Директория хранения корневого сертификата
		echo "</ca>"

		echo "<cert>"
		awk '/BEGIN/,/END/' "/etc/openvpn/pki/issued/$CLIENT.crt" #Директория с созданным #сертификатом клиента
		echo "</cert>"

		echo "<key>"
		cat "/etc/openvpn/pki/private/$CLIENT.key" #Директория с созданным ключом клиента
		echo "</key>"

} >> "$home/home/admin/IT/Temp/$CLIENT.ovpn" #Директория, в которой сформируется файл #конфигурации

	echo ""
	echo "Client $CLIENT added, the configuration file is available at $home/admin/IT/OVPN/Temp/$CLIENT.ovpn."
	echo "Download the .ovpn file and import it in your OpenVPN client."
exit 0;
}
newClient

Al poco tiempo, una nueva directiva que prohibía el acceso remoto obligó a cerrar también este servidor y la conexión operativa con Mikrotik. Se creó un nuevo servidor OpenVPN para los empleados del departamento de TI, que ahora funciona completamente en CentOS. Pero esa es otra historia.

Extiendo mi enorme agradecimiento a Ivan y Pavel por su ayuda en la redacción del artículo.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster