Raspberry Pi jako Wi-Fi access point bez NATu
Bridged Wi-Fi access point bez NATu znamená, že zařízení připojená přes Wi-Fi dostávají IP adresu ze stejného routeru a ze stejného rozsahu jako zbytek sítě. Tento postup vychází hlavně z návodu na Charlieblogu a z návodu k bridged AP od morrownr, ale doplňuje praktické poznámky z provozu na OSMC a zkušenosti s konkrétními USB Wi-Fi adaptéry.
Princip zapojení
Cílem je, aby Raspberry Pi nevystupovalo jako další router s vlastním NATem a vlastním DHCP serverem. Místo toho se vytvoří bridge br0, do kterého se zařadí ethernet a Wi-Fi rozhraní. Klienti připojení přes Wi-Fi pak komunikují přímo do stávající LAN a IP adresu jim přiděluje už existující router.
V mém případě Raspberry Pi původně používalo ethernet eth0 a Wi-Fi rozhraní wlan0 mělo sloužit jako access point. V článku níže je použité statické nastavení IP adresy pro br0, ale princip bridge zůstává stejný i tehdy, pokud si IP bere z DHCP.
Vytvoření bridge
Pro vytvoření bridge jsem použil systemd-networkd. Je potřeba založit zařízení br0, přidat do něj eth0 a síťovou konfiguraci přesunout z ethernetu na bridge.
Soubor /etc/systemd/network/bridge-br0.netdev:
[NetDev] Name=br0 Kind=bridge
Soubor /etc/systemd/network/bridge-br0-slave.network:
[Match] Name=eth0 [Network] Bridge=br0
Soubor /etc/systemd/network/bridge-br0.network:
[Match] Name=br0 [Network] Address=192.168.0.100/24 Gateway=192.168.0.1 DNS=8.8.8.8
Po změně konfigurace jsem restartoval systemd-networkd:
systemctl restart systemd-networkd
Tím vznikl bridge br0 a IP adresa se přiřazuje jemu místo samotného eth0.
OSMC a Connman
V praxi jsem narazil na problém, že se síť po restartu buď nenačetla správně, nebo se po delší době rozbilo DNS či samotné přidělení IP adresy. Příčina byla v tom, že vedle systemd-networkd se síť snažil spravovat ještě další démon.
Ve zdrojových návodech se často doporučuje upravit /etc/dhcpcd.conf a přidat:
denyinterfaces eth0 denyinterfaces wlan0
Na OSMC mi ale tenhle postup nepomohl. Nakonec jsem dohledal, že OSMC používá Connman, takže bylo potřeba blacklistovat rozhraní právě tam.
Soubor /etc/connman.conf:
NetworkInterfaceBlacklist=eth0,wlan0
Tím se vyřešil konflikt mezi více službami, které se snažily obsluhovat stejná rozhraní.
Konfigurace hostapd
Poslední krok je nastavit Wi-Fi rozhraní do AP režimu a zařadit ho do bridge. K tomu slouží hostapd. Prakticky důležitý je hlavně řádek bridge=br0.
apt install hostapd
Příklad konfigurace /etc/hostapd/hostapd.conf:
ssid=myPI-5g wpa_passphrase=myPW1234 hw_mode=a channel=36 vht_oper_chwidth=1 vht_oper_centr_freq_seg0_idx=42 country_code=CZ bridge=br0 interface=wlan0 driver=nl80211 ieee80211d=1 beacon_int=100 dtim_period=2 max_num_sta=32 macaddr_acl=0 wpa=2 rsn_pairwise=CCMP wpa_key_mgmt=WPA-PSK ieee80211n=1 wmm_enabled=1 ht_capab=[HT40+][HT40-][SHORT-GI-20][SHORT-GI-40] ieee80211ac=1 vht_capab=[SHORT-GI-80]
V některých případech je ještě potřeba odblokovat Wi-Fi přes ''rfkill'':
rfkill unblock wlan
Potom už stačí hostapd spustit a otestovat, že se klient připojí do stejné sítě jako zbytek LAN:
hostapd -c /etc/hostapd/hostapd.conf
Testování propustnosti přes iperf3
Po zprovoznění access pointu je praktické ověřit propustnost přes iperf3.
Instalace:
apt install iperf3
Soubor /etc/systemd/system/iperf3.service:
[Unit] Description=iPerf3 Service After=syslog.target network.target auditd.service [Service] Type=simple ExecStart=/usr/bin/iperf3 -s [Install] WantedBy=multi-user.target
Zapnutí služby:
systemctl enable iperf3
systemctl start iperf3
Test z klientského zařízení:
iperf3 -t 60 -c 192.168.0.100
Zkušenosti s adaptéry
Vedle samotné bridge konfigurace se v praxi ukázalo, že hodně záleží i na konkrétním USB Wi-Fi adaptéru a na kvalitě jeho linuxové podpory.
Tenda W311MI
U adaptéru Tenda W311MI se zařízení po instalaci Raspberry automaticky nenačetlo. Přes lsusb se hlásilo takto:
lsusb Bus 001 Device 005: ID 0bda:b711 Realtek Semiconductor Corp. RTL8188GU 802.11n WLAN Adapter (After Modeswitch)
Pomohla instalace nástrojů a kompilace ovladače podle Ask Ubuntu a repozitáře rtl8188gu:
sudo apt-get install build-essential git dkms bc git clone https://github.com/McMCCRU/rtl8188gu.git cd rtl8188gu make sudo make install sudo reboot
Kvůli chybě při kompilaci jsem ještě musel ručně vytvořit symlink v hlavičkách jádra. Kompiloval jsem přímo na Raspberry Pi:
ln -s /usr/src/linux-headers-5.15.84+/arch/arm /usr/src/linux-headers-5.15.84+/arch/armv6l
Další relevantní diskuse byly v issue rtl8188gu, rtl8723au a na Arch Linux fóru.
MediaTek MT7612U
Druhý použitý adaptér byl MediaTek MT7612U. Vybral jsem ho proto, že podle přehledů projektu USB-WiFi od morrownr má mít podporu přímo v jádře.
lsusb Bus 002 Device 003: ID 0e8d:7612 MediaTek Inc. MT7612U 802.11a/b/g/n/ac Wireless Adapter
Zařízení se mi podařilo rozběhat, ale pozoroval jsem výpadky připojení a zhoršenou rychlost přenosu. Příčinu jsem tehdy nedohledal.
Po zapojení se v dmesg objevovala chyba:
Direct firmware load for mt7662_rom_patch.bin failed with error -2
Pomohlo mi:
apt install firmware-misc-nonfree echo "options mt76_usb disable_usb_sg=1" >> /etc/modprobe.d/mt76_usb.conf apt install crda
A zároveň nastavit regulační doménu:
# /etc/default/crda REGDOMAIN=CZ
Pro spouštění AP jsem pak používal jednoduchý skript:
#!/bin/bash HOSTAPD=$(which hostapd) RFKILL=$(which rfkill) $RFKILL unblock wlan systemctl restart systemd-networkd $HOSTAPD /etc/hostapd/hostapd5-mediatek4.conf
Další poznámky a návody byly v How to Modeswitch, v přehledu 7612u, na fóru OpenWrt a znovu i v návodu k bridged AP.