How to tunnel through VPS
Wstęp
Chciałbyś postawić serwer ze swoją ulubioną grą, ale brakuje Tobie publicznego adresu IP żeby móc przekierować porty? Możesz wykupić serwer VPS i skorzystać z jego adresu IP do tego celu. W zestawieniu z połączeniem VPN (Virtual Private Network - wirtualna sieć prywatna) będziesz mógł podawać jego adres IP jakby to był adres IP przypisany przez Twojego dostawcę usług. VPN tworzy bezpieczny tunel między Twoim hostem a serwerem VPS, dzięki czemu możesz korzystać z publicznego IP VPS.
WireGuard
Poniższy schemat przedstawia standardową konfigurację sieci domowej. Twój dostawca usług internetowych (ISP) przydziela publiczny adres IP routerowi, który tworzy sieć lokalną (LAN). Wszystkie urządzenia w Twojej sieci domowej łączą się przez router, jednak nie mają bezpośredniego publicznego adresu IP.
┌─────────────────┐
│ Internet │
└────────┬────────┘
│
┌────────┴────────┐
│ ISP │
└────────┬────────┘
│ (Publiczny IP od ISP)
┌────────────┴────────────┐
┌──────┴──────┐ ┌──────┴──────┐
│ Urządzenia │ │ Router │
│ w sieci │ │ (Public IP) │
└─────────────┘ └──────┬──────┘
│ (LAN IP, np. 192.168.1.x)
┌────────┴────────┐
│ Router/ONT/Modem│
└────────┬────────┘
│
┌────────┴────────┐
│ Twoja sieć LAN │
└────────┬────────┘
│
┌────────┴────────┐
│ Host (serwer) │
│ (LAN IP) │
└─────────────────┘
Jeśli potrzebujesz publicznego adresu IP, a Twój dostawca go nie zapewnia, możesz wykorzystać serwer VPS (Virtual Private Server) z publicznym adresem IP. W tym wpisie pokażę, jak skonfigurować VPN między Twoim Hostem a serwerem VPS, aby korzystać z publicznego IP VPS. W dalszej części artykułu będę opierał się na serwerze VPS EC2 od AWS. Obie maszyny wykorzystane w przykładzie mają zainstalowany system Ubuntu Server 22.04 LTS.
┌─────────────────┐ ┌──────────────┐
│ Internet ├────┤ VPS │
└────────┬────────┘ │ (Public IP) │
│ │ 10.0.0.1/24 │
┌────────┴────────┐ └──────┬───────┘
│ ISP │ │
└────────┬────────┘ │ WireGuard
│ │ VPN Tunnel
┌────────────┴────────────┐ │
┌──────┴──────┐ ┌──────┴───────┐
│ Urządzenia │ │ Router │
│ w sieci │ │ (Public IP) │
└─────────────┘ └──────┬───────┘
│ (LAN IP)
┌────────┴────────┐
│ Router/ONT/Modem│
└────────┬────────┘
│
┌────────┴────────┐
│ Twoja sieć LAN │
└────────┬────────┘
│
┌────────┴────────┐
│ Host (serwer) │
│ VPN: 10.0.0.2 │
└─────────────────┘
Do tego celu po obu stronach zostanie skonfigurowany WireGuard, następnie po stronie VPS system Linux Ubuntu zostanie skonfigurowany tak aby pełnił rolę routera, a na koniec zostaną przekierowane porty do mojej maszyny Host.
VPN
Jak wspominałem na wstępie, do zestawienia połączenia VPN pomiędzy VPS, a Host wykorzystam oprogramowanie o nazwie WireGuard ( WG ). Konfiguracja tego jest zdecydowanie łatwiejsza w stosunku do np. OpenVPN. Zaczynamy od zainstalowania pakietu wireguard za pomocą managera pakietów. Jako, że ja korzystam z Ubuntu to u mnie jest to apt.
# tym poleceniem instaluje pakiet wireguard na obu maszynach
apt install wireguard
Po chwili przetwarzania, oba systemy powinny zasygnalizować gotowość do dalszej pracy. Czas przystąpić do konfigurowania. Postanowiłem, że sieć VPN ( na diagramie VPN Network ) przyjmie adresację 10.0.0.0/24, serwer VPN 10.0.0.1/24, a Host 10.0.0.2/24. Maska sieci jest gigantyczna jak na zestawienie tunelu dla 2 maszyn, jednak pozostawiam na przyszłość.
Najpierw ustawimy umask na katalogu, który będzie zawierać pliki konfiguracyjne oraz nasze klucze, tak aby nikt przypadkiem nie mógł ich odczytać lub też zmienić.
# rzecz także dzieje się na obu maszynach
umask 077 /etc/wireguard
Teraz kiedy katalog jest ustawiony aby każdy nowy plik tworzony był z możliwością wyłącznej edycji przez użytkownika root, można wygenerować i utworzyć klucze prywatne i na ich podstawie właściwe klucze publiczne, tak aby wymienić klucze pomiędzy maszynami. Klucz publiczny serwera zostanie przekazany do Host, a klucz publiczny Host zostanie przekazany do serwera.
# klucze muszą być wygenerowane na każdym hoście
wg genkey > /etc/wireguard/privatekey
wg pubkey < /etc/wireguard/privatekey > /etc/wireguard/publickey
Po ustawieniu umask i wygenerowaniu klucz na obu maszynach, możemy zweryfikować czy wszystko się nam zgadza jak na razie. W katalogu /etc/wireguard powinny być privatekey oraz publickey a ich uprawnienia powinny zezwalać wyłącznie użytkownikowi root na odczyt ( r ) oraz zapis ( w ).
# taki efekt powinien być uzyskany po każdej ze stron
root@ip-172-31-20-9:~# ls -la /etc/wireguard/
total 16
drwx------ 2 root root 4096 Dec 10 22:28 .
drwxr-xr-x 94 root root 4096 Dec 10 22:20 ..
-rw------- 1 root root 45 Dec 10 22:22 privatekey
-rw------- 1 root root 45 Dec 10 22:28 publickey
Następnie po stronie serwera tworzymy plik konfiguracyjny, który powie naszemu WG na którym porcie ma słuchać oraz jakie klucze publiczne są OK. Otwieramy/tworzymy plik konfiguracyjny naszym ulubionym edytorem tekstu. Ja do tego celu skorzystam z vim. Plik musi nosić nazwę interfejsu, z jakim WG będzie widnieć w naszym systemie i zakończony ma być ‘.conf’. Dlatego ja interfejs ten nazwę wg0, przez co plik nazywać się będzie wg0.conf.
<SERVER PRIVATE KEY> to ciąg znaków znajdujący się w pliku /etc/wireguard/privatekey na maszynie VPS, natomiast <CLIENT PUBLIC KEY> to ciąg znaków, które są w pliku /etc/wireguard/publickey na maszynie Host. Oba te ciągi znaków uzyskasz poleceniem cat.
cat /etc/wireguard/privatekey
cat /etc/wireguard/publickey
# zawartość pliku /etc/wireguard/wg0.conf na VPS
[Interface]
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = <SERVER PRIVATE KEY>
[Peer]
PublicKey = <CLIENT PUBLIC KEY>
AllowedIPs = 10.0.0.2/32
#zawartosc pliku /etc/wireguard/wg0.conf na Host
[Interface]
Address = 10.0.0.2/32
PrivateKey = <CLIENT PRIVATE KEY>
[Peer]
PublicKey = <SERVER PUBLIC KEY>
AllowedIPs = 10.0.0.0/24
Endpoint = <SERVER PUBLIC IP>:51820
PersistentKeepalive = 25
Teraz można uruchomić usługę WG i przejść do weryfikacji czy maszyny są w stanie odpowiadać na ping.
# polecenie jest dla obu stron, aby wystartować usługi na VPS oraz Host
wg-quick up wg0
Po uruchomieniu interfejsów sieciowych WG powyższym poleceniem na obu maszynach powinna być możliwa komunikacja obustronna, ze strony serwera wykonanie polecenia ping 10.0.0.2, powinno poskutkować uzyskaniem odpowiedzi od interfejsu wg0 z maszyny Host, a także wykonanie polecenia ping 10.0.0.1 na maszynie Host, powinno skutkować odpowiedzią od interfejsu wg0 z serwera.
Opcjonalnie, możemy skonfigurować system aby przy każdym starcie systemu, interfejs WG uruchamiał się automatycznie. W tym celu wywołujemy polecenie:
# chcemy aby po uruchomieniu się systemu, usługa wstała domyślnie, działamy na obu maszynach.
systemctl enable wg-quick@wg0
Tym sposobem zestawiliśmy w pełni połączenie VPN pomiędzy naszym Host, a serwerem w zdalnej lokacji.
Konfiguracja Linuksa do roli routera
Konfigurujemy VPS do pełnienia roli routera ( do użycia jego publicznego IP na rzecz podłączonych klientów VPN )
net.ipv4.ip_forward
Po udanym zestawieniu połączenia VPN ze zdalną maszyną należy teraz skonfigurować serwer VPS w taki sposób aby był w stanie przekazywać pakiety do maszyny Host za pośrednictwem wirtualnej sieci prywatnej (VPN). Krokiem pierwszym jest włączenie net.ipv4.ip_forward. Poniższym poleceniem sprawdzę, jaki jest aktualny stan tej funkcji. Polecenie to z dużym prawdopodobieństwem zwróci wartość ‘0’, jako że domyślnie Linux ma to wyłączone.
cat /proc/sys/net/ipv4/ip_forward
# 0 - disabled
# 1 - enabled
Jest kilka możliwości ustawienia tej wartości. Pierwsze dwie ( możesz użyć dowolnej metody ) z użyciem sysctl lub echo są tymczasowe i po restarcie zdalnej maszyny będzie trzeba ustawić na nowo.
sysctl -w net.ipv4.ip_forward=0
---
sysctl -w net.ipv4.ip_forward=1
echo 0 > /proc/sys/net/ipv4/ip_forward
---
echo 1 > /proc/sys/net/ipv4/ip_forward
Natomiast zmiany na stałe zostaną wprowadzone po wprowadzeniu zmian w pliku konfiguracyjnym /etc/sysctl.conf. W moim przypadku wystarczyło znaleźć odpowiedni wiersz i go odkomentować ( usunąć ‘#’ ). Po zapisaniu zmian, wprowadzenie ich w życie odbywa się poprzez polecenie
sysctl -p
iptables
System jest gotowy do przekazywania pakietów zgodnie z naszymi potrzebami. Do sterowania z którego portu do którego adresu IP i na który port wykorzystamy iptables. Jednak nim przystąpimy do dalszego klepania poleceń, zastanówmy się co chcemy osiągnąć. W przykładzie przekieruję port TCP 80 do Host. Port ten jest odpowiedzialny za HTTP czyli strony internetowe, a sprawdzenie poprawności przekierowania odbędzie się za pośrednictwem przeglądarki internetowej. Jeżeli zobaczymy stronę powitalną pakietu nGinx będzie to oznaczać, że tunel jest poprawnie ustawiony, a system linux poprawnie przekierowuje pakiety do naszej maszyny.
Dla przypomnienia, serwer VPS posiada adres VPN 10.0.0.1 oraz jakiś adres publiczny, a Host posiada jakiś adres sieci lokalnej oraz adres VPN 10.0.0.2
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 80 -j DNAT --to-destination 10.0.0.2:80
iptables -t nat -A POSTROUTING -p tcp --dport 80 -d 10.0.0.2 -j MASQUERADE
Konfiguracja ta jest ulotna, żeby serwer zapamiętał ustawienia i ustawiał je po każdym restarcie należy doinstalować pakiet iptables-persistent lub jeżeli już jest zainstalowany to zapisać zmiany w pliku konfiguracyjnym poprzez
iptables-save > /etc/iptables/rules.v4
Podsumowanie
W tym wpisie dowiedziałeś się w jaki sposób wykorzystać inną maszynę i jej publiczny adres IP w celu przetunelowania połączenia do swojej maszyny za pomocą połączenia VPN i krótkiej konfiguracji iptables. Sposób ten można wykorzystać nie tylko do przekazania portu dla stron www, serwery gier
Comments powered by Talkyard.