How to tunnel through VPS

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 będziesz mógł podawać jego adres IP jakby to był adres IP przypisany przez Twojego dostawcę usług.

WireGuard #

Na poniższym schemacie przedstawiłem w skrócie Twoją obecną sytuację. W opisie tym pominę kilka szczegółów i bardziej obrazowo niż technicznie przedstawię co tu się dzieje. Twój dostawca usługi dostępu do internetu ( ISP ), podobnie jak i Ty utworzył swoją własną sieć lokalna. Po podpisaniu z nim umowy, dostarczył Tobie router ( możliwe, że pozwolił zamienić na własny, jednak kabel nadal jest wpięty w jego sieć ) dzięki czemu możesz dowolnie podłączać urządzenia, a te mają połączenie z siecią Internet.

                      +----------------+
                      |                |
                      |  Internet      |
                      |                |
                      +-------+--------+
                              |
                              |
                              |
                              |
                      +-------+--------+
                      |                |
                      |     ISP        |
                      |                |
                      +-------+--------+
                              |
                              |( Public IP )
+--------------+       +------+-------+
|              |       |              |
|  Clients     +-------+   Router     |
+--------------+       +------+-------+
                              |
                              |
                              |( LAN IP )
                       +------+-------+
                       |              |
       ( You )         | Router/ONT/Modem
                       |              |
                       +------+-------+
                              |
                              |
                              |
                       +------+-------+    +----------------+
                       |              |    |                |
                       | Your network +----+  Host          |
                       |              |    |                |
                       +--------------+    +----------------+

Tobie natomiast zależy na uzyskaniu publicznego adresu IP i postanowiłeś pominąć z jakichś względów operatora. W tej sytuacji sięgnąłeś po maszynę w innej lokalizacji, która ma publiczny adres IP. Możliwe, że jest to serwer dedykowany, VPS, a może dzięki życzliwości kogoś znajomego uzyskasz taką konfigurację poprzez postawienia maszyny u tej osoby. Nie mniej w dalszej części ja się będę opierać o serwer VPS EC2 od AWS. Celem będzie zestawienie połączenia VPN pomiędzy maszyną w mojej sieci lokalnej na maszynie Host, a serwerem VPS. Abstrakcyjnie rzecz ujmując, pociągniemy kabel sieciowy przez cały internet. Obie maszyny wykorzystywane w tym przykładzie mają zainstalowany system Ubuntu Server 22.04 LTS.

                      +----------------+    +---------------+
                      |                |    |               |
                      |  Internet      +----+  VPS          |
                      |                |    |               |
                      +-------+--------+    +------+--------+
                              |                    |
                              |                    |
                              |                    |
                              |                    |
                      +-------+--------+           |
                      |                |           |
                      |     ISP        |           |
                      |                |           |
                      +-------+--------+           |
                              |                    |
                              |( Public IP )       |
+--------------+       +------+-------+    +-------+---------+
|              |       |              |    |VPN Network      |
|  Clients     +-------+   Router     |    |                 |
+--------------+       +------+-------+    +-------+---------+
                              |                    |
                              |                    |
                              |( LAN IP )          |
                       +------+-------+            |
                       |              |            |
       ( You )         | Router/ONT/Modem          |
                       |              |            |
                       +------+-------+            |
                              |                    |
                              |                    |
                              |                    |
                       +------+-------+    +-------+--------+
                       |              |    |                |
                       | Your network +----+  Host          |
                       |              |    |                |
                       +--------------+    +----------------+

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 narazie. 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 Linux 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 odnaleźć 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.