Raspberry Pi jako utwardzona brama WireGuard VPN ze Split-Tunnelingiem
Część 6 z 6 serii Homelab na Raspberry Pi

Spis treści
Przegląd architektury: Routing w jądrze WireGuard i Split-Tunneling
Tradycyjne protokoły VPN, takie jak OpenVPN czy IPsec, opierają się na przełączaniu kontekstu w przestrzeni użytkownika i złożonych uściskach dłoni (handshakes), co generuje wysokie obciążenie procesora oraz opóźnienia na komputerach jednopłytkowych ARM, takich jak Raspberry Pi. WireGuard działa bezpośrednio w przestrzeni jądra systemu Linux i wykorzystuje nowoczesne algorytmy kryptograficzne (ChaCha20, Poly1305, Curve25519), co umożliwia osiąganie przepustowości przekraczających 800 Mb/s na interfejsach Gigabit Ethernet przy minimalnym użyciu CPU.
W architekturze Split-Tunneling (dzielonego tunelowania) Raspberry Pi pełni funkcję utwardzonej bramy bezpieczeństwa. Zamiast kierować cały ruch internetowy klienta przez sieć domową – co ogranicza prędkość połączeń mobilnych – tunel selektywnie przesyła tylko określone podsieci docelowe (np. wewnętrzne zasoby laboratorium domowego w adresacji 192.168.10.0/24) przez zaszyfrowany interfejs WireGuard. Analogicznie, brama może zostać skonfigurowana do szyfrowania wybranych urządzeń w sieci lokalnej za pośrednictwem zewnętrznego dostawcy VPN, pozostawiając pozostały ruch LAN bez zmian.

