VPN Server v 10 minutách

1 Bezpečnost, Windows, Linux

Správné nastavení a zprovoznění VPN serveru nemusí být vůbec náročné. Použitý skript vygeneruje správnou konfiguraci a také následně dokáže spravovat uživatele a jejich certifikáty.

VPN Server v 10 minutách

VPN server je možné rozjet na jakémkoli fyzickém či virtuálním stroji, který má veřejnou IP adresu. Navrhovaný skript je vyzkoušen na Debianu ve virtuálním stroji na Google Cloudu.

Zprovoznit si vlastní VPN server může být docela oříšek. Provést veškerou konfiguraci správně, aby nebyl zranitelný a fungoval co možná nejlépe. Naštěstí už si tuto práci někdo dal a zveřejnil jednoduchý bash skript, který nainstaluje a správně nakonfiguruje OpenVPN.

Stačí si jej stáhnout a spustit. Skript se doptá na základní informace, nainstaluje OpenVPN, vytvoří základní konfiguraci a přidá prvního uživatele. Pokud je skript spuštěn opakovaně, automaticky detekuje již nainstalovaný OpenVPN server a umožní přidávat či odebírat další uživatele.

Co byste měli ve wizzardu odpovídat

Ze začátku se skript pokusí detekovat IP adresu, případně se na ni doptá či ověří. Následně se vybírá protokol, který by se měl použít. Doporučené je UDP a mělo by to tak i zůstat. Následně se už ptá pouze na port a DNS servery a poté na údaje o prvním uživateli. Vše ostatní včetně vygenerování serverových certifikátů skript provede za nás. Jak úžasné!

Proč použít UDP pro VPN? Protože VPN vytvoří pouze tunel, tj veškerý TCP provoz TCP zůstane, pouze půjde přes UDP tunel. Pořád bude zajištěn spolehlivý přenos.  Kdyby i VPN byla v TCP módu, dochází vlastně ke dvojí kontrole. Protože TCP paket je zaobalen v dalším TCP paketu.

Jak zprovoznit druhý server a proč to vůbec chtít?

V práci jsme chtěli zprovoznit VPN tunel přímo v Mikrotik routeru. Jenže ten nepodporoval UDP, jen TCP, ani autentizaci pomocí SHA512, jen SHA-1, ani TLS pro kontrolní kanály či CRL. Chtěli jsme tedy mít nejlépe nakonfigurovanou VPN pro zaměstnance, a o něco méně pro routery. Protože ty jsou na síti, které se důvěřuje více než veřejným Wi-Fi v hotelech apod.

Pro zprovoznění druhého serveru stačí zkopírovat soubor /etc/openvpn/server/server.conf do stejné složky a pojmenovat jej třeba router_server.conf. Původní VPN server lze restartovat spuštěním sudo systemctl restart openvpn-server@server.service  a nový pro routery pomocí sudo systemctl restart openvpn-server@router_server.service. Oba servery sdílejí stejné úložiště, skriptem je možné přidávat či odebírat certifikáty jak pro uživatele tak pro routery.

Poté je ještě potřeba upravit lokální VPN firewall pomocí IP Tables. Kód níže je nutné přidat do souboru etc/systemd/system/openvpn-iptables.service. Následně přegenerovat strom závislostí a konfigurací pomocí sudo systemctl daemon-reload a restartovat lokální OpenVPN firewall příkazem sudo systemctl restart openvpn-iptables.service.

# Následující obsah je do souboru nutné přidat, v původním obsahu je třeba upravit IP rozsah z /24 na /25
# Druhý VPN server běží na TCP a portu 443, a toto je nutné přidat ExecStart=/usr/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.128/25 ! -d 10.8.0.128/25 -j SNAT --to __YOUR_IP_HERE__ ExecStart=/usr/sbin/iptables -I INPUT -p tcp --dport 443 -j ACCEPT ExecStart=/usr/sbin/iptables -I FORWARD -s 10.8.0.128/25 -j ACCEPT ExecStart=/usr/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT ExecStop=/usr/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.128/25 ! -d 10.8.0.128/25 -j SNAT --to __YOUR_IP_HERE__ ExecStop=/usr/sbin/iptables -D INPUT -p tcp --dport 443 -j ACCEPT ExecStop=/usr/sbin/iptables -D FORWARD -s 10.8.0.128/25 -j ACCEPT ExecStop=/usr/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

