it:server:openvpn

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
it:server:openvpn [2024/06/01 21:56] Petr Nosekit:server:openvpn [2025/06/18 12:20] (aktuální) Petr Nosek
Řádek 21: Řádek 21:
 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. 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:
  
 +<code bash>
 +#!/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            
 +</code>
  
  
 +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:
  
 +<code>
 +[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
 +</code>
 +
 +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:
 +
 +<code>
 +#push "redirect-gateway def1 bypass-dhcp"
 +</code>
 +
 +
 +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:
 +
 +<code>
 +openvpn --config server2.conf
 +</code>
 +
 +
 +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: 
 +
 +{{:it:linux:desktop:pasted:20250513-214557.png}}
 +
 +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:
 +
 +<code>
 +push "dhcp-option DNS 192.168.1.50"
 +</code>
 +
 +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:
 +
 +<code bash>
 +resolvectl status
 +</code>
 +
 +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:
 +
 +<code>
 +mssfix 1200
 +tun-mtu 1400
 +</code>
 +
 +  * 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čí:
 +
 +<code bash>
 +openvpn --config myclient.ovpn
 +</code>
 +
 +Pro automatické spouštění použij:
 +
 +<code bash>
 +systemctl start openvpn-client@myclient.service
 +</code>
 +
 +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:
 +
 +<code>
 +keepalive 10 60
 +</code>
 +
 +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:
 +
 +<code bash>
 +systemctl enable openvpn-client@myclient
 +systemctl start openvpn-client@myclient
 +</code>
 +
 +**Ověření funkčnosti:**
 +
 +  * Stav služby:  
 +    <code bash>
 +    systemctl status openvpn-client@myclient
 +    </code>
 +
 +  * Aktivní tunel poznáš podle rozhraní `tun0`:  
 +    <code bash>
 +    ip a | grep tun0
 +    </code>
 +
 +  * Pro zobrazení logů:  
 +<code bash>
 +journalctl -u openvpn-client@myclient
 +</code>
 +
 +----
 +
 +===== 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:
 +
 +<code>
 +net.ipv4.ip_forward=1
 +</code>
 +
 +Změnu načti pomocí:
 +
 +<code bash>
 +sysctl -p
 +</code>
 +
 +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**
 +
 +<code bash>
 +#!/usr/bin/env bash
 +set -euo pipefail
 +
 +# Tento skript nakonfiguruje DNAT z OpenVPN (tun0) na interní stroj 10.112.234.112
 +# Přesměrování všech portů kromě SSH (port 22) s vyčištěním starých pravidel
 +
 +# Kontrola, zda běží pod rootem
 +if [[ "$EUID" -ne 0 ]]; then
 +  echo "Prosím spusťte jako root nebo pomocí sudo." >&2
 +  exit 1
 +fi
 +
 +# Proměnné – upravte podle potřeby
 +VPN_IF="tun0"
 +INT_IF="eth0"
 +DEST_IP="192.168.0.120"
 +EXCLUDE_PORT="22"
 +
 +# 0) Načtení FTP helper modulů
 +#modprobe nf_conntrack_ftp
 +#modprobe nf_nat_ftp
 +
 +# 0b) Připojení FTP helperu pro control channel (port 21)
 +iptables-legacy -t raw -A PREROUTING \
 +    -i "$VPN_IF" \
 +    -p tcp --dport 21 \
 +    -j CT --helper ftp
 +
 +
 +# 1) Vyčištění stávajících pravidel NAT a FORWARD
 +iptables-legacy -t nat -F PREROUTING
 +iptables-legacy -t nat -F POSTROUTING
 +iptables-legacy -F FORWARD
 +
 +# 2) Povolit IP forwarding
 +sysctl -w net.ipv4.ip_forward=1
 +if ! grep -q '^net.ipv4.ip_forward' /etc/sysctl.conf; then
 +  echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
 +fi
 +
 +# 3) DNAT: přesměrování všech TCP portů kromě SSH na interní stroj
 +iptables-legacy -t nat -A PREROUTING \
 +    -i "$VPN_IF" \
 +    -p tcp -m tcp ! --dport "$EXCLUDE_PORT" \
 +    -j DNAT --to-destination ${DEST_IP}
 +
 +# 4) DNAT: přesměrování všech UDP portů kromě SSH na interní stroj
 +iptables-legacy -t nat -A PREROUTING \
 +    -i "$VPN_IF" \
 +    -p udp -m udp ! --dport "$EXCLUDE_PORT" \
 +    -j DNAT --to-destination ${DEST_IP}
 +
 +# 5) Povolit forward chain pro směry tun0 → eth0 (nové i navázané relace)
 +iptables-legacy -A FORWARD \
 +    -i "$VPN_IF" -o "$INT_IF" -d "$DEST_IP" \
 +    -j ACCEPT
 +iptables-legacy -A FORWARD \
 +    -i "$INT_IF" -o "$VPN_IF" \
 +    -m state --state ESTABLISHED,RELATED \
 +    -j ACCEPT
 +
 +# 6) SNAT/MASQUERADE pro interní stroj, pokud nemá přímou zpětnou cestu
 +iptables-legacy -t nat -A POSTROUTING \
 +    -o "$INT_IF" \
 +    -d "$DEST_IP" \
 +    -j MASQUERADE
 +
 +# Hotovo
 +echo "Vyčištěna stará pravidla a aplikován DNAT pro všechna porty kromě portu ${EXCLUDE_PORT}."
 +
 +</code>
 +
 +**/etc/openvpn/down.sh**
 +
 +<code bash>
 +#!/usr/bin/env bash
 +set -euo pipefail
 +
 +# Tento skript odstraní pravidla DNAT a SNAT z předchozího setupu
 +
 +# Kontrola, zda běží pod rootem
 +if [[ "$EUID" -ne 0 ]]; then
 +  echo "Prosím spusťte jako root nebo pomocí sudo." >&2
 +  exit 1
 +fi
 +
 +# Proměnné – musí odpovídat setup skriptu
 +VPN_IF="tun0"
 +INT_IF="eth0"
 +DEST_IP="192.168.0.120"
 +EXCLUDE_PORT="22"
 +
 +# Odstranění raw/FTP helper pravidla
 +iptables-legacy -t raw -D PREROUTING -i "$VPN_IF" -p tcp --dport 21 -j CT --helper ftp || true
 +
 +# Vyčištění pravidel NAT a FORWARD vztahujících se k tun0 a DEST_IP
 +iptables-legacy -t nat -D PREROUTING -i "$VPN_IF" -p tcp -m tcp ! --dport "$EXCLUDE_PORT" -j DNAT --to-destination ${DEST_IP} || true
 +iptables-legacy -t nat -D PREROUTING -i "$VPN_IF" -p udp -m udp ! --dport "$EXCLUDE_PORT" -j DNAT --to-destination ${DEST_IP} || true
 +iptables-legacy -t nat -D POSTROUTING -o "$INT_IF" -d "$DEST_IP" -j MASQUERADE || true
 +iptables-legacy -D FORWARD -i "$VPN_IF" -o "$INT_IF" -d "$DEST_IP" -j ACCEPT || true
 +iptables-legacy -D FORWARD -i "$INT_IF" -o "$VPN_IF" -m state --state ESTABLISHED,RELATED -j ACCEPT || true
 +
 +# Volitelné: vrátit ip_forward do výchozí hodnoty (pokud potřebujete)
 +# sysctl -w net.ipv4.ip_forward=0
 +
 +echo "Pravidla DNAT/SNAT byla odstraněna."
 +
 +</code>
 +
 +**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í:
 +
 +<code bash>
 +chmod +x /etc/openvpn/up.sh /etc/openvpn/down.sh
 +</code>
 +
 +A nakonec je přidej do konfiguračního souboru `myclient.conf`:
 +
 +<code>
 +script-security 2
 +up /etc/openvpn/up.sh
 +down /etc/openvpn/down.sh
 +</code>
 +
 +**Ověření po navázání tunelu:**
 +
 +<code bash>
 +iptables-legacy -t nat -L -n -v
 +iptables-legacy -L -n -v
 +</code>
  
  • it/server/openvpn.1717279003.txt.gz
  • Poslední úprava: 2024/06/01 21:56
  • autor: Petr Nosek