Raspberry Pi + CentOS = Wi-Fi Hotspot (или малиновый роутер в красной шляпе)

В Интернете огромное количество информации по созданию Wi-Fi точек доступа на базе одноплатного ПК Raspberry. Как правило, подразумевается использование родной для «малинки» операционной системы — Raspbian.

Являясь адептом RPM-based систем, я не мог пройти мимо этого маленького чуда и не попробовать на нем мою любимую CentOS.

В статье представлена инструкция по изготовлению 5GHz/AC Wi-Fi роутера из Raspberry Pi 3 Model B+ на базе операционной системы CentOS. Будет несколько стандартных, но малоизвестных трюков, а в качестве бонуса — чертеж подключения к «малинке» дополнительного Wi-Fi оборудования, позволяющего ей одновременно работать в нескольких режимах (2,4+5GHz).

Raspberry Pi + CentOS = Wi-Fi Hotspot (или малиновый роутер в красной шляпе)
(микс изображений из свободного доступа)

Отметим сразу, что каких-то космических скоростей не получится. Я выжимаю из своей «малинки» по воздуху максимум 100 Мбит, и это покрывает скорость моего Интернет провайдера. Зачем нужен такой вялый AC, если даже на N в теории можно получить полгигабита? Если вы задались таким вопросом, то ступайте в магазин за настоящим роутером с восемью внешними антеннами.

0. Что понадобится

  • Собственно, само «малиновое изделие» калибра: Pi 3 Model B+ (для достижения заветных 5GHz скоростей и каналов);
  • Добротная microSD >= 4GB;
  • Рабочая станция с Linux и читателем/писателем microSD;
  • Наличие достаточных скиллов в Linux, статья — для подготовленного Гика;
  • Проводная сетевая (eth0) связанность между Raspberry и Linux, работающий DHCP-сервер в локальной сети и доступ в Интернет с обоих устройств.

Небольшой комментарий по последнему пункту. «Что появилось первым, яйцо или…» как сделать Wi-Fi роутер при отсутствии какого бы то ни было оборудования доступа в Интернет? Оставим за рамками статьи это занимательное упражнение и просто допустим, что Raspberry подключена к локальной сети проводом и имеет выход в Интернет. В этом случае нам не понадобятся дополнительные телевизор и манипулятор для настройки «малинки».

1. Установка CentOS

Домашняя страница проекта

На момент написания этой статьи, работающая версия CentOS на устройстве — 32-битная. Где-то на просторах всемирной Сети мне попадались мнения о снижении производительности таких ОС на 64-битной архитектуре ARM аж на 20%. Оставлю этот момент без комментария.

На Linux-е качаем минимальный образ с ядром «-RaspberryPI-» и записываем его на microSD:

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

Перед началом использования образа удалим из него раздел SWAP, расширим корень на весь доступный объем и избавимся от SELinux. Алгоритм — простой: делаем копию корня на Linux, удаляем с microSD все разделы кроме первого (/boot), создаем новый корневой и возвращаем его содержимое из копии.

Пример необходимых действий (суровый консольный вывод)

# 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

После распаковки содержимого корневого раздела самое время внести в него некоторые изменения.

Отключаем SELinux в /mnt/etc/selinux/config:

SELINUX=disabled

Редактируем /mnt/etc/fstab, оставляя в нем только две записи о разделах: загрузочный (/boot, без изменений) и корневой (изменяем значение UUID, которое можно узнать, изучив вывод команды blkid на Linux-е):

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

Наконец, изменяем параметры загрузки ядра: указываем новое расположение корневого раздела, отключаем вывод отладочной информации и (опционально) запрещаем ядру назначать IPv6 адреса на сетевых интерфейсах:

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

Приводим содержимое /mnt/cmdline.txt к следующему виду (одна строка без переносов):

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

Готово:

# cd
# umount /mnt
# sync

Переставляем microSD в «малинку», запускаем и получаем к ней сетевой доступ по ssh (root/centos).

2. Настройка CentOS

Первые три незыблемые движения: passwd, yum -y update, reboot.

Управление сетью отдаем networkd:

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

Создаем файл (вместе с каталогами) /etc/systemd/network/eth0.network:

[Match]
Name=eth0