wg0 przechodzą wyłącznie dwie sieci wymienione w AllowedIPs. Brama przekazuje je na poziomie jądra i maskuje na eth0; pozostały ruch opuszcza klienta bezpośrednio.Instrukcja wdrożenia krok po kroku
Krok 1: Włączenie przekazywania pakietów w jądrze Linux (IP Forwarding)
W celu umożliwienia przekazywania pakietów pomiędzy fizycznym interfejsem sieciowym (eth0) a wirtualnym interfejsem WireGuard (wg0), konieczne jest trwałe aktywowanie przekazywania ruchu IPv4 i IPv6 w konfiguracji jądra:
# /etc/sysctl.d/99-wireguard-forwarding.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
Zastosowanie zmodyfikowanych parametrów jądra natychmiast bez konieczności restartu hosta:
sysctl --system
Krok 2: Generowanie kluczy kryptograficznych i instalacja pakietów
Instalacja narzędzi jądrowych WireGuard oraz generowanie pary kluczy publicznych i prywatnych z rygorystycznymi uprawnieniami w systemie plików:
apt update && apt install -y wireguard wireguard-tools nftables
mkdir -p /etc/wireguard && cd /etc/wireguard
chmod 700 /etc/wireguard
wg genkey | tee server_private.key | wg pubkey > server_public.key
chmod 600 server_private.key
Krok 3: Konfiguracja utwardzonego interfejsu serwera (wg0.conf)
Główny plik konfiguracyjny definiuje port nasłuchu serwera, alokację podsieci oraz zintegrowane reguły zapory sieciowej. Stosowany jest domyślny port UDP WireGuard (51820) w połączeniu z rygorystycznymi regułami maskowania nftables:
# /etc/wireguard/wg0.conf
[Interface]
Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
# Automatyczne maskowanie zapory sieciowej za pomocą nftables
PostUp = nft add table ip wireguard; nft add chain ip wireguard nat { type nat hook postrouting priority 100\; policy accept\; }; nft add rule ip wireguard nat oifname "eth0" masquerade
PostDown = nft delete table ip wireguard
# Przykładowa konfiguracja klienta (Peer) w trybie Split-Tunnel
[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.100.0.2/32
Krok 4: Konfiguracja routingu Split-Tunnel na urządzeniu klienta
Na urządzeniu zdalnym parametr AllowedIPs decyduje o tym, czy połączenie działa jako pełny tunel, czy tunel dzielony. Ustawienie wartości AllowedIPs = 192.168.10.0/24, 10.100.0.0/24 wymusza przesyłanie przez zaszyfrowany tunel wyłącznie pakietów skierowanych do sieci domowej, podczas gdy publiczne przeglądanie stron internetowych odbywa się bezpośrednio przez lokalne łącze klienta:
# Konfiguracja po stronie klienta (Tryb Split-Tunneling)
[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = 10.100.0.2/24
DNS = 192.168.10.1
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = vpn.lukaswojcik.com:51820
AllowedIPs = 192.168.10.0/24, 10.100.0.0/24
PersistentKeepalive = 25
Krok 5: Kontrola jakości i walidacja przepustowości
Po uruchomieniu usługi systemd poleceniem systemctl enable --now wg-quick@wg0, weryfikację infrastruktury należy przeprowadzić w oparciu o trzy etapy diagnostyczne:
- Audyt nawiązywania sesji i wymiany kluczy: Wykonanie polecenia
wg show wg0w terminalu Raspberry Pi w celu potwierdzenia obecności aktualnych znaczników czasu (handshake) i statystyk transferu dla aktywnych klientów. - Weryfikacja tablicy routingu: Sprawdzenie tablic routingu na kliencie (np.
ip route show), co pozwala upewnić się, że domyślna brama internetowa pozostaje niezmieniona, a trasy statyczne dla192.168.10.0/24kierują ruch ściśle na interfejswg0. - Test przepustowości i opóźnień: Przeprowadzenie wewnętrznego testu prędkości narzędziem
iperf3pomiędzy zdalnym klientem a serwerem w sieci domowej w celu sprawdzenia, czy transfer osiąga maksymalne nasycenie łącza bez fragmentacji pakietów.
Podsumowanie i mierzalna wartość dodana
Co da się osiągnąć dzięki instrukcji: Wdrożenie utwardzonej bramy VPN WireGuard działającej w przestrzeni jądra systemu na platformie Raspberry Pi z selektywnym tunelowaniem dzielonym i automatycznym maskowaniem zapory sieciowej.
Resultujący wartość dodana:
- Dostęp zdalny bez opóźnień: Wewnętrzne usługi laboratorium domowego, panele administracyjne oraz zasoby dyskowe stają się bezpiecznie dostępne z zewnątrz bez otwierania portów wewnętrznych na świat.
- Optymalizacja zużycia łącza: Dzielone tunelowanie zapobiega przesyłaniu zewnętrznego ruchu wideo i webowego przez łącze domowe, utrzymując maksymalne prędkości pobierania na urządzeniach klientów.
- Minimalny pobór zasobów sprzętowych: Przetwarzanie na poziomie jądra wymaga na każdy przesłany gigabajt wyraźnie mniej czasu procesora niż protokoły działające w przestrzeni użytkownika, takie jak OpenVPN, dzięki czemu dla kontenerów aplikacji pozostaje zauważalnie więcej mocy obliczeniowej.
Pytania i odpowiedzi
Czy port UDP inny niż 51820 czyni bramę mniej widoczną dla skanów?
Raczej nie. WireGuard nie odpowiada na żaden pakiet, który nie niesie ważnego uzgodnienia połączenia (handshake) ze znanym kluczem, więc skan portów nie odróżni tego portu od filtrowanego, niezależnie od jego numeru. Utwardzenie polega na milczeniu protokołu, a nie na numerze portu, a 51820 i tak jest zwykłym domyślnym portem WireGuard.
Czy klient może obejść Split-Tunneling i wysyłać cały swój ruch przez sieć domową?
Tak, bo Split-Tunneling to decyzja klienta. AllowedIPs po stronie klienta określa tylko, które cele trafiają do tunelu. Jeśli klient wpisze tam 0.0.0.0/0, cały jego ruch trafi do Raspberry Pi, a ten przekaże go dalej: przekazywanie pakietów jest włączone, a reguła maskowania obejmuje wszystko, co opuszcza eth0, także drogę do internetu.
Na bramie konfiguracja ogranicza jedynie adres źródłowy: AllowedIPs = 10.100.0.2/32 w pliku serwera oznacza, że od tego peera przyjmowane są tylko pakiety z tym adresem źródłowym. O celach ta linia nic nie mówi.
Jeśli brama ma wymuszać Split-Tunneling, potrzebny jest łańcuch filtrujący na haku forward: przepuszczać ruch z wg0 do sieci domowej 192.168.10.0/24 oraz odpowiedzi na nawiązane połączenia, a całą resztę z wg0 odrzucać. Tabela rodziny inet obejmuje przy tym IPv4 i IPv6 w jednym łańcuchu.
Co dzieje się z rozwiązywaniem nazw na kliencie, gdy tunel przestaje działać?
Przestaje działać razem z nim. Przy DNS = 192.168.10.1 klient pyta serwer w sieci domowej, a ten adres leży w AllowedIPs. Każde zapytanie o nazwę idzie więc przez tunel, także o strony, których ruch poza tym płynie bezpośrednio do internetu. Gdy brama jest nieosiągalna, ogólny ruch wprawdzie płynie dalej bezpośrednio, ale żadna nazwa nie zostaje już rozwiązana, a dla osoby korzystającej z urządzenia wygląda to jak całkowita awaria.
Drugie ograniczenie dotyczy sieci, w której klient akurat się znajduje. Jeśli sieć hotelowa albo sieć dla gości sama używa 192.168.10.0/24, o te same adresy konkurują dwie trasy i zależnie od routingu klient nie osiągnie albo sieci domowej, albo lokalnej bramy. Mniej rozpowszechniona podsieć dla sieci domowej zmniejsza to ryzyko.
Homelab na Raspberry Pi
- Raspberry Pi 4 i 5: uruchamianie systemu z dysku SSD przez zmianę bootloadera
- Zasilanie awaryjne (UPS) dla Raspberry Pi 4 i 5: Top 5 urządzeń do wymagających projektów
- Lokalny CI/CD dla Raspberry Pi: Automatyzacja wdrożeń Docker Compose
- Autonomiczny serwer domowy Docker-Compose z Traefik, SSL i Watchtower
- Lokalny serwer mediów bez opóźnień: Jellyfin na Raspberry Pi 5 z akceleracją sprzętową
- Raspberry Pi jako utwardzona brama WireGuard VPN ze Split-Tunnelingiem