Raspberry Pi + CentOS = Wi-Fi Hotspot (lub malinowy router w czerwonej czapce)

W Internecie jest ogromna ilość informacji na temat tworzenia punktów dostępowych Wi-Fi opartych na jednopłytkowym komputerze Raspberry. Zazwyczaj zakłada się użycie natywnego systemu operacyjnego dla „malinki” — Raspbian.

Będąc zwolennikiem systemów opartych na RPM, nie mogłem przejść obojętnie obok tego małego cudu i nie wypróbować na nim mojej ulubionej CentOS.

W artykule przedstawiona jest instrukcja na temat tworzenia routera Wi-Fi 5GHz/AC z Raspberry Pi 3 Model B+ działającego na systemie operacyjnym CentOS. Będzie kilka standardowych, ale mało znanych trików, a jako bonus — schemat podłączenia dodatkowego sprzętu Wi-Fi do „malinki”, pozwalającego jej jednocześnie pracować w kilku trybach (2,4+5GHz).

Raspberry Pi + CentOS = Wi-Fi Hotspot (lub malinowy router w czerwonej czapce)
(miks zdjęć z domeny publicznej)

Zaznaczam od razu, że nie osiągniesz jakichś kosmicznych prędkości. Wyciągam z mojej „malinki” maksymalnie 100 Mbit w powietrzu, co pokrywa prędkość mojego dostawcy Internetu. Po co potrzebny taki wolny AC, skoro na N teoretycznie można osiągnąć pół gigabita? Jeżeli zadajesz sobie takie pytanie, wybierz się do sklepu po prawdziwy router z ośmioma zewnętrznymi antenami.

0. Co będzie potrzebne

  • Samo „malinowe” urządzenie kaliber: Pi 3 Model B+ (aby osiągnąć wymarzone prędkości 5GHz i kanały);
  • Porządna microSD >= 4GB;
  • Stacja robocza z Linuxem i czytnikiem/zapisującym microSD;
  • Posiadanie odpowiednich umiejętności w Linuxie, artykuł - dla przygotowanego Geeka;
  • Połączenie przewodowe (eth0) między Raspberry a Linuxem, działający serwer DHCP w lokalnej sieci oraz dostęp do Internetu z obu urządzeń.

Mały komentarz do ostatniego punktu. „Co było pierwsze, jajko czy…” jak zrobić router Wi-Fi przy braku jakiegokolwiek sprzętu umożliwiającego dostęp do Internetu? Zostawmy ten interesujący problem poza zasięgiem artykułu i po prostu załóżmy, że Raspberry jest podłączona do lokalnej sieci kablem i ma dostęp do Internetu. W takim przypadku nie potrzebujemy dodatkowego telewizora ani manipulatora do konfiguracji „malinki”.

1. Instalacja CentOS

Strona główna projektu

W momencie pisania tego artykułu, działająca wersja CentOS na urządzeniu to 32-bitowa. Gdzieś w zakamarkach sieci natknąłem się na opinie o spadku wydajności takich systemów na 64-bitowej architekturze ARM aż o 20%. Ten aspekt pozostawię bez komentarza.

Na Linuxie ściągamy minimalny obraz z jądrem „-RaspberryPI-» i zapisujemy go na microSD:

# xzcat CentOS-Userland-7-armv7hl-RaspberryPI-Minimal-1810-sda.raw.xz | 
  dd of=/dev/mmcblk0 bs=4M
# sync

Przed rozpoczęciem korzystania z obrazu usuńmy z niego partycję SWAP, rozszerzmy główną na całą dostępną przestrzeń i pozbądźmy się SELinux. Algorytm jest prosty: robimy kopię głównej na Linuxie, usuwamy z microSD wszystkie partycje oprócz pierwszej (\/boot), tworzymy nową główną i przywracamy jej zawartość z kopii.

Przykład niezbędnych działań (surowy wyjście konsoli)

# mount /dev/mmcblk0p3 /mnt
# cd /mnt
# tar cfz ~/pi.tgz . --no-selinux
# cd
# umount /mnt

# parted /dev/mmcblk0

(parted) unit s
(parted) print free
Model: SD SC16G (sd/mmc)
Disk /dev/mmcblk0: 31116288s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start     End        Size       Type     File system     Flags
        63s       2047s      1985s               Free Space
 1      2048s     1370111s   1368064s   primary  fat32           boot, lba
 2      1370112s  2369535s   999424s    primary  linux-swap(v1)
 3      2369536s  5298175s   2928640s   primary  ext4
        5298176s  31116287s  25818112s           Free Space

(parted) rm 3
(parted) rm 2

(parted) print free
Model: SD SC16G (sd/mmc)
Disk /dev/mmcblk0: 31116288s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start     End        Size       Type     File system  Flags
        63s       2047s      1985s               Free Space
 1      2048s     1370111s   1368064s   primary  fat32        boot, lba
        1370112s  31116287s  29746176s           Free Space

(parted) mkpart
Partition type?  primary/extended? primary
File system type?  [ext2]? ext4
Start? 1370112s
End? 31116287s

(parted) set
Partition number? 2
Flag to Invert? lba
New state?  on/[off]? off

(parted) print free
Model: SD SC16G (sd/mmc)
Disk /dev/mmcblk0: 31116288s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start     End        Size       Type     File system  Flags
        63s       2047s      1985s               Free Space
 1      2048s     1370111s   1368064s   primary  fat32        boot, lba
 2      1370112s  31116287s  29746176s  primary  ext4

(parted) quit

# mkfs.ext4 /dev/mmcblk0p2 
mke2fs 1.44.6 (5-Mar-2019)
/dev/mmcblk0p2 contains a swap file system labelled '_swap'
Proceed anyway? (y,N) y
Discarding device blocks: done                            
Creating filesystem with 3718272 4k blocks and 930240 inodes
Filesystem UUID: 6a1a0694-8196-4724-a58d-edde1f189b31
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done   

# mount /dev/mmcblk0p2 /mnt
# tar xfz ~/pi.tgz -C /mnt --no-selinux

Po rozpakowaniu zawartości głównej partycji nadszedł czas na wprowadzenie w niej kilku zmian.

Wyłączamy SELinux w /mnt/etc/selinux/config:

SELINUX=disabled

Edycja /mnt/etc/fstab, pozostawiając w nim tylko dwa wpisy o partycjach: startową (\/boot, bez zmian) i główną (zmieniamy wartość UUID, którą można poznać, analizując wyjście polecenia blkid w Linuxie):

UUID=6a1a0694-8196-4724-a58d-edde1f189b31  \/     ext4    defaults,noatime 0 0
UUID=6938-F4F2                             \/boot vfat    defaults,noatime 0 0

Na koniec zmieniamy parametry ładowania jądra: wskazujemy nowe położenie głównej partycji, wyłączamy wyjście informacji debugowania i (opcjonalnie) zabraniając jądru przydzielania adresów IPv6 na interfejsach sieciowych:

# cd
# umount /mnt
# mount /dev/mmcblk0p1 /mnt

Zmieniamy zawartość /mnt/cmdline.txt na następującą (jedna linia bez łamań):

root=\/dev\/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait quiet ipv6.disable_ipv6=1

Gotowe:

# cd
# umount /mnt
# sync

Przestawiamy microSD do "malinki", uruchamiamy i uzyskujemy do niej dostęp sieciowy przez ssh (root\/centos).

2. Konfiguracja CentOS

Trzy pierwsze niezmienne kroki: passwd, yum -y update, reboot.

Zarządzanie siecią oddajemy networkd:

# yum install systemd-networkd
# systemctl enable systemd-networkd
# systemctl disable NetworkManager
# chkconfig network off

Tworzymy plik (razem z katalogami) /etc/systemd/network/eth0.network:

[Match]
Name=eth0

[Network]
DHCP=ipv4

Restartujemy "malinkę" i ponownie uzyskujemy dostęp do niej przez ssh (adres IP może się zmienić). Zwróć uwagę, że do użytku jest /etc/resolv.conf, utworzony wcześniej przez Network Managera. Dlatego w przypadku problemów z resolve, edytuj jego zawartość. Nie użyjemy systemd-resolved .

Usuwamy "zbędne", naprawiamy i przyspieszamy ładowanie systemu operacyjnego:

# systemctl set-default multi-user.target
# yum remove GeoIP Network* aic* alsa* cloud-utils-growpart 
  cronie* dhc* firewal* initscripts iwl* kexec* logrotate 
  postfix rsyslog selinux-pol* teamd wpa_supplicant

Kto potrzebuje cron i kto nie akceptuje wbudowanych timerów systemd, mogą zainstalować brakujące. /var/log- i patrzymy przez journalctl. Jeśli potrzebna jest historia dziennika (domyślnie przechowywane są tylko informacje od momentu uruchomienia systemu):

# mkdir /var/log/journal
# systemd-tmpfiles --create --prefix /var/log/journal
# systemctl restart systemd-journald
# vi /etc/systemd/journald.conf

Wyłączamy użycie IPv6 przez główne usługi (jeśli to konieczne)/etc/ssh/sshd_config:

AddressFamily inet

/etc/sysconfig/chronyd:

OPTIONS="-4"

Aktualność czasu na "malince" to ważna sprawa. Ponieważ "z pudełka" brakuje możliwości sprzętowej do zachowania aktualnego stanu zegara przy ponownym uruchomieniu, potrzebna jest synchronizacja. Bardzo dobry i szybki demon do tego — chrony — już jest zainstalowany i uruchamia się automatycznie. Można zmienić serwery NTP na najbliższe.

/etc/chrony.conf:

server 0.ru.pool.ntp.org iburst
server 1.ru.pool.ntp.org iburst
server 2.ru.pool.ntp.org iburst
server 3.ru.pool.ntp.org iburst

Do ustawienia strefy czasowej wykorzystamy sztuczkę. Ponieważ naszym celem jest stworzenie routera Wi-Fi działającego na częstotliwościach 5GHz, wcześniej przygotujemy się na niespodzianki regulatora:

# yum info crda
Podsumowanie: Demon zgodności regulacyjnej dla sieci bezprzewodowych 802.11

Ta złośliwa konstrukcja, kierując się między innymi strefą czasową, "zabrania" używania (w Rosji) częstotliwości 5GHz i kanałów z "dużymi" numerami. Sztuczka polega na ustawieniu strefy czasowej bez użycia nazw kontynentów/miast, tzn. zamiast:

# timedatectl set-timezone Europe/Moscow

Wciskamy:

# timedatectl set-timezone Etc/GMT-3

A ostatnie szlify w stylizacji systemu:

# hostnamectl set-hostname router

/root/.bash_profile:

. . .

# Środowisko użytkownika i programy uruchamiające

export PROMPT_COMMAND="vcgencmd measure_temp"
export LANG=en_US.UTF-8
export PATH=$PATH:$HOME/bin

3. Dodatki CentOS

Wszystko, co zostało powiedziane powyżej, można uznać za zakończoną instrukcję instalacji "waniliowego" CentOS na Raspberry Pi. Powinieneś otrzymać PC, który (prze)uruchamia się w mniej niż 10 sekund, używa mniej niż 15 MB pamięci RAM i 1.5 GB microSD (w rzeczywistości mniej niż 1 GB z powodu niepełnego /boot, ale bądźmy szczerzy do końca).

Aby zainstalować oprogramowanie punktu dostępowego Wi-Fi na tym systemie, trzeba nieco rozszerzyć możliwości standardowego dystrybucji CentOS. Przede wszystkim "ulepszymy" sterownik (firmware) wbudowanego adaptera Wi-Fi. Na stronie głównej projektu jest napisane:

Wifi na Raspberry 3B i 3B+

Pliki firmware Raspberry PI 3B/3B+ nie mogą być dystrybuowane przez projekt CentOS. Możesz skorzystać z następujących artykułów, aby zrozumieć problem, zdobyć firmware i skonfigurować wifi.

Czego projektowi CentOS zabrania, to nie jest zabronione nam do użytku osobistego. Zastępujemy dystrybucyjną wersję Wi-Fi w CentOS odpowiednią od twórców Broadcom (tych samych nienawidzonych binarnych blobów…). To, między innymi, pozwoli korzystać z AC w trybie punktu dostępowego.

Aktualizacja firmware Wi-FiUstalamy model urządzenia i bieżącą wersję firmware:

# journalctl | grep $(basename $(readlink /sys/class/net/wlan0/device/driver))
Jan 01 04:00:03 router kernel: brcmfmac: F1 signature read @0x18000000=0x15264345
Jan 01 04:00:03 router kernel: brcmfmac: brcmf_fw_map_chip_to_name: using brcm/brcmfmac43455-sdio.bin for chip 0x004345(17221) rev 0x000006
Jan 01 04:00:03 router kernel: usbcore: registered new interface driver brcmfmac
Jan 01 04:00:03 router kernel: brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Mar  1 2015 07:29:38 version 7.45.18 (r538002) FWID 01-6a2c8ad4
Jan 01 04:00:03 router kernel: brcmfmac: brcmf_c_preinit_dcmds: CLM version = API: 12.2 Data: 7.14.8 Compiler: 1.24.9 ClmImport: 1.24.9 Creation: 2014-09-02 03:05:33 Inc Data: 7.17.1 Inc Compiler: 1.26.11 Inc ClmImport: 1.26.11 Creation: 2015-03-01 07:22:34 

Widząc, że wersja firmware 7.45.18 z 01.03.2015, zapamiętujemy następny zestaw cyfr: 43455 (brcmfmac43455-sdio.bin).

Pobieramy aktualny obraz Raspbian. Lenie mogą zapisać obraz na microSD i stamtąd pobrać pliki z firmware. Można również zamontować główną partycję obrazu w Linuxie i skopiować potrzebne stamtąd:

# wget https://downloads.raspberrypi.org/raspbian_lite_latest
# unzip -p raspbian_lite_latest > raspbian.img
# fdisk -l raspbian.img
Disk raspbian.img: 2 GiB, 2197815296 bytes, 4292608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x17869b7d

Device        Boot  Start     End Sectors  Size Id Type
raspbian.img1        8192  532480  524289  256M  c W95 FAT32 (LBA)
raspbian.img2      540672 4292607 3751936  1.8G 83 Linux

# mount -t ext4 -o loop,offset=$((540672 * 512)) raspbian.img /mnt
# cp -fv /mnt/lib/firmware/brcm/*43455* ...
'/mnt/lib/firmware/brcm/brcmfmac43455-sdio.bin' -> ...
'/mnt/lib/firmware/brcm/brcmfmac43455-sdio.clm_blob' -> ...
'/mnt/lib/firmware/brcm/brcmfmac43455-sdio.txt' -> ...
# umount /mnt

Otrzymane pliki firmware adaptera Wi-Fi należy skopiować z zastąpieniem na "malince" do katalogu /usr/lib/firmware/brcm/

Resetujemy przyszły router i uśmiechamy się szeroko:

# journalctl | grep $(basename $(readlink /sys/class/net/wlan0/device/driver))
Jan 01 04:00:03 router kernel: brcmfmac: F1 signature read @0x18000000=0x15264345
Jan 01 04:00:03 router kernel: brcmfmac: brcmf_fw_map_chip_to_name: using brcm/brcmfmac43455-sdio.bin for chip 0x004345(17221) rev 0x000006
Jan 01 04:00:03 router kernel: usbcore: registered new interface driver brcmfmac
Jan 01 04:00:03 router kernel: brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Feb 27 2018 03:15:32 version 7.45.154 (r684107 CY) FWID 01-4fbe0b04
Jan 01 04:00:03 router kernel: brcmfmac: brcmf_c_preinit_dcmds: CLM version = API: 12.2 Data: 9.10.105 Compiler: 1.29.4 ClmImport: 1.36.3 Creation: 2018-03-09 18:56:28 

Wersja: 7.45.154 z 27.02.2018.

Oczywiście, EPEL:

# cat > /etc/yum.repos.d/epel.repo << EOF
[epel]
name=Epel rebuild for armhfp
baseurl=https://armv7.dev.centos.org/repodir/epel-pass-1/
enabled=1
gpgcheck=0
EOF

# yum clean all
# rm -rfv /var/cache/yum
# yum update

4. Konfiguracja sieciowa i nadchodzące trudności

Jak ustaliliśmy wcześniej, „malinka” jest podłączona „przewodem” do lokalnej sieci. Załóżmy, że dostawca również zapewnia dostęp do Internetu dokładnie w ten sam sposób: adres w sieci publicznej jest przydzielany dynamicznie przez serwer DHCP (może być powiązany z MAC). W takim przypadku, po zakończeniu konfiguracji „malinki”, wystarczy „włożyć” do niej kabel od dostawcy i wszystko jest gotowe. Autoryzacja za pomocą systemd-networkd — to temat na osobny artykuł i tutaj nie jest omawiany.

Interfejs(y) Wi-Fi w Raspberry — to lokalna sieć, a wbudowany adapter Ethernet (eth0) — zewnętrzny. Numerujemy lokalną sieć statycznie, na przykład: 192.168.0.0/24. Adres „malinki”: 192.168.0.1. W zewnętrznej sieci (Internecie) będzie działał serwer DHCP.

Problem jednolitości nazewnictwa i znany programista z Gwatemali — to dwie nieprzyjemności, które czekają na każdego, kto zajmuje się konfiguracją interfejsów sieciowych i usług w dystrybucjach systemu systemd.

Równoległy chaos (lyryczne dygresja)Lennart Poettering stworzył swój program systemd bardzo dobrze. Ten systemd uruchamia inne programy tak szybko, że te, nie zdążywszy dojść do siebie po gwizdku sędziów, potykają się i padają na starcie nawet nie zaczynając swojego biegu przez przeszkody.

Jednak na poważnie, agresywne równoległe uruchamianie procesów podczas startu systemu systemd jest pewnym „osłowym mostkiem” dla doświadczonych zwolenników LSB. Na szczęście uporządkowanie tego „równoległego chaosu” okazuje się proste, choć nie zawsze oczywiste.

Tworzymy dwa wirtualne mosty (bridge) z stałymi nazwami: lan i wan. Do pierwszego „podłączamy” adapter(y) Wi-Fi, do drugiego — eth0 „malinki”.

/etc/systemd/network/lan.netdev:

[NetDev]
Name=lan
Kind=bridge

/etc/systemd/network/lan.network:

[Match]
Name=lan

[Network]
Address=192.168.0.1/24
IPForward=yes

/etc/systemd/network/wan.netdev:

[NetDev]
Name=wan
Kind=bridge
#MACAddress=xx:xx:xx:xx:xx:xx

/etc/systemd/network/wan.network:

[Match]
Name=wan

[Network]
DHCP=ipv4
IPForward=yes

IPForward=yes uwalnia nas od konieczności nakłaniania jądra do włączenia routingu przez sysctl.
MACAddress= odkomentujemy i zmienimy w razie potrzeby.

Najpierw „podłączamy” eth0. Pamiętamy o „problemie jednolitości” i używamy tylko adresu MAC tego interfejsu, który można poznać, na przykład w ten sposób:

# cat /sys/class/net/eth0/address 

Tworzymy /etc/systemd/network/eth.network:

[Match]
MACAddress=b8:27:eb:xx:xx:xx

[Network]
Bridge=wan

Usuwamy poprzedni plik konfiguracyjny eth0, uruchamiamy ponownie „malinkę” i uzyskujemy do niej dostęp sieciowy (adres IP prawdopodobnie się zmieni):

# rm -fv /etc/systemd/network/eth0.network
# reboot

5. DNSMASQ

Nie wymyślono lepszego sposobu na tworzenie punktów dostępowych Wi-Fi niż słodki duet z dnsmasq + hostapd jeszcze nie wymyślono. Moim zdaniem.

Jeśli ktoś zapomniał, to…hostapd — to narzędzie, które zarządza adapterami Wi-Fi (w szczególności podejmie się zadania ich łączenia z wirtualnym lan „malinką”), autoryzuje i rejestruje klientów bezprzewodowych.

dnsmasq — konfiguruje stos sieciowy klientów: przydziela adresy IP, serwery DNS, bramę domyślną i inne tego typu udogodnienia.

Zaczynamy od dnsmasq:

# yum install dnsmasq

Szablon /etc/resolv.conf:

nameserver 1.1.1.1
nameserver 1.0.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 77.88.8.8
nameserver 77.88.8.1
domain router.local
search router.local

edytujemy go według własnych upodobań.

Minimalistyczny /etc/dnsmasq.conf:

domain-needed
bogus-priv
interface=lan
bind-dynamic
expand-hosts
domain=#
dhcp-range=192.168.0.100,192.168.0.199,255.255.255.0,24h
conf-dir=/etc/dnsmasq.d

„Magia” polega na parametrze bind-dynamic, który nakazuje demonowi dnsmasq czekać na pojawienie się w systemie interface=lan, zamiast padać w omdlenie z powodu dumnej samotności po uruchomieniu.

# systemctl enable dnsmasq
# systemctl start dnsmasq; journalctl -f

6. HOSTAPD

I w końcu, magiczne konfiguracje hostapd. Nie mam wątpliwości, że ktoś czyta ten artykuł w poszukiwaniu tych wymarzonych linii.

Przed zainstalowaniem hostapd trzeba zmierzyć się z „problemem jednolitości”. Wbudowany adapter Wi-Fi wlan0 może łatwo zmienić swoją nazwę na wlan1 przy podłączeniu dodatkowego sprzętu USB Wi-Fi. Dlatego ustalimy nazwy interfejsów w następujący sposób: wymyślimy (bezprzewodowym) adapterom unikalne nazwy i powiążemy je z adresami MAC.

Dla wbudowanego adaptera Wi-Fi, który wciąż jest wlan0:

# cat /sys/class/net/wlan0/address 
b8:27:eb:xx:xx:xx

Tworzymy /etc/systemd/network/wl0.link:

[Match]
MACAddress=b8:27:eb:xx:xx:xx

[Link]
Name=wl0

Teraz będziemy mieć pewność, że wl0 — to wbudowane Wi-Fi. Uruchamiamy ponownie „malinkę”, aby się o tym przekonać.

Instalujemy:

# yum install hostapd wireless-tools

Plik konfiguracyjny /etc/hostapd/hostapd.conf:

ssid=rpi
wpa_passphrase=1234567890

channel=36

country_code=US

interface=wl0
bridge=lan

driver=nl80211

auth_algs=1
wpa=2
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

macaddr_acl=0

hw_mode=a
wmm_enabled=1

# N
ieee80211n=1
require_ht=1
ht_capab=[MAX-AMSDU-3839][HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]

# AC
ieee80211ac=1
require_vht=1
ieee80211d=0
ieee80211h=0
vht_capab=[MAX-AMSDU-3839][SHORT-GI-80]
vht_oper_chwidth=1
vht_oper_centr_freq_seg0_idx=42

