Raspberry Pi 3B jako energooszczędny serwer WireGuard VPN do dostępu do sieci domowej

Przez pewien czas używałem serwera HP ProLiant ML350p Gen8 jako serwera WireGuard VPN. Rozwiązanie działało poprawnie, ale pojawił się jeden problem – serwer pobiera znacznie więcej energii niż jest to potrzebne do samego utrzymywania tunelu VPN.

Postanowiłem więc przenieść usługę VPN na Raspberry Pi 3B, które wcześniej funkcjonowało jako domowy NAS (Open Media Vault). Ze względu na to, iż system był już mocno archaiczny i nie było sensu go aktualizować, postanowiłem zainstalować świeży Pi OS z ewentualną możliwością uruchomienia udziałów sieciowych przez SAMBĘ.

Raspberry Pi pobiera zaledwie kilka watów mocy i może działać przez całą dobę praktycznie bez wpływu na rachunki za energię dzięki czemu nadaje się jako punkt dostępowy VPN do sieci lokalnej.

Założenia

Infrastruktura:

  • Router TP-Link Archer C7
  • Raspberry Pi 3B połączone przez Wi-Fi
  • Publiczny adres IP
  • Dostęp z telefonu przez WireGuard

Docelowa architektura:

Telefon
    ↓
Internet
    ↓
WireGuard na Raspberry Pi
    ↓
Sieć domowa 192.168.0.0/24
    ├── ML350p
    ├── NAS
    ├── Router
    └── inne urządzenia

Instalacja Raspberry Pi OS

Przy użyciu Raspberry Pi Imager nagrałem Raspberry Pi OS.

Podczas tworzenia karty SD od razu skonfigurowałem:

  • SSH
  • nazwę hosta
  • użytkownika
  • hasło
  • połączenie Wi-Fi

Po uruchomieniu Raspberry połączyłem się przez SSH:

ssh pi@192.168.0.101

Instalacja WireGuard

Aktualizacja pakietów:

sudo apt update

Instalacja WireGuard:

sudo apt install wireguard

Sprawdzenie instalacji:

wg --version

Generowanie kluczy serwera

Przejście do katalogu WireGuard:

sudo mkdir -p /etc/wireguard
cd /etc/wireguard

Generowanie kluczy:

sudo -i

umask 077

wg genkey | tee privatekey | wg pubkey > publickey

Wyświetlenie klucza publicznego:

cat publickey

Konfiguracja serwera

Utworzenie pliku:

nano /etc/wireguard/wg0.conf

Konfiguracja:

[Interface]
Address = 10.9.0.1/24
ListenPort = 51820
PrivateKey = KLUCZ_PRYWATNY_SERWERA

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -A FORWARD -o wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE

PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -o wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE

W moim przypadku Raspberry było połączone przez Wi-Fi, dlatego użyłem interfejsu wlan0.

Nazwę interfejsu można sprawdzić:

ip route | grep default

Włączenie routingu IP

Sprawdzenie aktualnego stanu:

sysctl net.ipv4.ip_forward

Jeżeli wynik wynosi:

net.ipv4.ip_forward = 0

należy utworzyć plik:

sudo nano /etc/sysctl.d/99-wireguard.conf

i dodać:

net.ipv4.ip_forward=1

Następnie:

sudo sysctl --system

Weryfikacja:

sysctl net.ipv4.ip_forward

Powinno zwrócić:

net.ipv4.ip_forward = 1

Dodanie telefonu z androidem

Generowanie kluczy klienta:

wg genkey | tee phone_private.key | wg pubkey > phone_public.key

Dodanie klienta do konfiguracji serwera:

[Peer]
PublicKey = KLUCZ_PUBLICZNY_TELEFONU
AllowedIPs = 10.9.0.2/32

Restart WireGuard:

sudo systemctl restart wg-quick@wg0

Konfiguracja telefonu

Utworzenie pliku:

nano phone.conf

Przykład:

[Interface]
PrivateKey = KLUCZ_PRYWATNY_TELEFONU
Address = 10.9.0.2/24
DNS = 192.168.0.1

[Peer]
PublicKey = KLUCZ_PUBLICZNY_SERWERA
Endpoint = PUBLICZNE_IP:51820
AllowedIPs = 192.168.0.0/24,10.9.0.0/24
PersistentKeepalive = 25

Generowanie kodu QR

Instalacja:

sudo apt install qrencode

Wygenerowanie kodu:

qrencode -t ansiutf8 < phone.conf

lub do pliku PNG:

qrencode -t png -o phone.png < phone.conf

albo do terminala:

qrencode -t ansiutf8 < /etc/wireguard/phone.conf

Następnie wystarczy zeskanować kod w aplikacji WireGuard na telefonie.

Konfiguracja routera

Na routerze TP-Link Archer C7 utworzyłem przekierowanie:

Port: 51820
Protokół: UDP
Adres docelowy: 192.168.0.101

czyli adres Raspberry Pi.

Test połączenia

Po wyłączeniu Wi-Fi w telefonie i włączeniu tunelu WireGuard sprawdziłem stan serwera:

sudo wg

Poprawne połączenie wygląda następująco:

latest handshake: 15 seconds ago
transfer: 12.34 KiB received, 8.56 KiB sent

Typowe problemy

Brak handshake

Najczęściej:

  • błędny publiczny adres IP w konfiguracji klienta,
  • błędnie ustawiony port forwarding,
  • nieprawidłowy klucz publiczny serwera.

Błąd „iptables: command not found”

Należy zainstalować pakiet:

sudo apt install iptables

Usługa nie startuje wraz z rebootem

Polecenie, które powoduje automatyczne uruchamianie WireGuarda po każdym restarcie systemu, to:

sudo systemctl enable wg-quick@wg0

To tworzy wpis w systemd, dzięki któremu przy starcie systemu zostanie wykonane coś równoważnego:

sudo wg-quick up wg0

Można sprawdzić, czy jest włączone:

sudo systemctl is-enabled wg-quick@wg0

Jeżeli wynikiem jest:

enabled

to VPN będzie startował automatycznie po każdym reboocie.

Przydatne polecenia:

sudo systemctl start wg-quick@wg0    # uruchom teraz
sudo systemctl stop wg-quick@wg0 # zatrzymaj
sudo systemctl restart wg-quick@wg0 # restart
sudo systemctl disable wg-quick@wg0 # wyłącz autostart

Po restarcie można szybko sprawdzić, czy tunel wstał:

sudo wg

Efekt końcowy

Po migracji WireGuard działa na Raspberry Pi 3B pobierającym kilka watów energii, a dostęp do całej sieci domowej jest możliwy bez konieczności utrzymywania dużego serwera ML350p włączonego przez całą dobę.

Dzięki temu mogę łączyć się z:

  • iLO 4 aby zarządzać uruchomieniem serwera ML350p
  • innymi serwerami w sieci lokalnej,
  • udziałami sieciowymi,
  • urządzeniami administracyjnymi,

przy minimalnym zużyciu energii.

Dodaj komentarz

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