[Network]
DHCP=ipv4

Перезагружаем «малинку» и снова получаем к ней сетевой доступ по ssh (IP-адрес может измениться). Обратите внимание на то, что используется /etc/resolv.conf, созданный ранее Network Manager-ом. Поэтому, в случае проблем с resolve, отредактируйте его содержимое. Использовать systemd-resolved мы не будем.

Удаляем «лишнее», чиним и ускоряем загрузку ОС:

# 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

Кому нужен cron и кто не переваривает встроенные таймеры systemd, могут установить недостающее. /var/log-и смотрим через journalctl. Если потребуется история журнала (по умолчанию хранятся сведения только с момента старта системы):

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

Отключаем использование IPv6 основными службами (если требуется)/etc/ssh/sshd_config:

AddressFamily inet

/etc/sysconfig/chronyd:

OPTIONS="-4"

Актуальность времени на «малинке» — важная штука. Так как «из коробки» отсутствует аппаратная возможность сохранять текущее состояние часов при перезагрузке, то нужна синхронизация. Очень хороший и быстрый демон для этого — chrony — уже установлен и запускается автоматически. Можно изменить NTP-серверы на ближайшие.

/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

Для установки часового пояса будем использовать трюк. Так как наша цель — создание Wi-Fi роутера, работающего на 5GHz частотах, то заранее подготовимся к сюрпризам регулятора:

# yum info crda
Summary: Regulatory compliance daemon for 802.11 wireless networking

Эта злобная конструкция, ориентируясь в том числе на часовой пояс, «запрещает» использование (в России) 5GHz частот и каналов с «большими» номерами. Трюк заключается в установке тайм зоны без использования названий материков/городов, то есть вместо:

# timedatectl set-timezone Europe/Moscow

Вдавливаем:

# timedatectl set-timezone Etc/GMT-3

И финальные штрихи в прическе системы:

# hostnamectl set-hostname router

/root/.bash_profile:

. . .

# User specific environment and startup programs

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

3. Дополнения CentOS

Все, о чем было сказано выше, можно считать законченной инструкцией по установке «ванильного» CentOS на Raspberry Pi. У вас должен получиться ПК, который (пере)загружается менее чем за 10 секунд, использует менее 15 Мегабайт оперативной памяти и 1.5 Гигабайта microSD (на самом деле менее 1 Гигабайта из-за неполного /boot, но будем честными до конца).

Для установки ПО Wi-Fi точки доступа на эту систему потребуется немного расширить возможности стандартного дистрибутива CentOS. Прежде всего «прокачаем» драйвер(прошивку) встроенного Wi-Fi адаптера. На домашней странице проекта сказано:

Wifi on the Raspberry 3B and 3B+

The Raspberry PI 3B/3B+ firmware files are not allowed to be distributed by the CentOS Project. You can use the following articles to understand the issue, get the firmware and set up the wifi.

Что нельзя проекту CentOS, то не запрещено нам для личного использования. Заменяем дистрибутивную Wi-Fi прошивку в CentOS на соответствующую от разработчиков Broadcom (те самые ненавистные бинарные блобы…). Это, в частности, позволит использовать AC в режиме точки доступа.

Wi-Fi firmware upgradeВыясняем модель устройства и текущую версию прошивки:

# 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 

Видим, что прошивка версии 7.45.18 от 01.03.2015, и запоминаем следующий набор цифр: 43455 (brcmfmac43455-sdio.bin).

Качаем актуальный образ Raspbian. Ленивые могут записать образ на microSD и оттуда забрать файлы с прошивкой. А можно смонтировать корневой раздел образа в Linux и скопировать нужное оттуда:

# 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

Полученные файлы прошивки Wi-Fi адаптера нужно скопировать с заменой на «малинку» в каталог /usr/lib/firmware/brcm/

Перезагружаем будущий роутер и довольно улыбаемся:

# 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 

Версия: 7.45.154 от 27.02.2018.

Ну и конечно же 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. Сетевая конфигурация и предстоящие трудности

Как мы договорились выше, «малинка» подключена «проводом» к локальной сети. Предположим, что и провайдер предоставляет доступ в Интернет точно таким же способом: адрес в публичной сети выдается динамически DHCP сервером (может быть с привязкой к MAC). В этом случае, после окончательной настройки «малинки», достаточно «воткнуть» в нее кабель провайдера и все готово. Авторизация с помощью systemd-networkd — тема отдельной статьи и здесь не рассматривается.

Wi-Fi интерфейс(ы) у Raspberry — это локальная сеть, а встроенный Ethernet адаптер (eth0) — внешняя. Локальную сеть пронумеруем статически, например: 192.168.0.0/24. Адрес «малинки»: 192.168.0.1. Во внешней сети (Интернет) будет работать DHCP сервер.

Проблема единообразия именования и известный гватемальский программист — две неприятности, поджидающие каждого, кто занимается настройкой сетевых интерфейсов и служб в systemd-дистрибутивах.

Параллельный хаос (лирическое отступление)Леннарт Поттеринг составил свою программу systemd очень хорошо. Эта systemd запускает другие программы так быстро, что те, не успев опомниться от судейского пинка свистка, спотыкаются и падают на старте даже не начав свой бег с препятствиями.

Ну а если серьезно, то агрессивное распараллеливание запускаемых процессов при старте systemd-ОС является неким «ослиным мостиком» для матерых последовательных LSB-шников. К счастью, привести в порядок этот «параллельный хаос» оказывается простым, правда не всегда очевидным делом.

Создаем два виртуальных интерфейса-моста (bridge) с постоянными именами: lan и wan. К первому «подключим» Wi-Fi адаптер(ы), ко второму — eth0 «малинки».

/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 избавляет от необходимости через sysctl намекать ядру о включении маршрутизации.
MACAddress= раскомментируем и изменим при необходимости.

Сначала «подключаем» eth0. Помним о «проблеме единообразия» и используем только MAC адрес этого интерфейса, узнать который можно, например, так:

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

Создаем /etc/systemd/network/eth.network:

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

[Network]
Bridge=wan

Удаляем предыдущий файл конфигурации eth0, перезагружаем «малинку» и получаем к ней сетевой доступ (IP адрес скорее всего изменится):

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

5. DNSMASQ

Для изготовления точек доступа Wi-Fi ничего лучше сладкой парочки из dnsmasq + hostapd еще не придумали. По моему мнению.

Если кто забыл, то…hostapd — это штука, которая управляет Wi-Fi адаптерами (в частности, возьмет на себя труд по их подключению к виртуальному lan «малинки»), авторизует и регистрирует беспроводных клиентов.

dnsmasq — настраивает сетевой стек клиентов: выдает IP-адреса, DNS-серверы, шлюз по умолчанию и тому подобные прелести.

Начинаем с dnsmasq:

# yum install dnsmasq

Шаблон /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

редактируем его по своему вкусу.

Минималистичный /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

«Магия» здесь заключается в параметре bind-dynamic, который указывает демону dnsmasq дожидаться появления в системе interface=lan, а не падать в обморок от приступа гордого одиночества после старта.

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

6. HOSTAPD

И наконец, волшебные конфигурации hostapd. Не сомневаюсь, что кто-то читает эту статью в поиске именно этих заветных строчек.

Перед установкой hostapd нужно побороться с «проблемой единообразия». Встроенный Wi-Fi адаптер wlan0 может легко изменить свое имя на wlan1 при подключении дополнительного USB Wi-Fi оборудования. Поэтому зафиксируем имена интерфейсов следующим способом: придумаем (беспроводным) адаптерам уникальные названия и привяжем их к MAC адресам.

Для встроенного Wi-Fi адаптера, который пока еще wlan0:

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

Создаем /etc/systemd/network/wl0.link:

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

[Link]
Name=wl0

Теперь мы будем уверены, что wl0 — это встроенный Wi-Fi. Перезагружаем «малинку», чтобы в этом убедиться.

Устанавливаем:

# yum install hostapd wireless-tools

Конфигурационный файл /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

Ни на минуту не забывая о ГКЧП, изменяем необходимые нам параметры и вручную проверяем на работоспособность:

# hostapd /etc/hostapd/hostapd.conf

hostapd запустится в интерактивном режиме, транслируя на консоль свое состояние. Если ошибок не будет, то к точке доступа уже можно будет подключаться клиентам, поддерживающим AC-режим. Для остановки hostapd — Ctrl-C.

Осталось включить hostapd в автозагрузку системы. Если поступить стандартно (systemctl enable hostapd), то после очередной перезагрузки можно получить «валяющегося в крови» демона с диагнозом «интерфейс wl0 не найден«. В результате «параллельного хаоса» hostapd завелся быстрее, чем ядро нашло беспроводной адаптер.

В Интернете полно лекарств: от принудительного таймаута перед стартом демона (сколько-то минут), до еще одного демона, который мониторит появление интерфейса и (пере)запускает hostpad. Решения вполне себе рабочие, но ужасно некрасивые. Призываем на помощь великого systemd с его «целями» и «задачами» «зависимостями».

Копируем дистрибутивный service-файл в /etc/systemd/system/hostapd.service:

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

и приводим его содержимое к следующему виду:

[Unit]
Description=Hostapd IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
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

Магия обновленного сервисного файла заключается в динамической привязке hostapd к новой цели — интерфейсу wl0. При появлении интерфейса — демон запускается, при пропадании — останавливается. И это все в онлайне — без перезагрузки системы. Особенно эта техника будет полезной при подключении к «малинке» USB Wi-Fi адаптера.

Вот теперь можно:

# systemctl enable hostapd
# reboot

7. IPTABLES

«Шта???» © Да-да! Никакого systemd. Никаких новомодных комбайнов (в виде firewalld), которые в итоге делают одно и тоже.

Используем старый добрый iptables, службы которого после своего старта загрузят в ядро сетевые правила и спокойно завершат работу, не оставаясь резидентно и не потребляя ресурсов. У systemd есть элегантный IPMasquerade=, но трансляцию адресов (NAT) и файервол поручим все-таки iptables.

Устанавливаем:

# yum install iptables-services
# systemctl enable iptables ip6tables

Конфигурацию iptables я предпочитаю хранить в виде скрипта (пример):

#!/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

Выполняем вышеприведенный скрипт и теряем возможность устанавливать новые проводные ssh-соединения с «малинкой». Все правильно, мы изготовили Wi-Fi роутер, доступ к которому «через Интернет» по умолчанию запрещен — теперь только «по воздуху». Подключаем кабель провайдера в Ethernet и начинаем сёрфинг!

8. Бонус: +2,4GHz

Когда по вышеописанному чертежу я собрал первый Raspberry роутер, то обнаружил у себя в хозяйстве некоторое количество гаджетов, которые в силу своих конструктивных ограничений Wi-Fi не могли увидеть «малинку» вообще. Перенастраивать роутер на работу в 802.11b/g/n было неспортивно, так как максимальная скорость «по воздуху» в таком случае не превышала 40 Мбит, а мой любимый Интернет провайдер предлагает мне 100 (по кабелю).

На самом деле, решение проблемы было уже придумано: второй Wi-Fi интерфейс, работающий на частоте 2,4GHz, и вторая точка доступа. В ближайшем ларьке я приобрел не первый, а второй попавшийся мне USB Wi-Fi «свисток». Продавец был истерзан вопросами о чипсете, совместимости с ARM-ядрами Linux и о возможности работы в режиме AP (он первый начал).

Конфигурируем «свисток» по аналогии со встроенным Wi-Fi адаптером.

Сначала — переименуем его в 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

Управлять новым Wi-Fi интерфейсом поручим отдельному демону hostapd, который будет запускаться и останавливаться в зависимости от наличия в системе строго определенного «свистка»: wl1.

Конфигурационный файл /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]

Содержимое этого файла напрямую зависит от модели USB Wi-Fi адаптера, поэтому банальный copy/paste может вас подвести.

Копируем дистрибутивный service-файл в /etc/systemd/system/hostapd2.service:

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

и приводим его содержимое к следующему виду:

[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

Осталось включить новый экземпляр hostapd:

# systemctl enable hostapd2

Вот и все! Подергайте «свисток» и саму «малинку», посмотрите на беспроводные сети вокруг.

И напоследок хочу предупредить о качестве USB Wi-Fi адаптера и электропитания Raspberry. Подключенный «на горячую свисток», иногда может вызвать «зависание малинки» из-за кратковременных электрических неприятностей.

Источник: habr.com