Nie zapominając ani na chwilę o GKChP, zmieniamy wymagane parametry i ręcznie sprawdzamy ich działanie:

# hostapd /etc/hostapd/hostapd.conf

hostapd uruchomi się w trybie interaktywnym, wyświetlając swoje stany na konsoli. Jeśli nie wystąpią błędy, klienci obsługujący tryb AC będą mogli połączyć się z punktem dostępu. Aby zatrzymać hostapd — Ctrl-C.

Musisz jeszcze dodać hostapd do autostartu systemu. Jeśli postąpisz standardowo (systemctl enable hostapd), po kolejnej ponownej rozruchu możesz otrzymać "leżącego w krwi" demona z diagnozą "interfejs wl0 nie znaleziony". W rezultacie "równoległego chaosu" hostapd uruchomił się szybciej, niż jądro znalazło adapter bezprzewodowy.

W Internecie jest mnóstwo rozwiązań: od wymuszonego opóźnienia przed uruchomieniem demona (na kilka minut) po innego demona, który monitoruje pojawienie się interfejsu i (ponownie) uruchamia hostapd. Rozwiązania są całkiem działające, ale strasznie nieestetyczne. Wzywamy na pomoc wielkiego systemd z jego "celami" i "zadaniami" "zależnościami".

Kopiujemy plik service z dystrybucji do /etc/systemd/system/hostapd.service:

# cp -fv /usr/lib/systemd/system/hostapd.service /etc/systemd/system

i przekształcamy jego zawartość w następujący sposób:

[Unit]
Description=Hostapd IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Autoryzator
After=sys-subsystem-net-devices-wl0.device
BindsTo=sys-subsystem-net-devices-wl0.device

[Service]
Type=forking
PIDFile=/run/hostapd.pid
ExecStart=/usr/sbin/hostapd /etc/hostapd/hostapd.conf -P /run/hostapd.pid -B

[Install]
WantedBy=sys-subsystem-net-devices-wl0.device

Magia zaktualizowanego pliku serwisowego polega na dynamicznym powiązaniu hostapd z nowym celem — interfejsem wl0. Gdy interfejs się pojawi — demon się uruchamia, a gdy znika — zatrzymuje się. I to wszystko online — bez ponownego uruchamiania systemu. Ta technika będzie szczególnie przydatna przy podłączaniu do "malinki" adaptera Wi-Fi USB.

Teraz można:

# systemctl enable hostapd
# reboot

7. IPTABLES

"Co???" © Tak, tak! Żadnego systemd. Żadnych nowoczesnych kombajnów (w postaci firewalld), które w efekcie robią to samo.

Używamy starego, dobrego iptables, którego usługi po uruchomieniu załadują do jądra zasady sieciowe i spokojnie zakończą działanie, nie pozostając w pamięci i nie zużywając zasobów. systemd ma elegancką IPMasquerade=, ale translację adresów (NAT) i zaporę powierzymy w końcu iptables.

Instalujemy:

# yum install iptables-services
# systemctl enable iptables ip6tables

Preferuję przechowywać konfigurację iptables w postaci skryptu (przykład):

#!/bin/bash

#
# Disable IPv6
#
ip6tables --flush
ip6tables --delete-chain

ip6tables --policy INPUT   DROP
ip6tables --policy FORWARD DROP
ip6tables --policy OUTPUT  DROP

ip6tables-save > /etc/sysconfig/ip6tables
systemctl restart ip6tables

#
# Cleaning
#
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

#
# Loopback, lan
#
iptables -A INPUT -i lo  -j ACCEPT
iptables -A INPUT -i lan -j ACCEPT

#
# Ping, Established
#
iptables -A INPUT -p icmp  --icmp-type echo-request    -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#
# NAT
#
iptables -t nat -A POSTROUTING -o wan -j MASQUERADE

#
# Saving
#
iptables-save > /etc/sysconfig/iptables
systemctl restart iptables

Wykonujemy powyższy skrypt i tracimy możliwość nawiązywania nowych przewodowych połączeń SSH z "malinką". Wszystko się zgadza, stworzyliśmy router Wi-Fi, do którego dostęp "przez Internet" jest domyślnie zabroniony — teraz tylko "przez powietrze". Podłączamy kabel od dostawcy do Ethernetu i zaczynamy surfować!

8. Bonus: +2,4GHz

Kiedy złożyłem pierwszy router Raspberry zgodnie z powyższym schematem, odkryłem, że w moim gospodarstwie znajdują się pewne urządzenia, które z powodu swoich ograniczeń konstrukcyjnych nie mogły w ogóle zobaczyć „maliny” przez Wi-Fi. Przełączanie routera na pracę w 802.11b/g/n było nieco nieFair, ponieważ maksymalna prędkość „w powietrzu” w takim przypadku nie przekraczała 40 Mbit, podczas gdy mój ulubiony dostawca Internetu oferuje mi 100 (po kablu).

W rzeczywistości rozwiązanie problemu już zostało wymyślone: drugi interfejs Wi-Fi, działający na częstotliwości 2,4 GHz, oraz drugi punkt dostępu. W najbliższym sklepie kupiłem nie pierwszy, a drugi możliwy mi USB Wi-Fi „dongle”. Sprzedawca był zasypywany pytaniami o chip, zgodność z rdzeniami ARM na Linuxie oraz o możliwość pracy w trybie AP (to on zaczął).

Konfigurujemy „dongle” analogicznie do wbudowanego adaptera Wi-Fi.

Najpierw — zmieńmy jego nazwę na wl1:

# cat /sys/class/net/wlan0/address 
b0:6e:bf:xx:xx:xx

/etc/systemd/network/wl1.link:

[Match]
MACAddress=b0:6e:bf:xx:xx:xx

[Link]
Name=wl1

Zarządzaniem nowym interfejsem Wi-Fi zajmie się osobny demon hostapd, który będzie uruchamiany i zatrzymywany w zależności od obecności w systemie ściśle określonego „dongla”: wl1.

Plik konfiguracyjny /etc/hostapd/hostapd2.conf:

ssid=rpi2
wpa_passphrase=1234567890

#channel=1
#channel=6
channel=11

interface=wl1
bridge=lan

driver=nl80211

auth_algs=1
wpa=2
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

macaddr_acl=0

hw_mode=g
wmm_enabled=1

# N
ieee80211n=1
require_ht=1
ht_capab=[HT40][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]

Zawartość tego pliku bezpośrednio zależy od modelu USB Wi-Fi adaptera, dlatego banalne skopiowanie/wklejenie może Cię zawieść.

Kopiujemy plik service z dystrybucji do /etc/systemd/system/hostapd2.service:

# cp -fv /usr/lib/systemd/system/hostapd.service /etc/systemd/system/hostapd2.service

i przekształcamy jego zawartość w następujący sposób:

[Unit]
Description=Hostapd IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
After=sys-subsystem-net-devices-wl1.device
BindsTo=sys-subsystem-net-devices-wl1.device

[Service]
Type=forking
PIDFile=/run/hostapd2.pid
ExecStart=/usr/sbin/hostapd /etc/hostapd/hostapd2.conf -P /run/hostapd2.pid -B

[Install]
WantedBy=sys-subsystem-net-devices-wl1.device

Pozostało tylko uruchomić nową instancję hostapd:

# systemctl enable hostapd2

I to wszystko! Podłącz „dongle” oraz sama „malinę”, sprawdź dostępne sieci bezprzewodowe wokół.

Na koniec chcę ostrzec o jakości adaptera USB Wi-Fi i zasilania Raspberry. Podłączony „na gorąco dongle” może czasami powodować „zawieszenie maliny” z powodu krótkotrwałych problemów elektrycznych.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster