Warning: Constant BP3D_VERSION already defined, this will be an error in PHP 9 in /home/oliwia/domains/gpietrzak.pl/public_html/wp-content/plugins/3d-viewer/3d-viewer.php on line 56
Znajomy gra na moim serwerze Minecraft przez VPN i nie widzi reszty sieci - NieCodzienny Majsterkuje
Menu Zamknij

Znajomy gra na moim serwerze Minecraft przez VPN i nie widzi reszty sieci

Kolega zapytał, czy jego syn mógłby wchodzić na nasz serwer Minecraft. Sprawa niby prosta, tyle że serwer stoi u mnie w domu, w tej samej sieci co Home Assistant, kamery, dyski i kilka rzeczy, których nie pokazuję nikomu z zewnątrz. Przekierowanie portu odpadło w trzy sekundy.

Skończyło się na tunelu WireGuard, w którym gość widzi dokładnie jeden adres i cztery porty. Nic więcej. Ani routera, ani reszty sieci, ani nawet internetu przez ten tunel. Poniżej opisuję, jak to poskładałem, razem z dwoma pułapkami, które zjadły mi pół wieczoru.

Dlaczego odpadł Cloudflare i przekierowanie portu

Cloudflare Tunnel był pierwszym pomysłem i pierwszym skreślonym. Minecraft w wersji Bedrock, czyli ten z tabletów i telefonów, chodzi po UDP, a zwykły tunel Cloudflare go nie przepuszcza. Dla wersji Java po TCP trzeba by sięgnąć po Spectrum, produkt z półki dla firm. Do domowego serwera dla dzieciaków to armata na komara.

Przekierowanie portu na routerze działa i zajmuje minutę. Problem jest gdzie indziej. Mój serwer chodzi w trybie offline, bez weryfikacji kont Microsoftu, bo tak wymagają launchery, z których korzystają dzieci. W takim trybie każdy, kto trafi na otwarty port, wchodzi pod dowolnym nickiem. Również pod nickiem administratora. Wystawianie tego do internetu byłoby proszeniem się o kłopoty.

Dlaczego WireGuard dobrze nadaje się do wpuszczenia obcej osoby

WireGuard wiąże klucz publiczny każdego uczestnika z konkretnym adresem w tunelu. To pole nazywa się allowed-address i nie jest tylko informacją dla routingu. Pakiet, który przyjdzie tunelem z innym adresem źródłowym niż przypisany do danego klucza, zostaje odrzucony przez sam WireGuard, zanim w ogóle dotrze do reguł zapory.

To zmienia sytuację. W zwykłej sieci lokalnej adres źródłowy to sugestia, którą da się podrobić. Tutaj jest gwarantowany kryptograficznie. Dzięki temu reguły oparte o adres gościa są wiarygodne i nie da się ich obejść podszyciem pod cudze IP.

Cztery reguły, które załatwiają sprawę

Router to MikroTik z RouterOS. Adresy w przykładzie są zmyślone: sieć domowa to 192.168.10.0/24, serwer Minecraft siedzi na 192.168.10.50, tunel VPN pracuje w 192.168.20.0/24, a gość dostaje 192.168.20.99.

Zamiast wpisywać adres gościa wprost w każdą regułę, zakładam listę adresów. Kolejna osoba to wtedy jeden wpis, bez dotykania zapory.

/ip/firewall/address-list/add list=mc-goscie address=192.168.20.99 comment="Tablet goscia"

/ip/firewall/filter/add chain=input src-address-list=mc-goscie \
  action=drop comment="Goscie: brak dostepu do routera"

/ip/firewall/filter/add chain=forward src-address-list=mc-goscie \
  dst-address=192.168.10.50 protocol=tcp dst-port=25565 \
  action=accept comment="Goscie: Minecraft Java"

/ip/firewall/filter/add chain=forward src-address-list=mc-goscie \
  dst-address=192.168.10.50 protocol=udp dst-port=19132 \
  action=accept comment="Goscie: Minecraft Bedrock"

/ip/firewall/filter/add chain=forward src-address-list=mc-goscie \
  action=drop comment="Goscie: reszta zablokowana"

Pierwsza reguła odcina gościa od samego routera, bo w typowej konfiguracji WireGuarda jest gdzieś zgoda wpuszczająca uczestników tunelu na interfejs zarządzania. Dwie środkowe otwierają wyłącznie porty gry. Ostatnia zamyka wszystko inne, łącznie z wyjściem na internet przez mój tunel.

Pułapka, na którą się nadziałem

W RouterOS liczy się kolejność. Zapora bierze pierwszą pasującą regułę i kończy analizę. Moje cztery reguły muszą więc stać przed istniejącymi wpisami, które przepuszczają ruch z VPN do sieci domowej.

Do wstawiania w konkretne miejsce służy parametr place-before i tu zaczyna się zabawa. On liczy pozycję w chwili dodawania reguły, a każda dodana przesuwa numerację następnych. Efekt był taki, że moje cztery wpisy weszły poprzeplatane ze starymi. Najpierw reguła przepuszczająca VPN do całej sieci wylądowała przed blokadą, czyli gość dostałby dokładnie to, czego chciałem uniknąć. Po pierwszej poprawce blokada wskoczyła przed regułę od Bedrocka i wtedy z kolei UDP by nie przeszło.