Vlastní úpravy skriptu – jen doporučení

Pro naše interní použít jsem ve skriptu provedl drobné změny. První z nich je zakázání operace pro odinstalování OpenVPN serveru, která je nabídnuta při spuštění skriptu. Následující 2 řádky jsou vloženy před tento řádek: https://github.com/Nyr/.../openvpn-install.sh#L507

echo "Removing is now prohibited - exited in script before executing"
exit
# Hned poté následuje tento řádek
read -p "Confirm OpenVPN removal? [y/N]: " remove

Zaheslování uživatelského certifikátu

Další úpravou je možnost zaheslovat vygenerovaný certifikát při přidávání nového uživatele. Skript se prvně zeptá, zda certifikát má být zaheslován, protože Mikrotik zaheslované certifikáty nebere. Následující kód je vložen namísto tohoto řádku: github.com/Nyr/.../openvpn-install.sh#L458

echo
read -p "Create password protected certificate? [y/N]: " protectedCrt
until [[ "$protectedCrt" =~ ^[yYnN]*$ ]]; do
	echo "$protectedCrt: invalid selection."
	read -p "Create password protected certificate? [y/N]: " protectedCrt
done
if [[ "$protectedCrt" =~ ^[yY]$ ]]; then
	echo
	echo "Generating certificate, you will be asked to enter password"
	echo
	EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client"
else
	EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass
fi

Samostatné soubory pro konfiguraci a certifikáty

Skript generuje jediný *.ovpn soubor, který obsahuje certifikáty vloženy přímo do něj. My jsme chtěli, aby byla možnost sdílet 1 konfigurační soubor "veřejně" se všemi zaměstnanci a pouze dodat samostatné certifikáty. Celý obsah funkce new_client() na řádku https://github.com/Nyr/.../openvpn-install.sh#L82 byl nahrazen kódem níže. Po vygenerování jsou navíc soubory zabaleny do 1 ZIP soubory, který je chráněn heslem.

mkdir -p ~/openvpn_configs
clientSuffix="$client-MyCompany"
cp /etc/openvpn/server/easy-rsa/pki/ca.crt ~/openvpn_configs/ca.crt
cp /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ~/openvpn_configs/"$clientSuffix".crt
cp /etc/openvpn/server/easy-rsa/pki/private/"$client".key ~/openvpn_configs/"$clientSuffix".key
cp /etc/openvpn/server/tc.key ~/openvpn_configs/tls-crypt-tc.key

client="$clientSuffix" { cat /etc/openvpn/server/client-common.txt echo "" echo "ca ca.crt" echo "cert $client.crt" echo "key $client.key" echo "tls-crypt tls-crypt-tc.key" } >> ~/openvpn_configs/"$client".ovpn

mkdir -p ~/openvpn_certs zip ~/openvpn_certs/"OpenVPN-$client.zip" --junk-paths --password $(cat /etc/openvpn/server/client-zip.password) \ ~/openvpn_configs/ca.crt \ ~/openvpn_configs/"$client".crt \ ~/openvpn_configs/"$client".key \ ~/openvpn_configs/tls-crypt-tc.key \ ~/openvpn_configs/"$client".ovpn rm ~/openvpn_configs/*

Máte osobní zkušenosti s OpenVPN serverem, či jiným řešením? Podělte se v komentářích

K tomuto článku již není možné přidávat další komentáře

Komentáře

Než se trápit tímto řešení, máme nejlepší zkušenosti s nasazením routeru Fortigate. Ten se dá bez problémů napojit např. na Active Directory a uživatelé nemusí mít více loginů, stejně tak např. 2FA.