Toto je starší verze dokumentu!
OpenVPN
Pro servisní účely jsem potřeboval rychle rozběhnout OpenVPN. Nejprve jsem se docela trápil s nastavením konfiguračních souborů a certifikátů. Nicméně pak jsem objevil skript, který většinu věcí udělá za mě.
Projekt se skriptem se jmenuje openvpn-install.
Stažení je jednoduché:
curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh chmod +x openvpn-install.sh
A pak už jenom spustit:
./openvpn-install.sh
Zbytkem provede jednoduchý průvodce. Pokud chci vytvářet další uživatele a jejich certifikáty po instalaci, stačí skript spustit znovu a v nabídce se objeví možnost Add a client. Úplně stejně budu postupovat, pokud budu chtít vypnout nějakého klienta.
Skript mi vytvořil soubor /etc/iptables/add-openvpn-rules.sh, ve kterém bylo nachystáno routování do vnitřní sítě. Nemusel jsem se tedy trápit s tím, že když se připojím do VPN sítě, tak se nedostanu do vnitřní sítě.
Tady je obsah souboru:
#!/bin/sh iptables -t nat -I POSTROUTING 1 -s 10.8.0.0/24 -o wan -j MASQUERADE iptables -I INPUT 1 -i tun0 -j ACCEPT iptables -I FORWARD 1 -i wan -o tun0 -j ACCEPT iptables -I FORWARD 1 -i tun0 -o wan -j ACCEPT iptables -I INPUT 1 -i wan -p udp --dport 1194 -j ACCEPT
Dále pak vytvoří soubor /etc/systemd/system/multi-user.target.wants/iptables-openvpn.service, který nastavuje v systemd spouštění skriptu s iptables:
[Unit] Description=iptables rules for OpenVPN Before=network-online.target Wants=network-online.target [Service] Type=oneshot ExecStart=/etc/iptables/add-openvpn-rules.sh ExecStop=/etc/iptables/rm-openvpn-rules.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target
A jako další vytvoří soubor pro spouštění vpnserveru /etc/systemd/system/multi-user.target.wants/openvpn@server.service.
Dále mi ve složce /etc/openvpn vytvořil konfigurační soubor server.conf.
Pokud chci zařídit, aby po připojení k VPN nešel internet přes VPN server, tak je potřeba v konfiguračním souboru serveru zakomentovat tento řádek:
#push "redirect-gateway def1 bypass-dhcp"
Dále je možné mít klidně více instancí OpenVPN serveru. Stačí zkopírovat konfigurační soubor server.conf a vytvořit například server2.conf. V souboru editovat vše potřebné a poté spustit další instanci serveru:
openvpn --config server2.conf
Pokud mám VPN server nastavená tak, že nebude směřovat tok internetu přes server, je potřeba ještě u VPN klienta u připojení zaškrtnout tuto volbu:
Když jsem ji neměl zaškrtnutou, tak mi po připojení k VPN nešel internet.
Nastavení DNS serveru pro OpenVPN
Při konfiguraci OpenVPN serveru je možné nastavit, jaký DNS server bude klient používat po připojení. To se provádí přidáním následujícího řádku do konfigurace OpenVPN serveru:
push "dhcp-option DNS 192.168.1.50"
Tento příkaz zajistí, že klient po připojení použije DNS server s IP adresou 192.168.1.50. Lze přidat i více DNS serverů, přičemž první uvedený bude primární.
Po připojení přes OpenVPN jsem ověřil nastavení DNS serveru pomocí příkazu:
resolvectl status
Výstup tohoto příkazu zobrazil aktuálně používané DNS servery, což umožňuje ověřit, zda se změna správně projevila.
Problémy s SSH
Měl jsem problém, že ze serveru se mi nedařilo navázat spojení přes SSH u klientského počítače, který byl připojený přes VPN. Přitom ping na počítač fungoval a nmap mi potvrdil, že port s SSH je otevřený. Po delším zkoušení mě to dovedlo k tomu, že patrně dochází k fragmentaci packetů.
OpenVPN ve výchozím nastavení nebrání fragmentaci velkých TCP segmentů uvnitř tun-virt-rozhraní. Vaše MTU (1500 B na tun0) minus kryptografický overhead protokolu UDP/OpenVPN a minus IP/UDP hlavičky vychází někde kolem 1 400 B. Server ale posílá kusy až 1 388 B – to sice vypadá v pořádku, ale když se součet uvnitř šifrovaného UDP tunelu překlene do fragmentů (nebo někde v síti fragmenty zahazují), klient je už nikdy neslepí a TCP je neposkytne uživatelské aplikaci.
Vyřešil jsem to tak, že na konfiguračního souboru serveru jsem přidal:
mssfix 1200 tun-mtu 1400
- mssfix 1200 přinutí OpenVPN, aby upravilo MSS v TCP handshake na 1200 B, takže SSHKEX paket nikdy nepřesáhne bezpečnou velikost.
- tun-mtu 1400 pak nastavení tun-rozhraní na 1 400 B, aby zbyl dostatek místa i na OpenVPN hlavičky.
Bylo mi doporučeno to přidat i do konfiguračního souboru klienta, ale tam jsem to nepřidával a zatím to vypadá, že SSH už funguje.
Automatické připojení k OpenVPN serveru
Cílem je zajistit, aby se OpenVPN klient automaticky připojoval po startu systému a zároveň přesměrovával příchozí síťovou komunikaci na konkrétní zařízení ve vnitřní síti.
Klíčové je vložit konfigurační soubor do složky `/etc/openvpn/client/` a zajistit, aby měl příponu `.conf`. OpenVPN sice podporuje i příponu `.ovpn`, ale pouze `.conf` je systemd schopen automaticky spouštět.
Pro ruční spuštění postačí:
openvpn --config myclient.ovpn
Pro automatické spouštění použij:
systemctl start openvpn-client@myclient.service
Tento příkaz hledá konfigurační soubor `/etc/openvpn/client/myclient.conf`.
Doporučení: Chceš-li využívat výhody systemd (např. automatické restartování), přejmenuj soubor na `myclient.conf`. Obsah souboru může zůstat stejný jako `.ovpn`.
Pro stabilní spojení doporučujeme přidat do konfigurace řádek:
keepalive 10 60
To znamená, že klient každých 10 vteřin pošle „ping“ a po 60 vteřinách bez odpovědi restartuje spojení. Tento zápis je zjednodušený alias pro `–ping 10` a `–ping-restart 60`.
Shrnutí postupu:
- Přejmenuj soubor na `myclient.conf`
- Přidej (nebo ponech) `keepalive 10 60`
- Zkontroluj umístění: `/etc/openvpn/client/myclient.conf`
- Aktivuj a spusť službu:
systemctl enable openvpn-client@myclient systemctl start openvpn-client@myclient
Ověření funkčnosti:
- Stav služby:
systemctl status openvpn-client@myclient
- Aktivní tunel poznáš podle rozhraní `tun0`:
ip a | grep tun0
- Pro zobrazení logů:
journalctl -u openvpn-client@myclient
Forwarding na zařízení uvnitř sítě
Aby bylo možné přeposílat komunikaci z VPN na zařízení v lokální síti, je potřeba povolit IP forwarding.
V souboru `/etc/sysctl.conf` nastav:
net.ipv4.ip_forward=1
Změnu načti pomocí:
sysctl -p
Přesměrování provozu pak zajistí vlastní skripty. Níže je příklad jednoduchého nastavení pro zařízení s IP `192.168.0.120`.
/etc/openvpn/up.sh
#!/bin/bash INTERNAL_IP="192.168.0.120" INTERNAL_IF="eth0" # nebo jiné rozhraní dle sítě iptables -t nat -A PREROUTING -i tun0 -p tcp ! --dport 22 -j DNAT --to-destination $INTERNAL_IP iptables -t nat -A PREROUTING -i tun0 -p udp -j DNAT --to-destination $INTERNAL_IP iptables -A FORWARD -i tun0 -o $INTERNAL_IF -d $INTERNAL_IP -j ACCEPT iptables -t nat -A POSTROUTING -s $INTERNAL_IP -o tun0 -j MASQUERADE
/etc/openvpn/down.sh
#!/bin/bash INTERNAL_IP="192.168.0.120" INTERNAL_IF="eth0" iptables -t nat -D PREROUTING -i tun0 -p tcp ! --dport 22 -j DNAT --to-destination $INTERNAL_IP iptables -t nat -D PREROUTING -i tun0 -p udp -j DNAT --to-destination $INTERNAL_IP iptables -D FORWARD -i tun0 -o $INTERNAL_IF -d $INTERNAL_IP -j ACCEPT iptables -t nat -D POSTROUTING -s $INTERNAL_IP -o tun0 -j MASQUERADE
Poznámka: Pokud síťové rozhraní není `eth0`, uprav `$INTERNAL_IF` podle výstupu příkazu `ip a`.
Skripty je potřeba zpřístupnit pro spuštění:
chmod +x /etc/openvpn/up.sh /etc/openvpn/down.sh
A nakonec je přidej do konfiguračního souboru `myclient.conf`:
script-security 2 up /etc/openvpn/up.sh down /etc/openvpn/down.sh
Ověření po navázání tunelu:
iptables -t nat -L -n -v iptables -L -n -v