Wniosek na przyszłość: po dodaniu regul zawsze wypisz je i sprawdź wzrokiem, zamiast ufać, że wylądowały tam, gdzie chciałeś.

/ip/firewall/filter/print
/ip/firewall/filter/move numbers=5 destination=4

Konfiguracja po stronie gościa

Klucz prywatny generuje się na urządzeniu gościa, a do mnie trafia tylko publiczny. Gdy nie ma pod ręką narzędzi WireGuarda, wystarczy OpenSSL, bo pod spodem to zwykły klucz X25519.

openssl genpkey -algorithm X25519 -out klucz.pem
openssl pkey -in klucz.pem -outform DER | tail -c 32 | base64
openssl pkey -in klucz.pem -pubout -outform DER | tail -c 32 | base64

Sama konfiguracja klienta jest krótka. Najważniejsza linia to AllowedIPs zawężone do jednego hosta. Dzięki temu przez tunel idzie wyłącznie ruch do serwera gry, a zwykły internet gościa leci jego własnym łączem i nie obciąża mojego.

[Interface]
PrivateKey = (klucz prywatny gościa)
Address = 192.168.20.99/32

[Peer]
PublicKey = (klucz publiczny mojego routera)
AllowedIPs = 192.168.10.50/32
Endpoint = vpn.przykladowadomena.pl:51820
PersistentKeepalive = 25

Warto pamiętać, że zawężenie po stronie klienta to wygoda, nie zabezpieczenie. Gość może sobie to zmienić w dwie sekundy. Realną barierą są reguły na routerze i tylko one.

Plik konfiguracyjny da się zamienić na kod QR do zeskanowania aplikacją. Tylko koniecznie lokalnie, własnym generatorem. W tym pliku siedzi klucz prywatny i wklejanie go w losowy serwis w internecie jest mniej więcej tak rozsądne jak wysłanie komuś zdjęcia swojego klucza do mieszkania.

Bedrock na tablecie

Wersja Bedrock nie połączy się z serwerem Java. Rozwiązaniem jest Geyser z Floodgate, czyli wtyczki tłumaczące protokół. Wtyczki wymagają serwera, który je obsłuży, więc czysta wersja od Mojanga musi ustąpić miejsca Paperowi. Świat zostaje ten sam, podmienia się tylko silnik.

Dwie rzeczy potrafią zaskoczyć. Geyser domyślnie ustawia tryb uwierzytelniania, który wymaga od gracza posiadania konta w wersji Java, co przy graczu z tabletu nie ma sensu. Przy zainstalowanym Floodgate trzeba to przestawić. Druga sprawa: każda instancja Geysera domyślnie chce portu 19132, więc przy dwóch serwerach na jednej maszynie drugi trzeba przesunąć ręcznie, bo inaczej po prostu nie wstanie.

Przez tunel nie działa też wykrywanie serwerów w sieci lokalnej. Gość musi dodać serwer ręcznie, wpisując adres i port.

Dwa nieoczywiste problemy po stronie Androida

Pierwszy jest tak głupi, że aż mnie rozbroił. Na starszym tablecie trzymanym poziomo aplikacja WireGuard w ogóle nie pokazała okienka z nazwą tunelu po zeskanowaniu kodu. Nic. Klikam, skanuję i cisza, więc przez dobrą chwilę byłem przekonany, że to blokada uprawnień. Obróciłem tablet do pionu i okienko wyskoczyło od razu. Jeśli więc dodawanie tunelu wygląda, jakby nie działało, zanim zaczniesz grzebać w uprawnieniach, obróć ekran.

Drugi dotyczy urządzeń pod nadzorem Family Link. Przy dodawaniu tunelu wyskakuje komunikat o konieczności zapytania rodzica, tylko że na telefonie rodzica nie pojawia się żadne powiadomienie. To nie awaria. Google ma dwie ścieżki zgody i tylko część z nich, głównie instalacje z Play, leci zdalnie. Zmiany w ustawieniach systemowych idą ścieżką osobistą, w której rodzic musi potwierdzić operację bezpośrednio na urządzeniu dziecka. Służy do tego kod dostępu rodzica, który generuje się w aplikacji Family Link po wejściu w profil dziecka, a wpisuje na tablecie w ustawieniach, w sekcji cyfrowej równowagi i kontroli rodzicielskiej. Czekanie na powiadomienie nic nie da.

Co z tego wyszło

Gość ma na tablecie jedną aplikację, jeden tunel i skrót do serwera. W całej mojej sieci widzi jeden adres i cztery porty. Router jest dla niego niewidzialny, reszta urządzeń też, a jego zwykły ruch internetowy w ogóle mnie nie dotyczy.

Zostaje jeszcze jedna rzecz, o której łatwo zapomnieć przy takiej konfiguracji. Skoro serwer nie weryfikuje kont, to po wejściu do tunelu o tym, kto faktycznie wchodzi do gry, decyduje wyłącznie biała lista nicków na samym serwerze. Bez niej cała robota z zaporą chroni sieć, ale nie chroni samej gry.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *