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.