Самодельный роутер и мини-сервер на Raspberry Pi - Часть 2 (программы)
В прошлой статье было рассказано об аппаратной части самодельного сервера (роутера) и его конструкции. В этой статье я расскажу как установить и настроить операционную систему Raspberry Pi OS (GNU/Linux), подготовить программы для работы с сетью: ssh, iw, iptables, hostapd, isc-dhcp, wvdial, minicom.
Также, приведу простые скрипты на языке Python для вывода информации на дисплей SSD1306, воспроизведения звуковых сигналов, считывания информации с кнопок и другую полезную информацию.
Содержание:
- Структура сети и ее работа
- Подготовка Micro-SD карты с Raspbian
- Первое включение и базовая настройка Raspbian
- Подключение к сети и обновление ПО
- Установка необходимого программного обеспечения
- Оптимизация файловых систем
- Сетевые настройки и SSH
- Мощность передатчика Wi-Fi карты, регуляторный домен
- Настройка брандмауэра IPTables, роутинг и защита
- Беспроводная точка доступа (Access Point) на основе HOSTAPD
- Настройка демона ISC-DHCP-Server
- Решение проблемы старта isc-dhcpd и активации сетевых интерфейсов
- Настройка статического списка DNS-серверов
- Подготовка 3G-модема, узнаем его состояние используя minicom
- 3G-модем и консольная звонилка WVDIAL
- Режимы управления частотой CPU в Raspberry Pi и его температура
- Настройка часов реального времени (RTC)
- Считываем показания термодатчика DS18B20
- Генерация звуковых сигналов через пьезо-зуммер
- Управление RGB-светодиодом и реагирование на нажатия кнопок
- Вывод данных на OLED-дисплей
- Набор скриптов для управления
- Другие полезности
- Доработки, установка других сетевых служб, усложнение сети
- Устранение неполадок
- В завершение
Структура сети и ее работа
Поскольку наш самодельный мини-сервер будет выполнять роль сетевого маршрутизатора (роутер, router), то целесообразно предварительно спланировать структуру сети с использованием данного устройства.
Рис. 1. Структура сети, управляемой самодельным маршрутизатором (роутером) построенном на основе Raspberry PI.
Маршрутизатор может быть подключен к интернету используя один из каналов:
- Проводной, через USB-ethernet адаптер (интерфейс eth1);
- Беспроводный, через USB 3G адаптер (интерфейс ppp0).
Сетевые устройства могут быть подключены к маршрутизатору через следующие каналы:
- Проводной (eth0) - через сетевой свич (Ethernet switch): сервер, рабочая станция, ноутбук и т.п.
- Беспроводной (wlan0) - Wi-Fi: смартфон, планшет, ноутбук и другие беспроводные устройства.
USB-3G модем используется как резервный вариант в случае пропадания проводного канала, также возможно использовать его как основной канал.
Пропускная способность проводной сети составит 100Мбит/c. Она ограничена скоростью встроенного Ethernet-порта Raspberry Pi, USB-Ethernet адаптера, а также скоростью сетевого коммутатора.
Пропускная способность беспроводной сети может колебаться в значительных пределах и зависит от качества Wi-Fi сигнала между соединенными устройствами. Скорость интернета в варианте с 3G-модемом зависит от выбранного тарифа, уровня сигнала и возможностей самого модема.
В данном случае, внешние сетевые интерфейсы - это eth1 и ppp0, а внутренние - eth0 и wlan0.
Адреса для интерфейсов:
- eth0 - 192.168.1.1 /24
- wlan0 - 192.168.2.1 /24
- eth1 - DHCP (получаем адрес от интернет-провайдера)
- ppp0 - PPP (получаем адрес от интернет-провайдера)
Пулы адресов, зарезервированные для DHCP-сервера, который будет обслуживать внутренние LAN и WLAN сети:
- eth0: 192.168.1.10 - 192.168.1.100
- wlan0: 192.168.2.10 - 192.168.2.100
Остальные доступные адреса можно использовать для устройств со статическими сетевыми настройками или же чтобы обозначить какое-то конкретное устройство.
Например, можно выделить тестовому серверу легко запоминающийся адрес 192.168.1.111 (подключение по кабелю), а рабочему ноутбуку - 192.168.2.2 (подключение по Wi-Fi).
Все устройства из подсети 192.168.1.1/24 будут доступны для связи устройствам из подсети 192.168.2.1/24 и наоборот. Таким образом можно будет осуществлять коммуникацию между сетевыми устройствами, которые подключены к проводному и беспроводному (Wi-Fi) интерфейсам роутера.
Сетевые пакеты, проходящие через любой из интерфейсов ppp0 или eth1 (интернет-трафик), будут транслироваться с изменением их адресов (masquarade, NAT) для использования во внутренней сети.
Также, на этих интерфейсах выполним фильтрацию входящих пакетов и защиту от вторжений используя мощь iptables.
Есть еще важный нюанс: если у вас уже установлен интернет-маршрутизатор с IP-адресом в подсети 192.168.1.x то при подключении к нему малинового роутера для интерфейсов нужно будет выбрать и настроить подсети с другими номерами, например: для eth0 - 192.168.10.x., а для wlan0 - 192.168.20.x.
В интернет-маршрутизаторе уже могут быть задействованы подсети 192.168.1.x (для проводных подключений) и 192.168.2.x (для беспроводных, Wi-Fi), таким образом, выбрав другие номера подсетей для малинового роутера мы предотвратим конфликты в маршрутизации.
Ниже привожу рисунок со схемой, иллюстрирующей два варианта подключения самодельного роутера на основе Raspberry Pi к интернету:
- Напрямую к каналу интернет провайдера;
- Через домашний маршрутизатор.
Рис. 2. Схемы подключения самодельного маршрутизатора к интернету - напрямую и через промежуточный роутер.
Поскольку на малинке для сетевого интерфейса eth1 у нас будет настроен NAT (Network Adresses Translation, служба маскировки сетевых адресов), то (смотри рисунок 2):
- При прямом подключению к провайдеру, все узлы из его сети с IP-адресами вида 10.x.x.x не будут иметь доступа к устройствам вашей внутренней подсети;
- При подключении через домашний роутер "Home Router", все подключенные к нему устройства не смогут увидеть устройства, что подключены к интерфейсам малинки. Сети предоставляемые малинкой будут защищены от доступа со стороны устройств, что подключены к "Home Router". У вас получится такая себе "персональная подсеть", изолированная от основной домашней сети.
Как видите, структура сети совсем не сложная и достаточно универсальная. Вы можете выбрать удобные вам номера подсетей и настраивать конфигурацию всех служб как описано в статье но уже с учетом этих номеров.
Можем приступать к реализации схемы.
Подготовка Micro-SD карты с Raspbian
Раньше, в одной из статей, я уже подробно описывал процесс установки Raspbian на Micro-SD карту в операционных системах (ОС) Microsoft Windows и GNU/Linux, также там описаны нюансы подбора флешь-карточки и другиая полезная информация. Поэтому, здесь я лишь кратко распишу как установить Raspberry Pi OS (Raspbian).
Ищем подходящий нам архив с образом операционной системы на официальном сайте Raspberry Pi OS - https://www.raspberrypi.org/software/operating-systems/.
Там может быть несколько версий Raspberry Pi OS:
- облегченная версия с минимумом необходимого ПО (Lite);
- версия с ПО для графического рабочего стола (with desktop);
- версия с графическим рабочим столом + дополнительное ПО;
- и другие.
В данном случае, мною был скачан архив с максимально полным набором ПО - "2020-05-27-raspios-buster-full-armhf.zip" (2,5Гб), в котором запакован файл "2020-05-27-raspios-buster-full-armhf.img" (6,9Гб) - образ операционной системы Raspberry Pi OS (Debian 10 с кодовым названием Buster).
Выбрал я эту версию в целях эксперимента, для оценки набора предустановленных программ и возможностей, так как самодельный "роутер" иногда будет использоваться для подключения к монитору и для разных экспериментов. Для записи этого образа понадобится карта памяти с размером не менее чем на 16 ГБ (на 8 ГБ карту поместится, но свободного места останется мало).
Вы же можете использовать более малый по размеру образ с рабочим столом или же и вовсе облегченную версию.
Скачанный образ я сохранил его в папку "/home/master/Downloads" на своем рабочем Linux-ПК.
Установим на компьютере архиватор 7-Zip (для распаковки архива) и программу "pv" (для мониторинга за потоком данных):
sudo apt-get install p7zip-full pv
Распакуем архив:
cd /home/master/Downloads
7z x 2020-05-27-raspios-buster-full-armhf.zip
Установим Micro-SD карту в карт-ридер и узнаем название ее блочного устройства:
lsblk
sdX 8:32 1 14.5G 0 disk
├─sdX1 8:33 1 56M 0 part
└─sdX2 8:34 1 14.4G 0 part
Вместо "X" подставьте букву для своего полученного устройства и можно приступать к процессу записи образа ОС на карту памяти:
sudo pv 2020-05-27-raspios-buster-full-armhf.img | sudo dd of=/dev/sdX bs=4M
Запустим команду для сброса буферов записи и дождемся завершения ее работы:
sync
Теперь можно смело извлечь Micro-SD карту из карт-ридера и установить ее в компьютер Raspberry Pi.
Первое включение и базовая настройка Raspbian
Подключаем к нашему самодельному мини-серверу USB-клавиатуру и мышь (удобно использовать беспроводный комплект), к HDMI-выходу подключаем монитор. Включаем питание.
Дожидаемся загрузки графического интерфейса. При первом запуске будет предложено выбрать язык, временную зону и другие настройки - внимательно ознакомьтесь, в принципе все можно оставить пока что по умолчанию. На запрос обновления программного обеспечения отвечаем - Skip (пропустить).
Теперь запускаем программу "Терминал" (Консоль). В терминале запускаем конфигуратор малинки:
sudo raspi-config
Настройки по пунктам:
Change User Password - устанавливаем пароль доступа, желательно длиной от 8 и более символов с цифрами и буквами разного регистра.
Network options -> Hostname - меняем название системы, например на "myserver".
Boot options:
- Desktop / CLI -> Text console, requiring user to login - отключаем запуск графической оболочки при старте системы, будет загружена консоль с запросом авторизации. В будущем для запуска графической среды достаточно будет выполнить команду "startx" из консоли.
- Wait for Network at Boot -> Yes - ожидать завершения инициализации сетевой подсистемы при старте.
- Splash Screen -> Would you like to show the splash screen at boot? -> No - не отображать заставку при старте.
Localisation Options -> Change Locale:
- en_US.UTF-8, ru_RU.CP1251, ru_RU.KOI8-R, ru_RU.UTF-8, uk_UA.UTF-8, uk_UA.KOI8-R;
- Default locale for the system environment -> en_US.UTF-8 - выбор системной локали по умолчанию, если желаете то можете выбрать украинскую или русскую.
Localisation Options -> Change Timezone - установка временной зоны, например Europe -> Kiev.
Localisation Options -> Change Keyboard Layout:
- Generic 105-key (Intl) PC
- English US
- Key to function as AltGr -> The default for the keyboard
- Compose key -> No compose key
- Use Control+Alt+Backspace to terminate teh X server? -> No
Localisation Options -> Change Wi-fi Country - выбор страны для Wi-Fi, например "UA Ukraine". Очень важная настройка!
Interfacing options:
- SSH -> Would you like the SSh server to be enabled? -> Yes - включаем SSH-службу для удаленного доступа к консоли по сети;
- I2C -> Would you like the ARM I2C interface to be enabled? - Yes - включаем I2C-шину для доступа к дисплею SSD1306 и часам реального времени DS1307;
- 1-Wire -> Would you like the one-wire interface to be enabled? - Yes - включаем 1-Wire шину для доступа к датчику температуры DS18B20.
Advanced options:
- Expand filesystem - расширяем файловую систему ОС для использования всего доступного на Micro-SD карте пространства;
- Memory Split -> 64 - выбираем количество оперативной памяти, выделяемое под графический адаптер. Значение 64МБ - оптимальное если планируется использовать графическую оболочку, в противном случае можно установить 32МБ или 16МБ.
Подключение к сети и обновление ПО
Для возможности удаленного доступа к малинке через SSH выполним первичную настройку проводной сети. Это позволит удобно выполнять настройки, копировать файлы и редактировать скрипты.
Подключим малинку к ноутбуку или рабочему ПК используя сетевой кабель и сетевой коммутатор. Можно также непосредственно подключить два устройства без сетевого коммутатора, в таком случае понадобится сетевой кабель RJ-45 c перевернутой разводкой проводов (сетевой кросс-кабель).
Вариант 1: [notebook |RJ-45>----кабель1----<RJ-45| Ethernet switch |RJ-45>----кабель2----<RJ-45| Raspberry Pi]
Вариант 2: [notebook |RJ-45>----кабель_кросс----<RJ-45| Raspberry Pi]
На ноутбуке (или ПК) установим статический IP-адрес - 192.168.1.2.
Начиная с Raspbian Stretch (Debian 9) статические настройки для сетевых интерфейсов прописываются в конфигурационном файле для DHCP клиента (DHCP Client Daemon) - "/etc/dhcpcd.conf". В более старых версиях ОС, например Raspbian Jessie (Debian 8) - это делалось с помощью файла "/etc/network/interfaces".
Теперь, присвоим интерфейсу eth0 на малинке сетевой адрес 192.168.1.1. Для добавления настроек статической адресации откроем файл "dhcpcd.conf":
sudo nano /etc/dhcpcd.conf
Добавляем в самый низ файла следующие строчки:
interface eth0
static ip_address=192.168.1.1/24
Выходим из редактора (CTRL+X), подтверждаем сохранение содержимого файла (Y + ENTER).
Выполним перезагрузку Raspbian:
sudo reboot
Проверяем есть ли связь на ноутбуке (ПК) с сетевым адресом 192.168.1.1, пробуем подключиться к Raspberry PI используя этот же адрес:
ping 192.168.1.1
ssh pi@192.168.1.1
Будет запрошен пароль для авторизации по SSH - мы установили его на этапе начальной конфигурации.
Теперь, подключившись к Raspberry Pi удаленно по SSH, можно отключить клавиатуру и мышь от мини-компьютера. Но прятать далеко их не стоит, они еще могут понадобиться в случае если не удастся выполнить подключение к малинке по SSH и для решения других возможных проблем в процессе настройки.
Подключаем USB-Ethernet адаптер к одному из свободных USB-портов самодельного роутера, также подключаем к этому же адаптеру сетевой кабель с интернетом от провайдера или модема/роутера.
USB-Ethernet адаптер должен автоматически определиться малинкой, а его интерфейс получит IP-адрес, сетевой шлюз (Gateway) и список DNS-серверов от провайдера интернета или домашнего роутера.
Смотрим список доступных сетевых интерфейсов и их конфигурацию, список активных сетевых маршрутов, а также список DNS-серверов, полученных по DHCP:
ip -c a
ip route
cat /etc/resolv.conf
На малинке должен появиться интернет. Проверим доступен ли DNS-сервер Google:
ping 8.8.8.8
Осматриваем источники репозиториев, файлы и папки на наличие нежелательных:
ls -la /etc/apt/sources.list.d/
ls -la /etc/apt/trusted.gpg.d/
cat /etc/apt/sources.list
# Например, удяляем навязанный Microsoft репозиторий
# для VSCode и их ключ, которые пробовали "пропихнуть"
# в Raspberry Pi Foundation:
# https://old.reddit.com/r/linux/comments/lbu0t1/microsoft_repo_installed_on_all_raspberry_pis/
sudo rm /etc/apt/sources.list.d/vscode.list
sudo rm /etc/apt/trusted.gpg.d/microsoft.gpg
# Заблокируем хост с репозиторием от MS:
sudo echo "# Protecting from MS" >> /etc/hosts
sudo echo "127.0.0.1 packages.microsoft.com" >> /etc/hosts
Теперь можно выполнить обновление списков пакетов и обновить уже установленное программного обеспечение:
sudo apt-get update
sudo apt-get upgrade
Настроим автоматическую установку критических обновлений безопасности:
sudo apt-get install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
На запрос последней команды отвечаем утвердительно - Yes.
Выполним принудительный запуск unattended-upgrades для проверки работоспособности:
sudo unattended-upgrades -d
На этом этапе желательно перезагрузить Raspberry Pi и повторно проверить работоспособность сети и интернета.
Установка необходимого программного обеспечения
Выполним установку необходимого для работы и функционирования программного обеспечения. Базовый набор инструментов:
sudo apt-get install mc htop p7zip-full lynx tmux
- mc - Midnight Commander, консольный двухпанельный файловый менеджер;
- htop - мониторинг производительности и ресурсов системы;
- p7zip-full - мощный архиватор 7Zip;
- tmux - Terminal Multiplexor, удобный мультифункциональный эмулятор терминалов.
Полезности для работы с USB-модемом:
sudo apt-get install usb-modeswitch usb-modeswitch-data wvdial ppp minicom
- usb-modeswitch - набор скриптов для автоматического переключения режима работы модемов;
- wvdial - программа дозвона для модема;
- ppp - служба для поддержки протокола Point-to-Point;
- minicom - терминал с возможностью подключения к последовательным портам.
Сетевые программы:
sudo apt-get install tcpdump nmap netdiag hostapd isc-dhcp-server
- tcpdump - сниффер сетевых пакетов;
- nmap - мощный сетевой сканер, легендарная программа;
- netdiag - пакет, содержащий несколько полезных утилит, в особенности "trafshow" для мониторинга подключений;
- hostapd - служба для создания беспроводной точки доступа IEEE 802.11 AP и IEEE 802.1X/WPA/WPA2/EAP авторизатор ;
- isc-dhcp-server - популярный DHCP сервер.
Мониторинг дисковых операций:
sudo apt-get install iotop sysstat
- iotop - мониторинг операций ввода-вывода (I/O);
- sysstat - набор утилит для мониторинга производительности в GNU/Linux.
Оптимизация файловых систем
Для работы малинки в качестве роутера можно провести ряд оптимизаций, которые снизят количество операций записи на карту. Можно отключить логирование для некоторых программ и демонов, отключить отслеживание времени последнего доступа к файлам, а также перенести некоторые разделы на TMPFS (файловая система в оперативной памяти).
Для того чтобы узнать какие программы выполняют интенсивный обмен данными с накопителем данных (картой памяти), можно использовать утилиту iotop:
sudo iotop -bktoqqq
Пояснение ключей запуска:
- b - batch, включить не интерактивный режим;
- k - отображать значения в Килобайтах;
- t - показать временную метку для каждой строчки;
- o - отобразить только активные процессы ввода-вывода;
- qqq - не выводить суммарную информацию.
Увидим примерно следующую картину (фрагмент):
08:06:44 94 be/3 root 0.00 K/s 46.61 K/s 0.00 % 20.63 % [jbd2/mmcblk0p2-]
08:06:46 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.05 % [kworker/3:2]
08:06:48 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.05 % [kworker/3:2]
08:06:50 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.05 % [kworker/3:2]
08:06:52 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.05 % [kworker/3:2]
08:06:54 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.06 % [kworker/3:2]
08:06:55 537 be/4 root 0.00 K/s 11.13 K/s 0.00 % 0.00 % rsyslogd -n [rs:main Q:Reg]
08:06:56 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.06 % [kworker/3:2]
08:06:59 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.05 % [kworker/3:2]
08:07:01 94 be/3 root 0.00 K/s 7.41 K/s 0.00 % 1.88 % [jbd2/mmcblk0p2-]
08:07:01 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.06 % [kworker/3:2]
08:07:03 139 be/4 root 0.00 K/s 0.00 K/s 0.00 % 0.06 % [kworker/3:2]
08:07:03 537 be/4 root 0.00 K/s 14.83 K/s 0.00 % 0.00 % rsyslogd -n [rs:main Q:Reg]
08:07:03 1412 be/4 root 0.00 K/s 7.42 K/s 0.00 % 0.00 % sshd: pi [priv]
Также можно понаблюдать за суммарной статистикой ввода-вывода для накопителей данных, используя утилиту iostat:
iostat -dzp 5
Ключи запуска:
- d - отобразить отчет об использовании устройств;
- z - не выводить данные для неактивных устройств;
- p - отображать все блочные устройства и их разделы;
- 5 - интервал обновления.
Вывод программы будет иметь следующий вид:
Linux 4.9.35-v7+ (myserver) 24.08.17 _armv7l_ (4 CPU)
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
mmcblk0 4,11 116,12 43,40 208752 78024
mmcblk0p1 0,05 1,12 0,00 2015 0
mmcblk0p2 4,04 114,78 43,40 206337 78024
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
mmcblk0 0,40 0,00 3,20 0 16
mmcblk0p2 0,40 0,00 3,20 0 16
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
Таким образом, можно узнать какие системные и запущенные вручную программы наиболее активно обращаются к диску.
Перейдем непосредственно к оптимизациям, вот в чем они заключаются:
- Отключаем операции записи временных меток доступа к папкам и файлам (noatime, nodiratime);
- Переносим директории "/tmp", "/var/log", "/var/spool/mqueue" и "/var/tmp" в оперативную память (tmpfs);
- Отключаем файл подкачки (swap).
Все эти меры помогут минимизировать количество операций записи на карту памяти.
Редактируем файл "fstab" с описанием всех монтируемых файловых систем:
sudo nano /etc/fstab
Для раздела с точкой монтирования "/" добавляем флаги "noatime,nodiratime", также добавляем строчки для монтирования директорий в файловую систему "tmpfs". Примерный вид файла "fstab":
proc /proc proc defaults 0 0
PARTUUID=afb93022-01 /boot vfat defaults 0 2
PARTUUID=afb93022-02 / ext4 defaults,noatime,nodiratime 0 1
tmpfs /tmp tmpfs nodev,nosuid,nodiratime,size=256M 0 0
tmpfs /var/log tmpfs defaults,noatime,nosuid,mode=0755,size=50M 0 0
#tmpfs /var/spool/mqueue tmpfs defaults,noatime,nosuid,mode=0700,size=20M 0 0
tmpfs /var/tmp tmpfs defaults,noatime,nosuid,size=256M 0 0
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that
С такой конфигурацией все системные логи, письма в очереди на отправку и временные файлы будут записываться в файловой системе, выделяемой из оперативной памяти, после выключения питания малинки вся эта информация будет безвозвратно утеряна.
Если нужно сохранять логи, или же временно включить их сохранение, то достаточно закомментировать строчку "tmpfs /var/log...". Сейчас например закомментирована точка монтирования tmpfs для директории /var/spool/mqueue.
Подобным образом можно поступить и с другими точками монтирования, а также если нужно добавить свои.
Еще один из вариантов хранения логов и другой статической информации - подключить и подмонтировать миниатюрный USB-флешь накопитель с размером памяти 2-8G.
Максимальные значения оперативной памяти, которые могут быть выделены для точек монтирования в приведенном случае:
- /tmp - 256M;
- /var/log - 50M;
- /var/spool/mqueue - 20M;
- /var/tmp - 256M.
В суме: 256 + 50 + 20 + 256 = 582(М).
Оперативная память в файловой системе tmpfs используется по мере необходимости, это значит что если в /tmp записать файл размером 10М, то при максимально допустимом размере файловой системы 256M реальной памяти будет использовано примерно 10М.
В Raspberry Pi 3 B установлено 1G оперативной памяти, поэтому если будут заполнены все файловые системы "tmpfs" (что маловероятно) то на все остальное останется примерно 400М.
В некоторых случаях (просмотр содержания больших архивов через mc, установка определенного ПО которое использует много места во временной файловой системе и т.п.) выделенной памяти в 256М для раздела /tmp может быть маловато.
Чтобы выйти из этой ситуации можно временно закомментировать строчку отвечающую за монтирвоание "tmpfs" для "/tmp", перезагрузить малинку и выполнить все нужные операции, а потом вернуть все как прежде. Также можно попробовать увеличить размер файловой системы с 256М до 512М.
Идем дальше. Осталось отключить и удалить файл подкачки:
sudo dphys-swapfile swapoff
sudo systemctl disable dphys-swapfile
sudo rm /var/swap
В случае неполадок или ошибок после редактирования файла "fstab" операционная система может быть загружена в однопользовательском режиме, нормальный режим загрузки станет недоступным.
Чтобы исправить записи в файле "fstab" нужно перемонтировать корневую файловую систему в режиме записи и отредактировать файл fstab:
mount -o,remount /
nano /etc/fstab
После внесения изменений перезагружаем малинку.
Сетевые настройки и SSH
Разрешим пересылку IPv4 пакетов между сетевыми интерфейсами, а также отключим сетевой протокол IPv6. Для домашней сети IPv6 избыточен, поэтому мы его использовать не будем.
Открываем для редактирования файл "/etc/sysctl.conf":
sudo nano /etc/sysctl.conf
Добавляем в самый низ его содержимого следующие строки:
# Network packets forwarding for IPv4
net.ipv4.ip_forward=1
# Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
Также включим защиту от некоторых сетевых атак с подменой данных (Spoofing attacks), для этого нужно раскомментировать две строчки в этом же файле:
# Spoofing attacks protection
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.rp_filter=1
Добавим в файл "/etc/network/interfaces" настройки для поддержки "горячего" извлечения сетевых устройств, относящихся к интерфейсам wlan0(может быть USB-адаптер, например в малинке 2-й версии) и eth1(USB-адаптер). Также укажем что эти интерфейсы настраиваются вручную (их настройками будет управлять сконфигурированный нами сетевой демон DHCPCD).
sudo nano /etc/network/interfaces
Добавляем описания для интерфейсов:
allow-hotplug eth1
iface eth1 inet manual
allow-hotplug wlan0
iface wlan0 inet manual
Раньше нами уже был прописан статический IPv4-адрес для интерфейса eth0, осталось задать статический адрес для интерфейса беспроводной сети wlan0. Также нам нужно запретить использование механизма WPA-авторизации, что позже позволит использовать этот сетевой интерфейс для создания на его основе беспроводной точки доступа (Wireless Access Point).
sudo nano /etc/dhcpcd.conf
Заменяем ранее добавленные строчки для интерфейса eth0 следующим содержимым:
nohook wpa_supplicant
interface eth0
static ip_address=192.168.1.1/24
interface wlan0
static ip_address=192.168.2.1/24
Вы можете ознакомиться с назначением директив в файле "dhcpcd.conf" используя встроенную справочную систему:
man dhcpcd.conf
Перезагружаем малинку и смотрим статус службы dhcpcd:
sudo reboot
sudo systemctl status dhcpcd.service
Смотрим присвоены ли нужные нам статические IP-адреса для интерфейсов eth0 и wlan0:
ip -c a | grep eth0 && ip -c a | grep wlan0
Вы можете заметить что интерфейсу wlan0 не присвоен установленный нами IP-адрес, в действительности здесь все нормально - он появится позже, когда интерфейс будет инициализирован после настройки беспроводной точки доступа.
Фикс уязвимостей CVE-2016-0777 и CVE-2016-0778 для безопасности SSH-клиента:
sudo nano /etc/ssh/ssh_config
Добавить вниз файла строку:
UseRoaming no
В SSH-демоне по умолчанию включено выполнение DNS-запросов для получения имени удаленного хоста (который питается подключиться), эта возможность используется для того чтобы убедиться что обратное преобразование имени вернет идентичный IP-адрес, служит в целях безопасности. Следующий фикс ускорит SSH-подключения к нашему самодельному серверу из машин в локальной сети.
sudo nano /etc/ssh/sshd_config
Нужно найти (CTRL+W) и раскомментировать строку:
UseDNS no
Мощность передатчика Wi-Fi карты, регуляторный домен
В Raspberry Pi 3 (model B) встроен достаточно мощный модуль Wi-Fi. Мне нигде не удалось найти точных данных о выходной мощности беспроводного модуля для малинки, поэтому определил ее примерное значение экспериментально.
Значения мощности часто указывают по логарифмической децибельной шкале - в Децибелах (дБ, Decibel, dB). Если измерение выполняется относительно единицы мощности милливатт (мВт), то в децибеллах (дБ) это значение обозначается как "дБм" или "dBm" (0 dBm = 1mW).
Выходная мощность излучения беспроводного адаптера часто указывается и задается именно в dBm. Для простого перевода значений dBm в милиВатты можно воспользоваться следующей табличкой:
Значение, дБм | Значение, мВт | Значение, дБм | Значение, мВт | |
-1 | 0,8 | 21 | 125 | |
0 | 1 | 22 | 160 | |
1 | 1,259 | 23 | 200 | |
2 | 1,6 | 24 | 250 | |
3 | 1,995 | 25 | 320 | |
4 | 2,5 | 26 | 400 | |
5 | 3,2 | 27 | 500 | |
6 | 3,981 | 28 | 640 | |
7 | 5 | 29 | 800 | |
8 | 6,4 | 30 | 1000 | |
9 | 8 | 31 | 1250 | |
10 | 10 | 32 | 1600 | |
11 | 12,5 | 33 | 2000 | |
12 | 16 | 34 | 2500 | |
13 | 20 | 35 | 3200 | |
14 | 25 | 36 | 4000 | |
15 | 32 | 37 | 5000 | |
16 | 40 | 38 | 6400 | |
17 | 50 | 39 | 8000 | |
18 | 64 | 40 | 10 000 | |
19 | 80 | 50 | 100 000 | |
20 | 100 | 60 | 1000 000 |
Увеличение мощности передатчика на 1dBm равносильно ее увеличению в 100,1 раза или примерно в 1,259 раза. Каждое прибавление 3 дБ к мощности увеличивает ее в два раза, например: 10дБ (10мВт) + 3дБ = 13дБ (20мВт) или 30дБ (1Вт) + 3дБ = 33дБ (2Вт) и т.д.
Текущую мощность передатчика (txpower, Transmit Power) для беспроводного модуля с сетевым интерфейсом wlan0 можно узнать используя команду:
iw wlan0 info
Получим примерно следующую информацию:
Interface wlan0
ifindex 3
wdev 0x1
addr b8:27:eb:6a:XX:XX
ssid Raspberry-Pi
type AP
wiphy 0
channel 6 (2437 MHz), width: 20 MHz, center1: 2437 MHz
txpower 15.00 dBm
Здесь мы видим, что текущая выходная мощность передатчика (txpower) - 15 дБм, что равно 32мВт или 0,032Вт.
Чтобы узнать больше подробностей о текущих настройках и возможностях доступных беспроводных сетевых устройств, можно воспользоваться следующей командой:
iw list
На экран будет выведено много разной информации: поддерживаемые алгоритмы шифрования и режимы интерфейса, список возможных скоростей для передачи данных, каналов с указанием частот, поддерживаемые команды и многое другое.
Сейчас нас наиболее интересует раздел "Frequencies":
iw list | grep -A 15 Frequencies:
В моем случае его вывод команды имеет следующий вид:
Frequencies:
* 2412 MHz [1] (20.0 dBm)
* 2417 MHz [2] (20.0 dBm)
* 2422 MHz [3] (20.0 dBm)
* 2427 MHz [4] (20.0 dBm)
* 2432 MHz [5] (20.0 dBm)
* 2437 MHz [6] (20.0 dBm)
* 2442 MHz [7] (20.0 dBm)
* 2447 MHz [8] (20.0 dBm)
* 2452 MHz [9] (20.0 dBm)
* 2457 MHz [10] (20.0 dBm)
* 2462 MHz [11] (20.0 dBm)
* 2467 MHz [12] (20.0 dBm)
* 2472 MHz [13] (20.0 dBm)
* 2484 MHz [14] (disabled)
Supported commands:
Здесь указаны 14 частот для 14-ти каналов, доступны из которых только 13 (14-й канал заблокирован, disabled). Выходная мощность для передатчика ограничена значением в 20 dBm (100 mW).
Выполняя базовую настройку Raspbian в разделе "Localisation Options -> Change Wi-fi Country" мы раньше установили страну для Wi-Fi - UA (Украина).
В каждой стане действуют свои правила и ограничения по использованию частот и беспроводного сетевого оборудования. Для большинства стран мира доступны каналы 1-13, а 14-й канал недоступен к использованию, исключением здесь является Япония, где в некоторых режимах работа на 13-м канале все же возможна. Для соединенных штатов доступны каналы 1-11.
Для реализации правил использования частот при работе с сетевым оборудованием в разных странах используются регуляторные домены.
Регуляторный домен (Regulatory Domain, regdomain) - это специальный набор правил, специфичный для каждой страны, который регулирует использование частот, может ограничивать мощность радиопередатчика, не допускать использование некоторых технологий и возможностей при передаче данных в беспроводных сетях.
При работе с регуляторными доменами в GNU/Linux используется CRDA (Central Regulatory Domain Agent). Чтобы узнать правила и ограничения регуляторного домена для вашей страны можно воспользоваться публичной базой данных -
https://www.kernel.org/pub/software/network/wireless-regdb/
Скачиваем самый свежий архив, открываем файл "db.txt" и ищем там индекс своей страны. Пример для Украины:
country UA: DFS-ETSI
(2400 - 2483.5 @ 40), (20), NO-OUTDOOR
(5150 - 5250 @ 80), (20), NO-OUTDOOR, AUTO-BW
(5250 - 5350 @ 80), (20), DFS, NO-OUTDOOR, AUTO-BW
(5490 - 5670 @ 160), (20), DFS
(5735 - 5835 @ 80), (20)
# 60 GHz band channels 1-4, ref: Etsi En 302 567
(57000 - 66000 @ 2160), (40)
Там же найдете ссылки на регуляторные документы своей страны и другую полезную информацию.
Чтобы узнать какой регуляторный домен используется в текущий момент на малинке, достаточно выполнить следующую команду:
iw reg get
В моем случаем вывод команды будет почти идентичным (за исключением комментария), как и в примере из файла "db.txt" для Украины. Здесь видно что для диапазона частот 2400 - 2483(МГц) выходная мощность передатчика ограничивается значением 20dBm (100 мВт).
В данном случае, попытка установить мощность передатчика выше 20dBm, скорее всего, не даст практического результата - мощность будет ограничиваться текущим регуляторным доменом (ядром ОС, использующим этот набор правил).
Для установки или смены регуляторного домена в GNU/Linux применяется следующая команда:
sudo iw reg set UA
Здесь вместо "UA" может быть "US", "VE" или другой код страны. Сменив регуляторный домен, мы сменим правила, по которым ядро ОС применяет ограничения при использовании беспроводных сетевых устройств.
Есть регуляторные домены, в которых для некоторых частот запрещено использовать режим точки доступа (AP, Access Point), поэтому нужно с ответственностью и пониманием отнестись к установке этой опции.
Чтобы обойти ограничение на 20dBm, в моем случае можно выбрать регуляторный домен "VE" и изменить мощность передатчика в большую сторону - 30dBm, но это уже будет нарушением правил по использованию частот для моей страны. К тому же, мне не нужна такая большая мощность, даже наоборот - мы будем ее снижать, зачем нам лишнее излучение вокруг нас.
Установить мощность Wi-Fi передатчика для интерфейса wlan0 можно следующей командой:
sudo iwconfig wlan0 txpower 10
В данном случае "10" - это значение мощности в дБм (dBm), которое равно 10мВт. Такой мощности может вполне хватить чтобы покрыть беспроводной сетью небольшую комнату, в которой расположен роутер.
Данное изменение будет действовать только до перезагрузки ОС. Чтобы установка требуемого значения мощности выполнялась каждый раз при загрузке ОС, нужно добавить вышеуказанную команду в какой-то из скриптов, запускаемых при старте системы.
Мы же заставим эту команду выполняться при готовности сетевого интерфейса, в файле "/etc/network/interfaces". Там же можно и добавить команду установки регуляторного домена, если нужно. Откроем этот файл в редакторе:
sudo nano /etc/network/interfaces
Добавим секцию из двух строчек для интерфейса wlan0, настройки получат следующий вид:
allow-hotplug wlan0
iface wlan0 inet manual
up iw reg set UA
up iwconfig wlan0 txpower 10
Статический IP-адрес для этого интерфейса мы уже раньше указали в файле "/etc/dhcpcd.conf", поэтому здесь ничего больше добавлять не нужно.
Перезагружаем малинку и смотрим установилась ли нужная мощность передатчика и нужный регуляторный домен:
sudo reboot
iw wlan0 info
iw reg get
Настройка брандмауэра IPTables, роутинг и защита
С помощью IPTables мы будем выполнять следующие задачи:
- Разрешим пересылку сетевых пакетов между внутренними подсетями (интерфейсы eth0, wlan0);
- Выполним трансляцию сетевых пакетов (NAT, masquarade) через интерфейсы, которые выходят в интернет (ppp0, eth1);
- Разрешим подключение к роутеру через внутренние интерфейсы eth0, wlan0 используя порт 22 (SSH);
- Разрешим все входящие пакеты, относящиеся к уже установленным подключениям (для цепочек INPUT и FORWARD);
- Запретим все остальные входящие соединения на любом из сетевых интерфейсов;
- Ограничим возможность сканирования роутера с использованием TCP-пакетов со специальными флагами.
Это достаточно жесткая политика, тем не менее, она позволит неплохо защитить ваш роутер. Вы сможете устанавливать исходящие соединения и принимать входящие, которые относятся к уже установленным исходящим, использовать интернет, свободно работать с сетевыми устройствами во внутренней сети.
На роутере будет открыт для подключения только порт 22 (SSH, для администрирования), все остальные попытки "достукаться" до роутера со стороны провайдера или другого промежуточного маршрутизатора (через интерфейсы eth1, ppp0) будут бесполезны. Ваш роутер не смогут даже "пропинговать" (командой ping) снаружи, поскольку будут отсекаться все ICMP-пакеты.
Если же вам не нужна такая жесткая политика, то вы можете настроить брандмауэр на свое усмотрение, исправив, добавив или удалив какие-то из правил.
Для построения набора правил IPTables в Raspbian можно использовать пакет "iptables-persistent", который при каждом старте ОС будет выполнять загрузку правил брандмауэра с ранее сохраненной конфигурацией.
Я же предлагаю использовать отдельный скрипт, который будет загружаться системой через systemd. В одной из статей я приводил скрипт IPTables для ipv4 и ipv6 с автозагрузкой в Linux, здесь будет использована немного упрощенная (без IPv6) и модифицированная версия этого скрипта.
Создаем файл скрипта с будущими правилами, откроем его для редактирования:
sudo nano /usr/local/sbin/systemd-iptables.sh
Вставляем в окно редактора следующий код:
#!/bin/sh
# IPTables init script for systemd
# Project: Raspberry Pi Router
# by ph0en1x - https://ph0en1x.net
IPT=/sbin/iptables
ETH=eth0
WLAN=wlan0
PPP=ppp0
ETH_EXT=eth1
# Flush active rules, flush custom tables, and set default policy
Flush_Rules () {
$IPT --flush
$IPT -t nat --flush
$IPT -t mangle --flush
$IPT --delete-chain
$IPT -t nat --delete-chain
$IPT -t mangle --delete-chain
# Set default policies to ACCEPT
$IPT -P INPUT ACCEPT
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT ACCEPT
}
# Loading rules
Load_Rules () {
# Flush
Flush_Rules
# DEFAULT POLICIES
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT
# PASS localhost traffic
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# ALLOW traffic from already established connections
$IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# ALLOW local connections to router via SSH
$IPT -A INPUT -p tcp --dport 22 -i $ETH -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -i $WLAN -j ACCEPT
# DROP all other incoming connections
$IPT -A INPUT -j DROP
# ALLOW packets forwarding between internal networks
$IPT -A FORWARD -i $ETH -o $WLAN -j ACCEPT
$IPT -A FORWARD -i $WLAN -o $ETH -j ACCEPT
# ALLOW packets forwarding between local net and internet
$IPT -A FORWARD -i $PPP -o $ETH -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A FORWARD -i $ETH -o $PPP -j ACCEPT
$IPT -A FORWARD -i $PPP -o $WLAN -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A FORWARD -i $WLAN -o $PPP -j ACCEPT
$IPT -A FORWARD -i $ETH_EXT -o $ETH -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A FORWARD -i $ETH -o $ETH_EXT -j ACCEPT
$IPT -A FORWARD -i $ETH_EXT -o $WLAN -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A FORWARD -i $WLAN -o $ETH_EXT -j ACCEPT
# DROP all other forwarding traffic
$IPT -A FORWARD -j DROP
# DROP ports scanning traffic
$IPT -N PORT-SCAN
$IPT -A PORT-SCAN -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j RETURN
$IPT -A PORT-SCAN -j DROP
# NAT for external interface
$IPT -t nat -A POSTROUTING -o $PPP -j MASQUERADE
$IPT -t nat -A POSTROUTING -o $ETH_EXT -j MASQUERADE
}
case $1 in
start)
Load_Rules
echo "IPTables rules loaded."
;;
stop)
Flush_Rules
echo "IPTables rules flushed."
;;
restart)
Flush_Rules
Load_Rules
echo "IPTables rules reloaded."
;;
*)
echo "Usage: systemctl {start|stop|restart} iptables.service"
exit 1
esac
exit 0
В начале скрипта указаны названия задействованных интерфейсов:
- ETH - проводной сетевой интерфейс (внутренняя сеть)
- WLAN - беспроводной (Wi-Fi) сетевой интерфейс (внутренняя сеть)
- PPP - беспроводной (USB-3G) сетевой интерфейс (Internet)
- ETH_EXT - проводной сетевой интерфейс (Internet)
В самом начале статьи была приведена схема сети с использованием будущего роутера на основе малинки, не ленитесь еще раз на нее взглянуть чтобы более четко понять структуру сети и работу скрипта с правилами IPTables.
В процедуре "Flush_Rules" выполняется очистка правил для всех цепочек брандмауэра, установка разрешающей (ACCEPT) сетевой политики для всех цепочек. Процедура "Load_Rules" выполняет загрузку прописанных нами правил с указанием различных опций и цепочек фильтрации.
В конце, с помощью конструкции "case $1 in", выполняется анализ и применение переданной скрипту команды (start, stop, restart), запускаются выше указанные процедуры "Flush_Rules" и "Load_Rules в нужном порядке.
Чтобы скрипт можно было запускать на исполнение, его файлу нужно дать соответствующие права:
sudo chmod +x /usr/local/sbin/systemd-iptables.sh
Теперь вы можете вручную запустить, остановить, перезапустить скрипт и оттестировать функционал его правил:
sudo /usr/local/sbin/systemd-iptables.sh start
sudo /usr/local/sbin/systemd-iptables.sh stop
sudo /usr/local/sbin/systemd-iptables.sh restart
Когда скрипт готов, можно приступать к созданию специального юнита для systemd, который будет выполнять автозапуск скрипта при старте ОС.
sudo nano /etc/systemd/system/iptables.service
Содержимое файла будет таким:
[Unit]
Description=IPTables rules
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/systemd-iptables.sh start
ExecStop=/usr/local/sbin/systemd-iptables.sh stop
ExecReload=/usr/local/sbin/systemd-iptables.sh restart
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Разрешим использование новосозданного юнита демоном systemd:
sudo systemctl enable iptables.service
Дадим юниту команду на старт, проверим состояние таблиц IPTables:
sudo systemctl start iptables.service
sudo systemctl status iptables.service
sudo iptables -nvL
Также можно вывести список уже загруженных в IPTables правил в более удобном виде, с нумерацией строк:
sudo iptables -t filter --list --line-numbers
sudo iptables -t nat --list --line-numbers
Беспроводная точка доступа (Access Point) на основе HOSTAPD
Поскольку наш роутер будет предоставлять возможность подключения к нему по Wi-Fi, давайте выполним настройку отвечающей за это службы hostapd.
Hostapd (Host Access Point Daemon) - это демон, работающий в фоновом режиме и отвечающий за организацию беспроводной сетевой точки доступа стандарта IEEE 802.11 на основе имеющегося Wi-Fi адаптера с поддержкой этого режима. Также это демон берет на себя функции авторизации клиентов и выполняет другую связанную работу.
- https://w1.fi/hostapd/ - страничка программы на официальном сайте
- https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf - описание опций конфигурационного файла (набор впечатляет).
Чтобы убедиться что сетевой Wi-Fi адаптер малинки поддерживает режим точки доступа (Access Point, AP), выведем еще раз, как в разделе о настройке мощности передатчика, информацию о беспроводных интерфейсах:
iw list
Смотрим секцию "Supported interface modes", в моем случае ее содержимое выглядит вот так:
Supported interface modes:
* IBSS
* managed
* AP
* P2P-client
* P2P-GO
* P2P-device
Как видим, режим "AP" присутствует, значит можно продолжать.
Пакет "hostapd" уже был ранее нами установлен, на этапе установки необходимого программного обеспечения. Приступаем к настройке. Открываем для редактирования конфигурационный файл демона hostapd:
sudo nano /etc/hostapd/hostapd.conf
Приводим его содержимое к такому виду:
interface=wlan0
driver=nl80211
ssid=JohnX-Pi
# Use the 2.4GHz band
hw_mode=g
channel=6
# Enable 802.11n
ieee80211n=1
wmm_enabled=1
# Enable 40MHz channels with 20ns guard interval
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
# Accept all MAC addresses
macaddr_acl=0
# Use WPA authentication
auth_algs=1
# Require clients to know the network name
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_passphrase=SUP3R_PASSW00RD*#12
# Use AES, instead of TKIP
rsn_pairwise=CCMP
# 0 - disabled
wps_state=0
Это минимальный набор опций для организации беспроводной точки доступа. Опции которые вам следует изменить на свое усмотрение:
- "ssid=JohnX-Pi" - здесь указано название будущей точки доступа, вместо "JohnX-Pi" укажите свое название, используйте по возможности символы A-Z0-9 и дефис. В названии допустимо использование всего арсенала символов из кодировки UTF-8 если добавить в конфигурационный файл опцию "utf8_ssid=1", правда отображаться на некоторых устройствах такие имена могут не корректно;
- "channel=6" - номер канала, на котором будет осуществляться обслуживание беспроводной сети, выберите наименее загруженный в своей местности или здании;
- "wpa_passphrase=SUP3R_PASSW00RD*#12" - пароль для доступа к беспроводной сети. Установите сложный и надежный пароль, с использованием 10-20 символов, включая буквы, цифры и специальные знаки.
Укажем путь к используемому конфигурационному файлу для демона hostapd:
sudo nano /etc/default/hostapd
Нужно расскомментировать строчку "DAEMON_CONF=" и указать в ней путь к файлу hostapd.conf:
DAEMON_CONF="/etc/hostapd/hostapd.conf"
Перезапускаем службу hostapd и смотрим ее статус после запуска:
sudo systemctl restart hostapd
sudo systemctl status hostapd
В новых версиях Raspbian эта служба по умолчанию скрыта (masked). Поэтому после попытки запустить hostapd вы можете получить сообщение об ошибке:
Failed to start hostapd.service: Unit hostapd.service is masked.
В данном случае нужно разблокировать службу и запустить ее, делается это следующими командами:
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl start hostapd
sudo systemctl status hostapd
Теперь можно попробовать подключиться к точке доступа, используя ноутбук или смартфон, правда ни одно из устройств не получит сетевых настроек, потому что нужно еще настроить сервер DHCP.
Настройка демона ISC-DHCP-Server
Раньше мы уже выполнили установку пакета "isc-dhcp-server".
ISC DHCP Server (Internet Systems Consortium Dynamic Host Configuration Server) - это программа, работающая в фоновом режиме (служба, демон), которая отвечает за автоматическую выдачу сетевых настроек для разных устройств.
- https://www.isc.org/ - официальный сайт Internet Systems Consortium
Документация по ISC DHCP Server доступна во встроенной справочной системе GNU/Linux, используем команды "man":
man dhcpd
man dhcpd.conf
Планируя структуру сети в начале статьи мы уже определились с пулами адресов для сетевых интерфейсов, которыми будет орудовать DHCPD:
- eth0: 192.168.1.10 - 192.168.1.100
- wlan0: 192.168.2.10 - 192.168.2.100
Открываем для редактирования конфигурационный файл DHCP сервера - dhcpd.conf (не путать с dhcpcd.conf для DHCP клиента):
sudo nano /etc/dhcp/dhcpd.conf
Укажем что этот DHCP-сервер будет официальным в сети, для этого ищем строчку "#authoritative;" и раскомментируем ее, убрав значек решотки:
authoritative;
Добавляем в самый низ файла две секции с описанием параметров выдачи адресов и настроек для подсетей:
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.10 192.168.1.100;
option broadcast-address 192.168.1.255;
option routers 192.168.1.1;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local-network";
# OpenDNS
option domain-name-servers 208.67.222.222, 208.67.220.220;
}
subnet 192.168.2.0 netmask 255.255.255.0 {
range 192.168.2.10 192.168.2.100;
option broadcast-address 192.168.2.255;
option routers 192.168.2.1;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local-network";
# OpenDNS
option domain-name-servers 208.67.222.222, 208.67.220.220;
}
Также, по желанию, можно привязать какой-либо фиксированный IP-адрес к какому-то устройству по его MAC-адресу. Например, сделаем так, чтобы тестовый лептоп с мак-адресом сетевой карты "00:0c:12:b6:f2:c8" всегда получал IP-адрес "192.168.1.55", для этого добавим в конец файла "dhcpd.conf" еще одну секцию:
host TEST-LAPTOP {
hardware ethernet 00:0c:12:b6:f2:c8;
fixed-address 192.168.1.55;
}
По завершению редактирования конфигурационного файла DHCPD выполним проверку его синтаксиса:
sudo dhcpd -t
Если нет никаких предупреждений и указаний о наличии ошибок - значит все отлично!
По умолчанию DHCPD будет пробовать работать на всех доступных сетевых интерфейсах - нам это не нужно, поскольку eth1 у нас подключен к интернету и с ним уже работает служба DHCP клиента - dhcpcd.
Поэтому укажем DHCP серверу работать только с интерфейсами eth0 и wlan0:
sudo nano /etc/default/isc-dhcp-server
Прописываем названия интерфейсов для IPv4 через пробел:
INTERFACESv4="eth0 wlan0"
INTERFACESv6=""
Запускаем службу и смотрим ее состояние:
sudo systemctl start isc-dhcp-server
sudo systemctl status isc-dhcp-server
Наблюдать за всеми событиями служб DHCP сервера и клиента можно с помощью следующей команды:
cat /var/log/daemon.log | grep dhcp
DHCP сервер от ISC сохраняет внутреннюю базу данных о выданных когда-либо адресах и параметрах подключаемых устройств, эту информацию удобно использовать как для отладки, так и в других целях. Посмотреть файл базы данных можно командой:
less /var/lib/dhcp/dhcpd.leases
Содержимое и структура этого файла хорошо описаны во встроенной справочной системе:
man dhcpd.leases
Теперь можно попробовать подключить к роутеру другие сетевые устройства и убедиться что они получают корректные сетевые настройки. Подключенному устройству будут назначены следующие адреса:
- IP-адрес с подсетью 192.168.1.ххх для проводного подключения и с подсетью 192.168.2.ххх для беспроводного;
- Шлюз (Gateway) 192.168.1.1 для проводного подключения и 192.168.2.1 для беспроводного;
- Публичные DNS-сервера от OpenDNS (208.67.222.222, 208.67.220.220).
Подключив к USB-разъему малинки USB-Ethernet адаптер, который в свою очередь подключен сетевым кабелем к другому маршрутизатору с DHCP-сервером на борту или же интернет-провайдеру, мы получим работающий интернет как на малинке, так и на подключенных к ней сетевых устройствах.
Маршрутизатор на основе Raspberry Pi должен уже работать.
Решение проблемы старта isc-dhcpd и активации сетевых интерфейсов
После нескольких перезапусков роутера на основе малинки вы можете столкнуться с проблемой, когда подключаемые к нему сетевые устройства не могут получить сетевых настроек (IP, Gateway, DNS) по протоколу DHCP.
Причина этому - запуск демона DHCPD, прежде чем сетевые интерфейсы станут активными и получат указанные нами в настройках DHCPCD статические IP-адреса.
Смотрим логи системы с момента ее запуска:
journalctl -b
Там можно встретить следующие предупреждения для сетевых интерфейсов (пример для eth0):
No subnet declaration for eth0 (no IPv4 addresses).
** Ignoring requests on eth0. If this is not what
you want, please write a subnet declaration
in your dhcpd.conf file for the network segment
to which interface eth0 is attached. **
Not configured to listen on any interfaces!
If you think you have received this message due to a bug rather
than a configuration issue please read the section on submitting
bugs on either our web page at www.isc.org or in the README file
before submitting a bug. These pages explain the proper
process and the information we find helpful for debugging..
exiting.
Это означает, что в конфигурационном файле "dhcpd.conf" нет описания подходящей зоны для сетевого интерфейса eth0 с IP-адресом и подсетью которые ему назначены на данный момент. Поэтому обслуживание этого интерфейса будет игнорироваться.
По сути, интерфейс eth0 еще не успел получить статический IP-адрес и подсеть, указанный в настройках DHCPCD. Такое же предупреждение появится и для второго интерфейса - wlan0.
Для решения проблемы можно попробовать переназначить приоритеты для запуска служб, то есть запускать DHCPD на более позднем этапе загрузки, после инициализации DHCPCD и сетевой подсистемы в целом.
На форуме raspberrypi.org нашел описание решения подобной проблемы, заключается оно в создании копии юнит-файла "isc-dhcp-server.service" для systemd, с указанием дополнительных опций "Restart=on-failure" и "RestartSec=5", что позволило бы при неудачном старте или сбое (failure) демона "isc-dhcp-server" выполнить его автоматический перезапуск через 5 секунд.
Подобное решение мне показалось интересным, но оно не заработало, и вот почему... Предупреждение в логах системы гласит что в файле "dhcpd.conf" отсутствует описание зоны для закрепленной за интерфейсом подсети. Интерфейс еще не успел получить настройки от DHCPCD, поэтому он просто игнорируется службой DHCPD.
Сама же служба DHCPD при этом не "падает" (failure) и продолжает работать, выводя в системный лог предупреждение (warning). Таким образом, опция "Restart=on-failure" в юнит-файле проблему не решит.
К тому же, подобное копирование и изменение системного юнит-файла "isc-dhcp-server.service" может привести в будущем к проблемам при получении обновлений для пакета isc-dhcp-server.
Решил разобраться с этой проблемой по своему - создать сторожевого песика (Watchdog), являющего из себя скрипт, который будет запущен при старте системы и проследит за получением сетевых адресов на указанных интерфейсах, после этого выполнит перезапуск службы "isc-dhcp-server".
Открываем для редактирования новый файл:
sudo nano /usr/local/sbin/systemd-isc-watchdog.sh
Вставляем в него следующий код:
#!/bin/bash
# Waiting for interfaces assigning IP, than restarting isc-dhcp-server.
# https://ph0en1x.net
declare -A INTERFACES
INTERFACES=(
[eth0]="192.168.1.1"
[wlan0]="192.168.2.1"
)
for i in "${!INTERFACES[@]}"
do
# wait until interface accepts IP
for ((n=0; n < 60; n++))
do
has_ip=`ip a show "$i" | grep "inet ${INTERFACES[$i]}"`
if [ ! -z "$has_ip" ]; then
echo "ISC_Watchdog: interface $i ready."
break
fi
sleep 1
done
done
sleep 15
echo "ISC_Watchdog: restarting isc-dhcp-server..."
systemctl restart isc-dhcp-server
exit 0
Скрипт работает следующим образом:
- запускается при старте ОС отдельно созданным для systemd юнит-файлом;
- проходит в цикле через каждую пару [название_интерфейса]=IP из массива INTERFACES;
- для каждого интерфейса делается 60 проверок наличия нужного IP-адреса с таймаутом 1 секунда;
- после завершения проверок ждет 15 секунд и перезапускает isc-dhcp-server;
Таким образом, проверка с ожиданием может длиться максимум 60+60 секунд, после этого в любом случае через 15 секунд DHCPD будет перезапущен.
Здесь важно указать верные IP-адреса для сетевых интерфейсов eth0 и wlan0. Если планируется использовать еще какой-то сетевой интерфейс для внутренней сети (например eth2), обслуживаемый DHCPD и получивший IP-адрес (например 192.168.10.1) через DHCPCD, то его также можно добавить в массив строчкой "[eth2]="192.168.10.1".
Дадим файлу скрипта право на запуск и откроем для редактирования новый файл с юнитом для systemd:
sudo chmod +x /usr/local/sbin/systemd-isc-watchdog.sh
sudo nano /etc/systemd/system/isc-watchdog.service
Поместим в него следующее содержимое:
[Unit]
Description=Watchdog for isc-dhcp-server.
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/systemd-isc-watchdog.sh
RemainAfterExit=no
[Install]
WantedBy=multi-user.target
Разрешим обработку юнита при старте ОС:
sudo systemctl enable isc-watchdog.service
На всякий случай, можно еще добавить периодический перезапуск демона через crontab, откроем файл системного планировщика заданий для редактирования:
sudo nano /etc/crontab
Добавим строчку с новым заданием:
# Restart ISC DHCP-server
1 * * * * root /bin/systemctl restart isc-dhcp-server
Таким образом мы настроили перезапуск демона isc-dhcp-server в начале каждого часа (период 60 минут).
Настройка статического списка DNS-серверов
Список DNS-серверов, используемых системой, как правило содержится в файле "/etc/resolv.conf". По умолчанию, содержимое этого файла в Raspbian автоматически генерируется при запуске системы и может быть изменено различными службами (например DHCPCD, PPP и другими).
При подключении сетевого кабеля от провайдера интернета к USB-Ethernet адаптеру с интерфейсом eth1, этому интерфейсу будет присвоен IP-адрес от провайдера, в системе будет установлен маршрут по умолчанию (Default Route) с указанием шлюза провайдера, а также в файл "/etc/resolv.conf" будет помещен список DNS-серверов. Все эти действия выполняет сетевой демон DHCPCD (DHCP-клиент).
Мы можем сами указать список предпочитаемых DNS-серверов, поместив их в файл "/etc/resolv.conf", но после презагрузки системы или же после переподключения USB-Ethernet адаптера, все внесенные в файл изменения будут перезаписаны демоном DHCPCD.
Если вы действительно хотите использовать свой список DNS-серверов (например от Гугла), то нужно указать службе DHCPCD не выполнять "хук" (не "подцеплять") список NS-серверов, полученный от другого маршрутизатора по DHCP.
Добавим IP-адреса публичных серверов от OpenDNS:
sudo nano /etc/resolv.conf
Заменим содержимое файла строчками:
nameserver 208.67.222.222
nameserver 208.67.220.220
Теперь нужно отредактировать файл "/etc/dhcpcd.conf":
sudo nano /etc/dhcpcd.conf
Добавляем в нем строчку "nohook resolv.conf", вот пример из текущей конфигурации:
nohook wpa_supplicant
nohook resolv.conf
interface wlan0
static ip_address=192.168.2.1/24
Данное ограничение на действия с файлом "/etc/resolv.conf" будет справедливо только для службы DHCPCD, другие программы и далее смогут вносить изменения в этот файл.
Чтобы полностью запретить изменение прописанных вручную DNS-серверов в файле "/etc/resolv.conf", его нужно защитить от перезаписи, важно заметить что манипуляции с командой "chmod -w" здесь не помогут. Для этой цели воспользуемся командой "chattr", которая служит для изменения атрибутов файлов.
Установим файлу "/etc/resolv.conf" атрибут "immutable" (не модифицируемый), который запретит переименование файла, создание символьных ссылок для него, не позволит записывать в него данные и запускать. Снять этот атрибут из файла может только суперпользователь - root.
sudo chattr +i /etc/resolv.conf
Если нужно будет отредактировать файл, то с помощью следующей команды можно снять атрибут "immutable":
sudo chattr -i /etc/resolv.conf
Важно понимать, что получаемый от интернет-провайдера список DNS-серверов может использоваться для сопоставления доменных имен и IP-адресов ресурсов, которые работают внутри сети провайдера (не в интернете).
В случае замены DNS-серверов, полученных от интернет-провайдера по DHCP, на любые другие, его внутренние сайты и ресурсы могут оказаться недоступными. Исправить это можно временной установкой DNS-серверов провайдера или же прописыванием статических записей с соответствием "хост-IP" часто используемых ресурсов из сети провайдера в файл hosts.
Важная заметка в плане информационной безопасности публичных DNS: делая запросы к разным сайтам и хостам в интернете их имена будут преобразовываться в IP-адреса используя для этого указанные вами публичные DNS-сервера, соответственно компании что предоставляют такие услуги смогут видеть что с вашего IP выполняются DNS-запросы для получения адресов сопоставимых именам тех или иных сайтов.
Будут ли эти данные собраны и потом как-то использованы - можно лишь догадываться. Например в компании Гугл эта информация может быть использована в маркетинговых или других статистических целях.
По этим причинам рекомендую хорошо обдумать какому из публичных DNS-провайдеров отдавать предпочтение, и стоит ли это делать вообще если в вашем случае безопасность и приватность очень важна.
Таблица с публичными DNS-серверами от различных компаний по всему миру:
Компания | IPv4 nameservers | IPv6 nameservers | Примечание |
CloudFlare | 1.1.1.1 1.0.0.1 |
||
Google INC | 8.8.8.8 8.8.4.4 |
2001:4860:4860::8888 2001:4860:4860::8844 |
|
OpenNIC | 185.121.177.177 185.121.177.53 |
2a05:dfc7:5::53 2a05:dfc7:5::5353 |
|
UncensoredDNS | 91.239.100.100 89.233.43.71 |
2001:67c:28a4:: 2a01:3a0:53:53:: |
anycast unicast |
Comodo | 8.26.56.26 8.20.247.20 |
||
DNS.WATCH | 84.200.69.80 84.200.70.40 |
2001:1608:10:25::1c04:b12f 2001:1608:10:25::9249:d69b |
|
OpenDNS | 208.67.222.222 208.67.220.220 |
2620:0:ccc::2 2620:0:ccd::2 |
|
Quad9 | 9.9.9.9 9.9.9.10 |
2620:fe::fe 2620:fe::10 |
С blocklist и DNSSEC Без blocklist и DNSSEC |
Подготовка 3G-модема, узнаем его состояние используя minicom
Многие 3G-модемы являются составными устройствами, которые могут эмулировать несколько различных устройств:
- виртуальный накопитель CD-ROM (как правило на нем содержатся драйвера и программы);
- картридер для Flash-карты (если в устройстве есть разьем под карточку);
- модем.
В начале статьи нами был установлен пакет "usb-modeswitch", который представляет собой набор udev-правил (скриптов), позволяющих в автоматическом режиме переключить беспроводный 3G-адаптер из режима накопителя (как правило виртуальный CD-привод) в режим модема.
Подключаем 3G-модем к свободному USB-разъему малинки и смотрим какие устройства в /dev нам доступны для использования:
ls /dev | grep ttyUSB
Получим примерно следующий список файлов-устройств (последовательных портов):
ttyUSB0
ttyUSB1
ttyUSB2
ttyUSB3
Теперь не плохо бы узнать код производителя (Vendor ID, vid) и код устройства (Product ID, pid) для используемого модема, просмотрим список подключенных по USB к малинке устройств:
lsusb
Примерный вывод:
...
Bus 001 Device 008: ID 05c6:6000 Qualcomm, Inc. Siemens SG75
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
В данном случае модем определился как 'Siemens SG75' со следующими идентификаторами:
- Vendor ID = 05c6 (Qualcomm, Inc.);
- Product ID = 6000 (Siemens SG75).
Идентификаторы USB-устройств и их названия можно узнать на сайте проекта 'Linux USB Project', вот свежий список в формате TXT: http://www.linux-usb.org/usb.ids
Идентификаторы 'Vendor ID' и 'Product ID' зависят от типа используемого вами 3G-модема и будут отличаться от приведенного выше примера.
Теперь мы можем подключиться к любому из ttyUSB* используя эмулятор последовательного терминала 'minicom'. О параметрах запуска и работе с программным эмулятором последовательного терминала 'minicom' можно узнать из его man-странички:
man minicom
В моем случае на прием команд согласились только два из портов: 'ttyUSB0' и 'ttyUSB1'. Первый порт используется для управления модемом, а второй - для приема и передачи потока данных.
Подключимся к 'ttyUSB0':
minicom --device=/dev/ttyUSB0
При успешном подключении к порту увидим приветствие и информацию по вызову справки:
Welcome to minicom 2.7
OPTIONS: I18n
Compiled on Apr 22 2017, 09:14:19.
Port /dev/ttyUSB0, 11:47:54
Press CTRL-A Z for help on special keys
Для отображения списка команд (справки) нужно нажать комбинацию клавиш CTRL+A и отпустив их потом нажать Z, для выхода из справки нажимаем ENTER.
Теперь для тестирования и управления модема можно использовать AT-команды. Проверим отвечает ли нам модем - наберем команду "AT" и нажмем ENTER:
Press CTRL-A Z for help on special keys
AT
OK
Если все работает то получим ответ 'OK'.
Используя AT-команды можно узнать разную полезную информацию о модеме и его состоянии, установить режим его работы, и даже отправить SMS (если поддерживается).
Список некоторых информационных AT-команд:
- ATI - вывести информацию о модеме;
- AT+CGMI - отобразить только производителя модема;
- AT+CGMR - вывести версию программного обеспечения;
- AT^HWVER - вывести версию аппаратного обеспечения;
- AT+CGSN - вывести IMEI;
- AT+CIMI - вывести IMSI;
- AT^PREFMODE=? - вывести поддерживаемые режимы передачи данных;
- AT+CSQ - вывести уровень сигнала 3G;
- AT+CBC - уровень заряда батареи (если используется автономный модем или телефон);
- AT^CVOICE=? - поддерживает ли модем голосовые вызовы;
- AT^SYSINFO - вывести системную информацию (состояние, роуминг, режим).
Если какая-то из команд вывела ошибку и терминал отказывается отвечать - выполним выход из программы со сбросом состояния модема: нажимаем CTRL+A, Z и потом X. Теперь можно снова подключиться к порту модема используя minicom.
Запрос 'AT^SYSINFO' выведет информацию одной закодированной строчкой:
AT^SYSINFO
^SYSINFO:2,255,0,8,240
Формат выведенной информации: [status], [domain], [roaming status], [mode], [SIM state]. Сегменты разделены запятыми и имеют соответствующие текущим параметрам цифровые значения.
[status]:
- 0 - No service (нет сигнала);
- 1 - Restricted service (ограниченный доступ);
- 2 - Valid service (сигнал ок);
- 3 - Restricted regional service (ограниченный региональный доступ);
- 4 - Power-saving and deep sleep state (спящий режим).
[domain]:
- 0 - No service;
- 1 - Only CS service;
- 2 - Only PS service;
- 3 - PS+CS service;
- 4 - CS and PS not registered, searching.
[roaming status]:
- 0 - Non roaming (роуминг не активен);
- 1 - Roaming (в роуминге).
[mode]:
- 0 - No service;
- 1 - AMPS mode;
- 2 - CDMA mode;
- 3 - GSM/GPRS mode;
- 4 - HDR mode;
- 5 - WCDMA mode;
- 6 - GPS mode;
- 7 GSM/WCDMA;
- 8 CDMA/HDR HYBRID;
- 15 TD-SCDMA mode.
[SIM state]:
- 0 - Invalid USIM card state or pin code locked;
- 1 - Valid USIM card state;
- 2 - USIM is invalid in case of CS;
- 3 - USIM is invalid in case of PS;
- 4 - USIM is invalid in case of either CS or PS;
- 255 - USIM card is not existent.
Запрос 'AT+CSQ' выведет уровень сигнала:
AT+CSQ
+CSQ: 26, 99
В данном случае получено значение в формате '26, 99', где:
- 26 - Received signal strength indicator (уровень сигнала в CSQ)
- 99 - Bit Error Rate (счетчик ошибок)
Для перевода значения из CSQ в dBm можно использовать формулу:
dBm = -113 + N * 2
где N - это полученное после AT-команды значение CSQ.
dBm = -113 + 26 * 3 = -61 (отличное качество сигнала).
Чтобы вам было легче сориентироваться в значениях, приведу небольшую табличку:
Значение CSQ | RSSI, dBm | Описание |
2 ... 9 | -109 ... -95 | Плохой сигнал |
10 ... 14 | -93 ... -85 | Так себе, ОК |
15 ... 19 | -83 ... -75 | Хороший сигнал |
20 ... 30 | -73 ... -53 | Отличный сигнал |
Запрос 'AT^PREFMODE=?' выведет список поддерживаемых режимов передачи данных для 3G-модема:
AT^PREFMODE=?
^PREFMODE:(2,4,8)
Возможные режимы работы модема:
- 2 - CDMA2000 (1x), скорость обмена данными до 153 КБит/сек;
- 4 - EVDO (Evolution Data Only), высокая скорость обмена данными;
- 8 - гибридный, с автоматическим выбором типа подключения по состоянию сигнала.
Скорость передачи данных в разных ревизиях EVDO:
- rev.0 - 2,4 Mbit/s на прием 0,153 Mbit/s на передачу;
- rev.A - 3,1 Mbit/s на прием 1,8 Mbit/s на передачу;
- rev.B - 73,5 Mbit/s на прием 27 Mbit/s на передачу.
Как видите, с помощью AT-команд можно узнать очень много полезной информации о модеме, она вам может пригодиться для отладки, мониторинга и сбора информации о модеме.
3G-модем и консольная звонилка WVDIAL
Для работы с 3G-USB модемом нам понадобится программа "wvdial", которая умеет выполнять дозвон к провайдеру с установленными параметрами, а также следить за состоянием сетевого подключения.
WVDial (WeaVe Dial) - это умная программа для организации подключений с использованием модемов через протокол PPP (Point-to-Point Protocol). Мы уже установили ее на этапе установки программ.
Документация по wvdial и параметрам его конфигурационного файла:
man wvdial
man wvdial.conf
Для обнаружения модема и создания базового файла с настройками, желательно запустить программу-конфигуратор:
sudo wvdialconf
Программа выполнит определение и тест модема, на основе полученных данных сгенерирует базовый конфигурационный файл:
Editing `/etc/wvdial.conf'.
Scanning your serial ports for a modem.
ttyUSB0<*1>: ATQ0 V1 E1 -- OK
ttyUSB0<*1>: ATQ0 V1 E1 Z -- OK
ttyUSB0<*1>: ATQ0 V1 E1 S0=0 -- OK
ttyUSB0<*1>: ATQ0 V1 E1 S0=0 &C1 -- OK
ttyUSB0<*1>: ATQ0 V1 E1 S0=0 &C1 &D2 -- OK
ttyUSB0<*1>: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 -- OK
ttyUSB0<*1>: Modem Identifier: ATI -- Manufacturer: +GMI: Qualcomm
ttyUSB0<*1>: Speed 9600: AT -- OK
ttyUSB0<*1>: Max speed is 9600; that should be safe.
ttyUSB0<*1>: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 -- OK
...
Found a modem on /dev/ttyUSB0.
Modem configuration written to /etc/wvdial.conf.
ttyUSB0<Info>: Speed 9600; init "ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0"
ttyUSB1<Info>: Speed 9600; init "ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0"
Теперь файл "/etc/wvdial.conf" должен быть уже создан, в нем прописаны настройки и путь к файлу последовательного порта (/dev/ttyUSB0), через который будет работать модем. Откроем "wvdial.conf" для редактирования:
sudo nano /etc/wvdial.conf
Примерно так выглядит мой уже измененный конфигурационный файл:
[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Init3 = AT+CSQ
Init4 = AT^PREFMODE=8
Modem Type = Analog Modem
Phone = #777
ISDN = 0
Username = USER
Password = PASSWORD
New PPPD = yes
Modem = /dev/ttyUSB0
Baud = 9600
В параметрах Init1-init4 содержатся наборы AT-команд для управления модемом, здесь я вручную добавил строку "Init4 = AT^PREFMODE=8", которая принудительно пытается переключить модем в гибридный режим работы EVDO+CDMA2000 (8).
Если у вас в местности слабый и не стабильный сигнал, то возможно что стоит переключить модем на использование именно гибридного режима (8).
Строчка 'Init3 = AT+CSQ' заставляет модем вывести текущий уровень принимаемого сигнала, об этом я рассказывал в предыдущем разделе.
Следующие параметры в конфигурационном файле отвечают за дозвон и авторизацию, установите их в соответствии с инструкциями от своего провайдера:
- Phone = #777 - номер телефона для дозвона;
- Username = USER - имя пользователя;
- Password = PASSWORD - пароль.
В случае если в файле "/etc/resolv.conf" прописаны статичные DNS-сервера целесообразно отключить получение их списка от провайдера 3G-интернета. Для этого в файл /etc/wvdial.conf нужно добавить следующую строчку:
Auto DNS = Off
Также в данном случае нужно открыть для редактирования файл "/etc/ppp/peers/wvdial":
sudo nano /etc/ppp/peers/wvdial
Комментируем (ставим спереди значек решотки) в нем строчку:
#usepeerdns
Теперь мы можем запустить дозвон до провайдера и получить интернет подключение с помощью wvdial. Если у вас к малинке уже подключен интернет через внешний USB Ethernet адаптер, то интерфейс этого адаптера нужно предварительно деактивировать:
sudo ip link set dev eth1 down
Для запуска дозвона используем следующую команду:
sudo wvdial
Начнется процедура выполнения AT-команд и получения параметров соединения, IP-адресов.
--> WvDial: Internet dialer version 1.61
--> Initializing modem.
--> Sending: ATZ
ATZ
OK
--> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
...
--> PPP negotiation detected.
--> Starting pppd at Mon Jun 25 15:05:21 2018
--> Pid of pppd: 2967
--> Using interface ppp0
--> local IP address 10.10.10.82
--> remote IP address 10.10.11.3
--> primary DNS address 192.168.10.121
--> secondary DNS address 192.168.10.122
На малинке должен появиться интернет через 3G-соединение. Будет создан и активирован интерфейс ppp0, это можно проверить выполнив команду 'ip a':
$ ip a
...
5: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 3
link/ppp
inet 10.10.10.122 peer 10.1.1.3/32 scope global ppp0
valid_lft forever preferred_lft forever
Проверяем пингом соединение с каким-то внешним сайтом:
ping reddit.com
Результат:
PING reddit.com (151.101.65.140) 56(84) bytes of data.
64 bytes from 151.101.65.140 (151.101.65.140): icmp_seq=1 ttl=57 time=131 ms
64 bytes from 151.101.65.140 (151.101.65.140): icmp_seq=2 ttl=57 time=123 ms
64 bytes from 151.101.65.140 (151.101.65.140): icmp_seq=3 ttl=57 time=120 ms
^C
--- reddit.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 120.250/125.185/131.506/4.698 ms
Интернет есть, все работает!
Прервать соединение через wvdial можно в окне терминала, где была запущена команда на старт, достаточно нажать комбинацию клавиш 'CTRL+C'. Также можно принудительно завершить все процессы под именем wvdial следующей командой:
sudo killall wvdial
После деактивации 3G-подключения можем вернуть обратно интернет подключение через USB Ethernet адаптер (интерфейс eth1), активируем проводной интерфейс:
sudo ip link set dev eth1 up
Программу wvdial очень удобно запускать в мультиплексоре терминалов - TMUX (Terminal MUltipleXor). Это позволит выполнять программу в фоновом режиме и при необходимости наблюдать за состоянием соединения и процессом дозвона wvdial. Для этого запустим сначала сам TMUX:
tmux
В открывшемся терминале запускаем 'wvdial':
sudo wvdial
Теперь программа дозвона выполняется в программном терминале TMUX, чтобы отключиться от него и перейти в основной терминал достаточно нажать комбинацию клавиш 'CTRL+b', а потом отпустив их 'd'. Чтобы обратно подключиться к терминалу TMUX с запущенным и работающем в нем wvdial достаточно выполнить команду:
tmux attach
TMUX - очень мощная программа, которая позволяет разделить экран (сессию) на несколько подтерминалов, запускать и управлять множеством сессий и содержит много других полезных и удобных возможностей.
Больше информации о этой программе можно узнать из ее man-страници:
man tmux
Режимы управления частотой CPU в Raspberry Pi и его температура
Ядро Linux управляет частотой микропроцессора (CPU) в одном из установленных режимов:
- ondemand - по требованию, частота каждого ядра CPU возрастает при увеличении нагрузки;
- performance - частота ядер CPU постоянно имеет максимальное значение;
- powersave - энергосберегающий режим.
Узнать текущий режим управления частотой первого ядра CPU Raspberry Pi (отсчет начинается с 0) можно командой:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
Узнаем режимы для каждого из ядер:
for i in /sys/devices/system/cpu/*/cpufreq/scaling_governor; do cat $i; done
Примерный вывод для 4х-ядерного микропроцессора малинки:
ondemand
ondemand
ondemand
ondemand
По умолчанию в малинке используется 'ondemand'.
Текущий режим всех ядер CPU можно попробовать изменить например на 'performance' (максимальная частота), для этого нужно выполнить команду:
sudo sh -c 'for i in /sys/devices/system/cpu/*/cpufreq/scaling_governor; do echo performance > $i; done'
Таким же способом можно перевести все ядра в режим энергосбережения (минимальная частота):
sudo sh -c 'for i in /sys/devices/system/cpu/*/cpufreq/scaling_governor; do echo powersave > $i; done'
Cписок доступных рабочих частот всех ядер микропроцессора можно узнать командой:
for i in /sys/devices/system/cpu/*/cpufreq/scaling_available_frequencies; do cat $i; done
В моем случае доступны только по две частоты для каждого ядра:
600000 1200000
Минимальную и минимальную частоты первого ядра можно узнать следующими двумя командами:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
Частоты ядер микропроцессора в Raspberry Pi 3 Model B:
- 600МГц - минимальная (постоянно включена в режиме powersave);
- 1200МГц - максимальная (постоянно включена в режиме performance).
Узнаем текущие частоты всех ядер микропроцессора:
for i in /sys/devices/system/cpu/*/cpufreq/scaling_cur_freq; do cat $i; done
Вывод:
600000
600000
600000
600000
Я бы не рекомендовал изменять scaling_governor из значения по умолчанию 'ondemand' на 'powersave' или 'performance' если малинка будет работать в режиме роутера, режим 'ondemand' - оптимальный в большинстве случаев применения малинки.
Если все же требуется перманентно перевести микропроцессор малинки например в энергосберегающий режим, то это можно сделать добавив соответствующую конструкцию из команд в файл 'rc.local':
sudo nano /etc/rc.local
Добавляем в самый низ строку с командами:
/bin/sh -c 'for i in /sys/devices/system/cpu/*/cpufreq/scaling_governor; do echo powersave > $i; done'
или так (для 4х ядер CPU):
/bin/echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
/bin/echo powersave > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
/bin/echo powersave > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
/bin/echo powersave > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
Теперь после перезагрузки Raspbian микропроцессор будет находиться в режиме энергосбережения.
В зависимости от нагрузки на CPU его температура будет возрастать. Узнать температуру микропроцессора Raspberry Pi можно следующей командой:
cat /sys/class/thermal/thermal_zone0/temp
Результатом будет число (пример):
45622
Делим его на 1000 и получим: 45,622 градусов по Цельсию.
Также температуру чипа можно получить используя одну из утилит для работы с графическим процессором (GPU):
/opt/vc/bin/vcgencmd measure_temp
Примерный вывод:
temp=45.6'C
Настройка часов реального времени (RTC)
В прошлой статье я описывал как исправить, подключить и установить в корпус модуль часов реального времени DS1307. Данный модуль работает используя шину данных I2C.
В одной из прошлых статей я описывал как работать с шиной I2C. На этапе настройки малинки мы уже включили эту шину, теперь можно просканировать ее на предмет подключенных к ней устройств:
sudo i2cdetect -y 1
Пример результата выполнения команды:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Видим что обнаружены три устройства:
- 0x3c - OLED-дисплей SSD1306;
- 0x68 - модуль RTC DS1307;
- 0x50 - I2C EEPROM 24C32, установленная на плате с DS1307.
Модуль часов определен и готов к использованию. Зарегистрируем модуль часов реального времени в операционной системе:
sudo sh -c 'echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device'
Теперь, если снова вывести список адресов I2C-устройств в консоль, то вместо адреса модуля "68" появятся "UU":
Рис. 3. Смена вывода адреса DS1307 после активации.
Считаем текущее значение времени, установленное в RTC:
sudo hwclock -r
При первом подключении и использовании модуля получим дату 2000-01-01:
2000-01-01 02:00:03.093197+0200
Проверяем текущую дату и время в Raspbian, выполним любую из команд:
date
timedatectl
Если дата или время в системе отличается от реальных значений - исправляем их, сделать это можно следующей командой:
sudo timedatectl set-time '2050-11-23 08:10:40'
где:
- 2050-11-23 - год в формате: год-мес-день;
- 08:10:40 - время в формате: час:мин:сек.
По умолчанию в Raspbian включена служба NTP (Network Time Protocol), которая служит для синхронизации времени через интернет, поэтому делать правку даты или времени скорее всего не понадобится.
Теперь можем выполнить запись текущих значений даты и времени в модуль RTC:
sudo hwclock -w
Считываем значения из модуля RTC, убедимся что значения записались:
sudo hwclock -r
После выполнения команды должны увидеть текущие дату и время.
Теперь мы можем выполнять синхронизацию системного времени ОС Raspbian с временем в RTC используя следующую команду:
hwclock -s
При каждой загрузке малинки нужно выполнять синхронизацию времени ОС с данными даты и времени из RTC, поэтому мы автоматизируем этот процесс.
Команды для инициализации I2C модуля и синхронизации системного времени можно добавить в файл '/etc/rc.local', но я предлагаю сделать для данной цели отдельный скрипт и юнит для systemd.
sudo nano /usr/local/sbin/systemd-i2chwclock.sh
Содержимое скрипта:
#!/bin/sh
# HWClock init script for systemd
/bin/echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
/bin/sleep 3
/sbin/hwclock -s
exit 0
Делаем файл исполняемым и запускаем его:
sudo chmod +x /usr/local/sbin/systemd-i2chwclock.sh
sudo /usr/local/sbin/systemd-i2chwclock.sh
Готовим юнит для systemd:
sudo nano /etc/systemd/system/i2chwclock.service
[Unit]
Description=I2C HWClock sync
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/systemd-i2chwclock.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Разрешаем запуск при старте системы:
sudo systemctl enable i2chwclock.service
Также, в данном случае, желательно отключить службу синхронизации времени через интернет. Узнаем установлена ли служба NTP:
sudo systemctl status ntp
Если же демон NTP установлен и запущен - остановим его и отключим:
sudo systemctl stop ntp
sudo systemctl disable ntp
Теперь можно перезагрузить малинку и проверить системное время - все должно быть в порядке!
Считываем показания термодатчика DS18B20
Датчик температуры DS18B20 установлен на плате модуля часов реального времени DS1307, его вывод данных подключен к пину интерфейса 1-Wire в Raspberry Pi, который соответствует IO4 (7-й вывод гребенки).
Интерфейс передачи данных 1-Wire (через один проводник) мы уже активировали на этапе базовой настройки операционной системы Raspbian.
Каждый датчик температуры DS18B20, подключаемый к малинке, получает свой уникальный идентификатор. В дереве устройств автоматически создается файловая структура, взаимодействуя с которой можно очень просто считать текущие данные из нужного нам датчика.
Выведем список директорий в дереве устройств, что имеют отношение к интерфейсу 1-Wire:
ls /sys/bus/w1/devices/
Примерный результат вывода:
28-021501b2baсf w1_bus_master1
Для датчиков температуры DS18B20 создаются директории вида "28-XXXXXXXXXXXX", таким образом можно идентифицировать каждый из подключенных датчиков. В нашем случае, подключен всего один датчик температуры, он получил идентификатор "28-021501b2baсf".
В директории этого устройства содержатся некая структура файлов и директорий, смотрим их список:
ls /sys/bus/w1/devices/28-021501b2baсf
Вывод команды:
driver hwmon id name power subsystem uevent w1_slave
В данном случае нас интересует файл под названием "w1_slave", выведем его содержимое в консоль:
cat /sys/bus/w1/devices/28-021501b2baсf/w1_slave
Примерный результат:
0e 02 4b 46 7f ff 0c 10 0b : crc=0b YES
0e 02 4b 46 7f ff 0c 10 0b t=32875
Здесь:
- crc=0b YES - говорит о том что контрольная сумма результата в порядке;
- t=32875 - число, поделив которое на 1000 получим текущее значение температуры, в данном примере это 32,875 градуса по Цельсию.
Для получения только числового значения температуры можно воспользоваться чтением данных из другого файла:
cat /sys/bus/w1/devices/28-021501b2baсf/hwmon/hwmon0/temp1_input
Результат:
32875
Минус последнего метода в том, что здесь не указано верна ли контрольная сумма операции и можно ли доверять этому значению.
Полученные с помощью этих команд данные можно использовать в программах написанных на Bash, Python и других языках программирования.
Генерация звуковых сигналов через пьезо-зуммер
Пьезо-зуммер ("пищалка") подключен к каналу IO18 (вивод 12 на гребенке малинки). Генерация звуковых сигналов осуществляется подачей импульсов разной частоты и длины на канал IO18.
В данном случае можно написать программу с несколькими вложенными циклами, которая будет генерировать очереди импульсов, а можно использовать функцию PWM (широтно-импульсная модуляция) в модуле Rpi.GPIO.
Подавая на пин 12 сигналы с определенными частотами и длительностью можно генерировать различные звуковые оповещения и мелодии.
В качестве примера приведу очень простую программу, которая генерирует "сигналы от инопланетян" , звучит достаточно забавно.
nano ~/speaker-alien-signal-test.py
Скопируйте в открывшийся редактор следующий код:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Raspberry Pi Router speaker test.
# https://ph0en1x.net
import RPi.GPIO as GPIO
from random import randrange
from time import sleep
GPIO.setmode(GPIO.BCM)
# Speaker connected to IO18 (pin N12).
GPIO.setup(18, GPIO.OUT)
# Start frequency=1Hz.
pwm = GPIO.PWM(18, 1)
# Generate meandr signal (duty_cycle=50%) |_|^|_|^|...
pwm.start(50)
try:
while True:
# Change frequency in random range 20Hz-10kHz.
pwm.ChangeFrequency(randrange(20,10001))
# Change timeout in random range 0.01-0.04 sec.
sleep(randrange(1,5)/100)
except KeyboardInterrupt:
pass
# Stop PWM, clean GPIO PIN state.
pwm.stop()
GPIO.cleanup()
Запускаем...
python3 ~/speaker-alien-signal-test.py
Прервать выполнение программы можно нажав комбинацию клавиш "CTRL+C" (break).
Чередуя комбинации "частота+длительность" сигнала можно создать свою звуковую мелодию. Согласитесь, что составлять такую мелодию из значений частот и временных задержек не очень удобно - потребуется не мало времени и без хорошего музыкального слуха тут не обойтись.
Компания Nokia в свое время создала специальный формат RTTTL (Ring Tone Text Transfer Language) для описания, передачи и хранения мелодий в своих мобильных телефонах.
Пример мелодии 'Aqua - Barbie girl' в формате RTTTL:
Barbie girl:d=4,o=5,b=125:8g#,8e,8g#,8c#6,a,p,8f#,8d#,8f#,8b,g#,8f#,8e,p,8e,8c#,f#,c#,p,8f#,8e,g#,f#
Ниже я покажу как можно проигрывать мелодии в формате RTTTL используя платформу Raspberry Pi и подключенный к ней динамик.
Прежде чем перейдем к программе нам понадобится установить модуль 'rtttl' для языка Python, который позволит перевести строчку мелодии формата RTTTL в массив с частотами и интервалами. Исходный код модуля и примеры по его использованию приведены на GITHUB'е разработчика.
Установим модуль для Python3 следующей командой:
sudo pip3 install rtttl
Создадим новый скрипт:
nano ~/speaker-rttl-test.py
Исходный код программы:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Raspberry Pi Router speaker RTTTL melody test.
# https://ph0en1x.net
import RPi.GPIO as GPIO
from rtttl import parse_rtttl
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
pwm = GPIO.PWM(18, 1)
pwm.start(50)
song = ("Barbie girl:d=4,o=5,b=125:8g#,8e,8g#,8c#6,a,p,8f#,"
"8d#,8f#,8b,g#,8f#,8e,p,8e,8c#,f#,c#,p,8f#,8e,g#,f#")
notes = parse_rtttl(song)
try:
print("Playing: {} ...".format(notes['title']))
for note in notes['notes']:
if note['frequency'] == 0:
note['frequency'] = 1
pwm.ChangeFrequency(note['frequency'])
sleep(note['duration']/1000)
except KeyboardInterrupt:
pass
pwm.stop()
GPIO.cleanup()
Запуск:
python3 ~/speaker-rttl-test.py
Данная программа является немного измененным и дополненным вариантом предыдущего примера. Здесь добавлен парсинг кода песни в формате RTTTL и проигрывание полученных нот в цикле по-порядку.
Добавил еще небольшую поправку: если частота в списке нот равна нулю (для реализации паузы), то проигрываем сигнал с частотой 1Гц. Метод 'pwm.ChangeFrequency' в качестве аргумента не принимает значения равного 0 (будет выведена ошибка). К тому же в этом решении есть еще один плюс: если пауза длинная, то мы будем слышать как бы звук фоновых ударных с частотой 1Гц.
Для поиска текстов мелодий в формате RTTTL можно воспользоваться поисковыми системами, используйте следующую конструкцию поискового запроса: "RTTTL + имя_песни". Также есть сайты, которые содержат целые базы рингтонов, например - www.cellringtones.com.
Вот архив с кодами 10 000+ мелодий - 10000_melodies_rttl.7z (513КБ).
У большинства мелодий в приведенном архиве есть названия песен и исполнителей, присутствуют разные варианты одних и тех же песен, некоторые мелодии могут не работать или работать не корректно, в общем нужно тестировать.
Таким образом, вы можете создать программу для проигрывания нужной мелодии и использовать ее вызов в различных скриптах на Bash или Python, озвучивая различные события в самодельном роутере на Raspberry Pi.
Управление RGB-светодиодом и реагирование на нажатия кнопок
О том как работать с кнопками и светодиодами, подключенными к GPIO Raspberry Pi, я уже описывал в прошлых статьях:
Здесь приведу небольшой пример: будем в случайном порядке включать и выключать три цвета подключенного RGB-светодиода, при нажатии на одну из кнопок - перебор цветов остановится на текущем, при нажатии на другую кнопку - продолжится.
Если посмотреть на принципиальную схему, то светодиод и две из кнопок у нас подключены к следующим каналам GPIO:
- LED Red - IO23 (вывод 16);
- LED Green - IO24 (вывод 18);
- LED Blue - IO25 (вывод 22);
- Switch 1 - IO20 (вывод 38);
- Switch 2 - IO21 (вывод 40).
Создадим новый файл скрипта:
nano ~/leds-switches-test.py
Код программы:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Raspberry Pi Router LEDs+SWITCHes test.
# https://ph0en1x.net
import RPi.GPIO as GPIO
from random import choice, randrange
from time import sleep
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
# Prepare LEDs pins for OUTPUT.
leds_io = [23, 24, 25]
for led_io in leds_io:
GPIO.setup(led_io, GPIO.OUT)
# Prepare SWITCHes pins for INPUT
switch_on = 20
switch_off = 21
GPIO.setup(switch_on, GPIO.IN)
GPIO.setup(switch_off, GPIO.IN)
change_color_on = True
def callback_start(channel):
""" Start color changing. """
global change_color_on
change_color_on = True
print('START')
def callback_stop(channel):
""" Stop color changing. """
global change_color_on
change_color_on = False
print('STOP')
GPIO.add_event_detect(
switch_on,
GPIO.FALLING,
callback=callback_start,
bouncetime=300)
GPIO.add_event_detect(
switch_off,
GPIO.FALLING,
callback=callback_stop,
bouncetime=300)
print("Press CTRL+C to exit...")
try:
while True:
io_num = choice(leds_io)
io_level = GPIO.HIGH if randrange(0,2) else GPIO.LOW
if not GPIO.input(io_num) == io_level and change_color_on:
GPIO.output(io_num, io_level)
sleep(0.1)
sleep(0.01)
except KeyboardInterrupt:
GPIO.cleanup()
Для запуска скрипта без указания в командной строке интерпретатора python3 сделаем файл исполняемым:
chmod +x ~/leds-switches-test.py
Запуск:
~/leds-switches-test.py
С помощью кнопок можно управлять различными режимами работы роутера, запускать и останавливать выполнение программ и служб, завершать работу операционной системы. RGB-светодиодом можно индицировать различные события и режимы работы, оповещать о пропадании интернет-канала и так далее.
Вывод данных на OLED-дисплей
В статье "OLED дисплей SSD1306 (128х64px) и Raspberry Pi, подключение и эксперименты" я подробно расписал как выводить текст, геометрические фигуры и рисунки на дисплей SSD1306, который подключен к Raspberry Pi. Хочу заметить что в комментариях к этой статье вы найдете дополнительную полезную информацию, которой нет в самой статье.
В данном проекте использован точно такой же дисплей, предыдущее сканирование шины I2C показало что адрес этого дисплея на шине - 0x3c.
Набор скриптов для управления
Итак, сервер/роутер на основе raspberry Pi настроен, все службы работают, с использованием часов реального времени, светодиодов, пищалки, термодатчика, кнопок и дисплея разобрались.
Чтобы показать как это все можно связать вместе я написал несложную программу, которая являет собой набор Python-скриптов. Эта программа служит для вывода некоторой полезной информации на дисплей, управления кнопками с индикацией и звуковым оповещением для установленных событий, а также для безопасного завершения работы сервера.
Пять кнопок на корпусе малинки в данном случае выполняют следующие запрограммированные функции:
- Вызов меню, активация выбранного пункта;
- Выбрать предыдущий пункт меню;
- Выбрать следующий пункт меню;
- Вывод системной информации;
- Вывод пользовательской информации.
Рис. 4. Вывод меню и различной информации на дисплей сервера, построенного на Raspberry Pi.
Кнопки 4 и 5 можно очень просто перепрограммировать на другие действия, в данном случае эти кнопки дублируют функционал пунктов меню 1 и 2, так сказать "горячие кнопки".
Пищалка задействована следующим образом:
- звук 1 ("сигнал от инопланетян") - при нажатии кнопок 1, 4 и 5;
- звук 2 ("клик") - при нажатии кнопок 2 и 3;
- звук 3 ("ошибка") - при пропадании интернет-соединения.
Включить или выключить озвучивание событий можно через пункт меню 3 или же в конфигурационном файле (дальше кратко - КФ).
Использование RGB-светодиода (Red Green Blue):
- R - светится при отсутствующем интернет-подключении, а также при запуске процедуры завершения работы;
- G - мигает в процессе сбора данных для отображения системной и пользовательской информации;
- B - мигает при нажатии любой из кнопок;
- R+G+B - при запуске скрипта светятся все вместе.
В режиме бездействия экран малинки погашен, но через каждые 20 секунд отображается одна из анимаций, которые были подготовлены для примера:
- Вращающийся логотип Debian;
- Вращающийся атом;
- Краткий анимультфильм про кота и паука.
Список анимаций для отображения можно задать в КФ, там же можно отключить анимации, а еще для этого служит 4-й пункт меню.
Анимация в данном случае выполняется поочередной последовательной сменой картинок, которые хранятся в папке 'images/' проекта со скриптами. Имена файлов для картинок с анимацией начинаются с префикса 'anim_', дальше следует название анимации (оно указывается в списке анимаций для отображения в КФ), а за ним следует номер кадра по порядку: 1, 2, 3...8, 9, a, b, c, d...z. Если кадры нумеровать используя числа больше 10-ти (11, 25...) то порядок выполнения анимации будет нарушен.
Таким образом, собрав в папку 'images/' картинки-кадры и прописав имя анимации в КФ вы сможете добавить свою оригинальную анимацию - это может быть ваш логотип, какое-то сообщение, например "Не лезь, стукнет током!" с рисунком молнии и т.п.
Теперь кратко о сборе данных для отображения пользовательской и системной информации. Получение значений курсов валют и криптовалют осуществляется с помощью открытых API таких сайтов как "Coinmarcetcap.com" и "Currencyconverterapi.com".
Примерную температуру корпуса мы получим из данных датчика DS18B20, температуру CPU и общее/занятое количество ОЗУ узнаем используя штатные средства GNU/Linux.
Для периодического мониторинга и отображения наличия доступа в интернет будет использоваться проверка подключения к DNS-серверу гугла на порт 53.
Архив программы (python-скрипты и ресурсы) v.1.2 - (35KB).
! Репозитории со скриптами на GitHub больше размещаться не будут. После покупки мегакорпорацией, блокировок аккаунтов и полезных репозиториев, а также ситуации с youtube-dl нет желания там присутствовать.
Файловая структура директории 'rrouter':
- beeper.py - содержит класс, отвечающий за работу с звуковыми сигналами;
- config.py - конфигурационный файл (КФ);
- display.py - содержит класс, отвечающий за вывод информации на OLED-дисплей;
- [images] - директория с иконками событий и рисунками для анимации;
- __init__.py - скрипт инициализации модуля;
- leds.py - класс для управления RGB-светодиодом;
- menu.py - генерация и вывод пунктов меню;
- rrouter.py - основной файл программы, запускатся и работает как фоновый процесс;
- ssd1306.py - драйвер для OLED-дисплея SSD1306;
- sysinfo.py - класс для сбора и вывода на экран системной информации;
- usrinfo.py - класс для сбора и вывода на экран пользовательской информации (в данном случае курсов валют и криптовалют).
Рис. 5. Файловая структура директории со скриптами.
Хранить программу на малинке я предлагаю в домашней директории пользователя по умолчанию. Допустим что папка 'rrouter' из архива скопирована в домашнюю директорию пользователя 'pi' - "/home/pi/".
Перед использованием программы необходимо еще установить два питонных модуля:
- beautifulsoup4 - для парсинга HTML-документов;
- daemonize - для возможности выполнения программы в фоновом режиме как отдельный процесс со своими атрибутами;
- requests - для выполнения HTTP-запросов к сайтам с курсами валют.
sudo pip3 install beautifulsoup4 daemonize requests
Об использовании daemonize я уже рассказывал в одной из статей о безопасном завершении работы Raspbian нажатием на физическую кнопку.
Назначение переменных в конфигурационном файле:
- pins - содержит список названий и соответствующих каналов GPIO;
- ssd1306_12c_address - адрес модуля SSD1306 на шине I2C;
- sounds_is_on - разрешить/запретить звуковые сигналы по умолчанию;
- aminations_is_on - разрешить/запретить отображение анимаций по умолчанию;
- animation_sets - набор из названий анимаций, которые должны отображаться в режиме простоя;
- idle_time_to_sleep - время бездействия (после нажатия на одну из кнопок) для очистки экрана.
Выполним запуск программы с возможностью отладки и с выводом возможных ошибок в консоли:
/home/pi/rrouter/rrouter.py --manual
Безопасно прервать выполнение программы можно с помощью комбинации клавиш CTRL+C.
Если все хорошо, то перейдем к созданию systemd-юнита для автоматического запуска скрипта при старте операционной системы.
sudo nano /etc/systemd/system/rrouter-script.service
Содержимое юнита:
[Unit]
Description=Raspberry Pi router daemon
After=network.target
[Service]
Type=oneshot
User=root
ExecStart=/home/pi/rrouter/rrouter.py
ExecStop=/bin/kill -2 $MAINPID
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Разрешим запуск службы:
sudo systemctl enable rrouter-script.service
Запускаем, проверяем статус, если нужно останавливаем:
sudo systemctl start rrouter-script.service
sudo systemctl status rrouter-script.service
sudo systemctl stop rrouter-script.service
Перезапускаем малинку и проверяем запущен ли скрипт и правильно ли он выполняет свои функции.
Зная язык программирования Python вы можете модифицировать или дорабоатть скрипт так, как вам необходимо под ваши задачи или же просто в самообразовательных целях.
Другие полезности
Я заметил что иногда малинка отказывается нормально загружаться с первого раза, подключив дисплей к HDMI видео-выходу я увидел что процесс загрузки остановился на следующих строчках:
[ OK ] Started /etc/rc.local Compatibility.
[ OK ] Started Permit User Sessions.
Starting Light Display Manager...
Starting Hold until boot process finishes up...
Starting Terminate Plymouth Boot Screen...
Как видим все зависло на этапе завершения процесса Plymouth Boot Screen. Пакет Plymouth нужен для возможности наблюдать красивый экран загрузки с разными лого и в высоком разрешении.
Малинка в режиме сервера/роутера отлично работает без подключенного дисплея, обычного экрана загрузки в текстовом режиме вполне хватит для информативных целей, было принято решение удалить пакет plymouth:
sudo apt-get remove plymouth
Теперь желательно перезагрузить малинку несколько раз и убедиться что все ОК.
Если же нужно будет подключить дисплей и запустить графическую оболочку (например воспроизвести видео, открыть какой-то документ и т.п.), то здесь не возникнет никаких проблем, все должно работать как и раньше после запуска команды:
startx
Для защиты сервера на Raspberry Pi от перебора паролей по SSH из внутренних сетей (подключения через интерфейсы интернета фильтруются файрволом) можно установить fail2ban:
sudo apt-get install fail2ban
Конфигурация по умолчанию уже настроена на мониторинг попыток перебора паролей для демона SSHD, здесь настраивать больше ничего не нужно.
Для теста скорости интернета можно установить программу speedtest-cli:
sudo apt-get install speedtest-cli
Запускаем:
speedtest-cli
Программа выполнит тесты и отобразит максимальную скорость скачивания и отдачи для активного в данный момент канала интернет, вот пример вывода данных:
Testing download speed......................
Download: 57.26 Mbit/s
Testing upload speed........................
Upload: 59.87 Mbit/s
В моем случае, роутер на основе Raspberry Pi и подключенного адаптера USB-Ethernet позволил получать стабильные 100 МБит (примерно 12МБ/сек) при закачивании файлов с внутренней сети интернет-провайдера без значительных скачков и падений скорости.
Для тестирования производительности микропроцессора и памяти Raspberry Pi можно воспользоваться пакетом sysbench. Он позволит оценить разницу в производительности разных версий малинки, а также примерно сопоставить их с произвоительностью настольных систем для оценки возможности запуска различного ресурсоемкого ПО. Установим пакет:
sudo apt-get install sysbench
Запуск быстрого теста производительности CPU в 4 потока (в процессоре малинке 4 ядра):
sysbench --test=cpu --num-threads=4 run
По завершению работы программы в консоли будут выведены результаты теста, здесь нам наиболее интересна строчка "total time". В моем случае (Raspberry Pi 3 model B - ARMv7 Processor rev 4) тест завершился за 35,1910 секунд, если же его запустить в один поток то он выполнится примерно за 140 секунд.
Вот мы и имеем приблизительную цифру для оценки производительности CPU и сравнения ее с другими системами. Например, такой же тест на одном ядре (1 поток) микропроцессора Intel(R) Xeon(R) CPU E3-1241 3.50GHz будет завершен примерно за 9 секунд, здесь можно судить так: чтобы получить примерно такую же производительность нужен кластер из 4-х четырехядерных малинок.
Но опять же, здесь нельзя ставить в один ряд обычный серверный/десктопный процессор и микропроцессор на архитекутре ARM - у них разные возможности, наборы инструкций и разное назначение.
А теперь запустим тесты для определения скорости чтения и записи в оперативную память с различными размерами блоков (1КБ, 32КБ и 64КБ):
sysbench --test=memory --memory-block-size=1K --memory-scope=global --memory-total-size=1G --memory-oper=read run
sysbench --test=memory --memory-block-size=32K --memory-scope=global --memory-total-size=1G --memory-oper=read run
sysbench --test=memory --memory-block-size=64K --memory-scope=global --memory-total-size=1G --memory-oper=read run
sysbench --test=memory --memory-block-size=1K --memory-scope=global --memory-total-size=1G --memory-oper=write run
sysbench --test=memory --memory-block-size=32K --memory-scope=global --memory-total-size=1G --memory-oper=write run
sysbench --test=memory --memory-block-size=64K --memory-scope=global --memory-total-size=1G --memory-oper=write run
Результаты теста на моей малинке:
- READ (1K) - 740.49 MB/sec;
- READ (32K) - 11601.80 MB/sec;
- READ (64K) - 22536.72 MB/sec;
- WRITE (1K) - 544.77 MB/sec;
- WRITE (32K) - 1829.46 MB/sec;
- WRITE (64K) - 1957.27 MB/sec.
При разных типах операций производительность может очень и очень сильно отличаться, это нужно понимать и использовать подобные поверхностные тесты лишь для оценки "на глаз".
Чтобы оценить производительность микропроцессора и системы вцелом при выполнении различных операций (плавающая запятая, архивация, работа с MySQL и т.п.) можно воспользоваться комбайном под названием Phoronix Test Suite, который на данный момент поддерживает около 450 различных тестов и более 100 готовых наборов с тестами.
Доработки, установка других сетевых служб, усложнение сети
Здесь приведена достаточно простая схема реализации домашнего роутера (маршрутизатора). В ней нет вложенных сетевых туннелей, сложных правил маршрутизации, разбора пакетов по содержимому, сетевых служб работающих с разными более сложными и даже вложенными протоколами и т.п.
Наращивать функционал приведенной мною конфигурации можно, важно понимать что это потребует от вас изучения дополнительной информации и экспериментов, а соответственно затрат вашего времени и возможно даже вложения каких-то средств.
Если вам нужно прикрутить к роутеру из этой статьи: TOR, OpenVPN, RedSocks, Squid, LXC, Docker, Shadowsocks, Stunnel и т.п., то будьте готовы к тому, что придется самостоятельно разбираться и решать разными путями проблемы, который могут возникнуть в процессе какой либо достройки и/или обновления ПО, с учетом и пониманием того как изначально все настроено.
Все будущие доработки данной конфигурации с моей стороны, если на это появится надобность и желание, скорее всего будут оформлены в виде отдельных детально проработанных статей.
Устранение неполадок
В процессе эксплоатации может возникнуть ряд неисправностей, например по какой-то причине откажется стартовать какая-то служба и т.п.
Статус всех основных служб, которые мы настраивали в статье, можно посмотреть командами:
# DHCP-клиент
sudo systemctl status dhcpcd
# Служба для организации WLAN точки доступа
sudo systemctl status hostapd
# Самописный скрипт для IPTables
sudo systemctl status iptables
# DHCP-сервер от ISC
sudo systemctl status isc-dhcp-server
# Самописный скрипт для контроля интерфейсов ISC DHCP сервера
sudo systemctl status isc-watchdog
# Самописный скрипт для синхронизации времены с апаратными часами
sudo systemctl status i2chwclock
# Программа управления роутером написанная на Python
sudo systemctl status rrouter-script
Если какая-то служба не смогла запуститься то можно попробовать остановить/запустить ее вручную, вот пример для 'rrouter-script':
sudo systemctl stop rrouter-script
sudo systemctl start rrouter-script
Бывает что в следствии неконтроллируемых выключений и перезагрузок роутера (например пропадало электричество) какая-то из служб не смогла запуститься и даже ручной запуск не помогает.
В этом случае необходимо внимательно изучить вывод команды что показывает статус службы.
Для примера, если в статусе службы 'isc-dhcp-server' нашлась вот такая строчка:
Nov 28 19:24:06 rrouter isc-dhcp-server[720]: Segmentation fault
Видим здесь ошибку сегментации памяти - "Segmentation fault". Это значит что служба не смогла запустить бинарный файл, поскольку он не правильно обращается к памяти или же поврежден.
Причиной повреждения файлов могут быть ошибки на диске, возникшие, например, после внезапного пропадания питания или же в следствии износа ячеек Flash-карты памяти.
В таком случае, можно попробовать несколько раз перезагрузить малинку, как правило если разделы Linux были не корректно размонтированы перед выключением то при следующем старте ОС запустится программа проверки и исправления ошибок на диске - fsck (не сложно запомнить - от FileSystemChecK).
Если же перезагрузка не помогла и какая-то служба или службы все еще не могут запуститься, то нужно выполнить проверку файловых систем вручную на другом компьютере с GNU/Linux, подключив к нему карту памяти от нашего роутера или же принудительно указать запуск проверки накопителя данных на этапе следующего запуска системы Raspbian на роутере.
Чтобы программа fsck в принудительном порядке на этапе запуска Raspbian начала проверку подключенных устройств хранения данных на ошибки достаточно отредактировать файл:
sudo nano /boot/cmdline.txt
Там увидим длинную строку, в нее нужно добавить следующую директиву:
fsck.mode=force
Например, частично эта строка с добавленной директивой может выглядеть вот так:
... rootfstype=ext4 elevator=deadline fsck.mode=force fsck.repair=yes rootwait
Директивы fsck:
- "fsck.repair=yes" указывает что при наличии ошибок на диске на запрос о их исправлении нужно отвечать утвердительно - y/yes!
- "fsck.mode=force" дает системе понять что проверку дисков нужно запускать в любом случае обязательно.
Сохранив изменения достаточно перезагрузить ОС командой:
reboot
После запуска снова проверяем статус всех служб, есть большая вероятность что теперь все будет в порядке!
Если проблемы не исчезли, то стоит внимательно изучить журнал запуска системы и ее служб, а потом принимать нужные меры.
Например если в логах увидели 'I/O error' или еще что-то подобное, связанное с картой памяти 'mmcblk0', то скорее всего она уже изношена и требует замены.
Команды для просмотра журналов системы, лог с момента последнего запуска ОС:
dmesg
sudo journalctl -b
В завершение
О питании роутера и коммутатора я уже рассказал в предыдущей статье по данному проекту, но думаю не лишним будет еще раз здесь упомянуть.
Для надежной работы Raspberry Pi необходим хороший и стабильный источник питания с постоянным напряжением +5В, иначе возможны периодические хаотические зависания системы и сбои.
Поэтому не пожалейте на него 10-15$, а также будет замечательно если перед ним будет стоять еще и источник бесперебойного питания. К тому же, весь комплект (малинка+свитч) можно питать от аккумуляторного блока (PowerBank), имеющего два порта USB по +5В и током не менее 2А. В качестве примера такого пауербанка, из не дорогих, можно привести: "Trust Urban" (2USB x 2,4A = total 4,8A)
Cо всем уважением, прошу не писать в комментариях просьб и вопросов наподобие: "а как настроить на малинке service_1+service_2+protocol_X+Z" или "опишите как связать сеть A с сетями B-C через шифрованные туннели с авторизацией и метриками" и т.п.
Я бы рад здесь привести руководства по настройке всевозможных служб и сетевых конфигураций, чтобы помочь людям, но на это все просто физически не хватит времени чтобы изучить, опробовать, отладить и описать. К тому же, ждут своей очереди к публикации еще и другие интересные статьи разного направления.
Пожалуйста, оставляйте комментарии с замечаниями и вопросами строго по теме статьи!
Краткое видео с демонстрацией меню программы:
Вот такой получился занимательный проект, надеюсь было не скучно. Желаю всем креативных идей и творческих успехов!
Полезные ссылки:
Было бы интересно увидеть и последнюю часть)
Владимир, у вас будет такая возможность
Решил разделить последний раздел "Кнопочное управление, дисплей, пищалка, термодатчик" на несколько отдельных разделов и описать все более подробно.
Супер статья! Просто нет слов насколько она понятна, полезна, не вызывает не единого вопроса!
Статья полностью завершена.
Заснял небольшое видео работы с меню, а также там показано как программа реагирует на пропадание и появление интернет-подключения.
Поддерживаю мнение, что данный мануал просто великолепен! В моем случае, помог не только быстро и качественно добиться поставленной цели, но подробность описания еще и многому меня научила в плане работы с данной реализацией Raspbian. Низкий Вам поклон и +100500 в карму за проделанную работу, уважаемый автор!
ЗЫ. единственный затык произошел после редактирования /etc/fstab. а именно после добавления ,nodiratime в строку PARTUUID=p1234567-02 /. как и было заявлено после(!) описания редактирования? точка монтирования "/" стала ридонли. и всё бы ничего, но вот только команда "mount -o,remount /" не помогла. результатом работы данной команды было одно - данной точки монтирования не существует. пришлось сделать "mount -w /dev/x12345678 /", быстренько вернуть fstab в исходное состояние и ребутнуться. но все это даже к лучшему. вырвало меня из колеи копипаста и напомнило, что нужно думать и проверять. за что отдельное спасибо.
Dr.PPC, спасибо за отзыв!
В статье я не ожидал что может быть вариант с недогрузкой Raspbian через невозможность монтирования самого корневого раздела (в следствии совершенной ошибки в fstab), описанный вами опыт может кому-то пригодится. )
Добавил в статью еще информацию и несколько примеров с тестами производительности CPU и RAM.
Отличная статья! Еще бы фильтр сайтов для детей...
Важно понимать что со временем интерес ребенка возьмет верх и он доберется до любого желаемого контента если не у себя дома (что будет лишь минусом в будущем доверии к родителям), то на домашнем компьютере у своего друга. Поэтому, фильтрация контента, различные ограничения и запреты - это достаточно неоднозначное решение.
Считаю что более сложно, но эффективно - оставить достаточно свободы и вместе с тем попробовать заранее объяснить ребенку что хорошо и что плохо и главное почему оно так. Это даст правильный вектор на будущее развитие и более подготовленное понимание неизвестных ему в его возрасте "взрослых" вещей.
Ответ на ваш вопрос и некоторые из возможных решений попробую описать ниже.
На стороне клиента (браузер):
На стороне роутера:
Вариант с использованием безопасного DNS - наиболее простой, опишу подробно как его реализовать для примера со сконфигурированным роутером из данной статьи.
В интернете есть не мало провайдеров, предоставляющих безопасный DNS с фильтрацией нежелательного контента как на платной, так и на бесплатной основе.
В любом случае, нужно понимать, что использование стороннего DNS-сервера даст возможность его владельцу собирать информацию о посещаемых вами сайтах и возможно в будущем использовать эту информацию в его личных целях (анализ, продажа и т.п.).
Вот некоторые из DNS-провайдеров, предлагающих фильтрацию нежелательных сайтов:
В разделе Настройка демона ISC-DHCP-Server для нужной подсети (например для клиентов подключаемых только по Wi-Fi) необходимо изменить адреса DNS-серверов на те, которые предоставляет выбранный сервис.
Вот пример блока настроек для подсети "192.168.2.0" с прописанными ДНС-серверами от OpenDNS Family Shield:
Как это работает. Например ребенок запускает бнраузер с ноутбука, который подключен по беспроводной сети к нашему самодельному роутеру, операционная система на ноутбуке получит динамически назначиваемый IP-адрес, сетевой шлюз и список DNS-серверов по DHCP.
При попытке зайти на сайт с вредоносным контентом будет выполнен запрос IP-адреса для запрашиваемого браузером домена через полученные в сетевых настройках DNS-сервера (а они у нас в данном случае от OpenDNS), в ответ будет возвращен не реальный IP-адрес запрашиваемого домена, а IP-адрес сервера, например, с безопасной страницей-заглушкой. Все, доступ ограничен.
Привет!
Пожалуй, первый увиденный мною реально полезный проект на малинке. Вдобавок отлично проработанный и описанный вами. Спасибо!
Вопросы:
1. Возможно ли перенести этот проект на мою Orange Pi Pc (система Rapsberry Pi для этой платы имеется, а цена меньше вдвое).
2. Не думали ли добавить локальный полноценный DNS сервер с поддержкой DNSCrypt Proxy 2, к примеру.
Здравствуйте, AMG! Спасибо за отзыв )
1. С платформой Orange Pi Pc не доводилось иметь дело. В списке поддерживаемых ОС к ней есть много Debian-подобных, например поддерживается тот же Raspbian. Вполне может быть, что при переносе придется что-то достраивать и перенастраивать.
2. Мой пример реализации - это скорее основа (просто и минимально), а что уже дальше прикручивать к этой умной коробочке пусть каждый решает для себя сам. Можно поднять различные сервера, личное облако, крутить кучу самописных скриптов, LXC-контейнеры, Docker, SSH-DNS-SSL туннели, заворачивать траффик в TOR, I2P...
Спасибо огромное за статью! Перелопатил очень много информации о том, как поднять AP на Малинке, только у Вас нашёл решение. Очень много полезной информации о командах в Raspbian.
Информации о том как настроить точку доступа на Raspberry Pi в интернете действительно полно, но она везде разбросана по кусочкам. В этой статье я постарался собрать только самое полезное и необходимое.
Тем не менее, в зависимости от версии ОС, модели беспроводного сетевого адаптера и других особенностей, процесс настройки может потребовать дополнительных решений, здесь уже нужно действовать по ситуации.
Спасибо за отзыв
Добрый день!
А можно с помощью этого девайся, при первом подключении к малинке через интернет, показывать клиенту стартовую страничку на которой просьба ввести номер телефона для авторизации? Спрашиваю для кафе, по новому закону мое кафе при раздаче интернета должна запрашивать данные пользователя иначе штраф.
Здравствуйте. При реализации указанного вами может возникнуть ряд вопросов:
Думаю стоит обратиться к юристу и подробно разузнать все детали закона, порядок работы с персональными данными клиентов (номера телефонов и т.п.). Будьте готовы к тому что технических деталей в законе может и не быть - они пишутся разными людьми с различным уровнем компетенции, иногда "глубина" этого уровня может вызвать смех и печаль. )
По 1-му вопросу - привязка к системе какого-то сервиса приема СМС. После ввода номера телефона на него отсылается сообщение с контрольным кодом, клиент вводит этот код в системе и получает временный пароль для подключения к Wi-Fi.
По 2-му вопросу - сложнее, нужно как-то реализовать схему: один пароль = подключение с 1-го устройства. Но и здесь пароль кто-то может подсмотреть и потом использовать когда клиент уже уйдет. В зависимости от требований закона, возможно придется делать привязки к MAC-адресам устройств, вести лог подключений и их фильтрацию.
Насчет 3-го вопроса - хранить все номера телефонов, метки времени и т.п. в базе данных, периодически резервируя ее в зашифрованном виде.
Несколько идей по самой реализации: написать приложение для WEB-браузера на основе фреймворка Flask или Django, все данные хранить в SQLite, периодически резервируя в архив с надежным паролем и отправляя на какой-то личный сервер/почту.
К Raspberry Pi подключить небольшой дисплей с тач-скрином, перенастроить и изолировать оконный менеджер чтобы было доступно только приложение для авторизации и экранная клавиатура. Также можно обойтись и без WEB-панели с браузером - применить дисплей без тач-скрина, к малинке подключить обычную клавиатуру, а программу сделать консольной, изолировав доступ к командной оболочке - так будет даже безопаснее.
На такую разработку может уйти не мало времени, понадобится хороший программист и ресурсы на оплату его труда. Также попробуйте поискать уже готовые решения и как-то адаптировать их под себя.
Отличная статья!
Подскажите что нужно поменять в скрипте чтобы пройти из интернета в Хеома (порт 8090) для просмотра камер?
Xeoma (http://felenasoft.com/xeoma/ru) - это платный продукт с закрытым кодом, служит для организации видео-наблюдения. Данной программой не пользовался.
Для доступа из интернета понадобится "Белый" IP-адрес от вашего провайдера. Если ваш провайдер не использует NAT (трансляцию адресов, маскировку) то можно использовать и "Серый" (динамический) IP, в сочетании с одной из настроенных служб Dyn-DNS (периодическое получение текущего IP, с привязкой к бесплатному или купленному домену). Для этой цели можно воспользоваться старым проверенным сервисом freedns.afraid.org.
Если программа видео-наблюдения запущена на малинке, то порт 8090 уже активен, нужно лишь разрешить подключение к нему с наружного интерфейса (который смотрит в интернет) в брандмауэре IPTAbles. Для этого необходимо создать правило в цепочке "INPUT" для разрешения подключений через нужный интерфейс на порт 8090.
После правил:
добавляем аналогичные, разрешающие подключения с заданными параметрами (для двух интерфейсов, которые ведут в интернет):
Если у вас малинка подключена к каналу интернет-провайдера не напрямую, а через промежуточный маршрутизатор, то придется также настроить "проброс порта" на этом устройстве (смотрите разделы "NAT", "Ports forwarding", "Перенаправление портов" и т.п.) чтобы сетевой пакет с портом назначения 8090, пришедший через канала провайдера, попал на малинку.
Отличная статья...
Добавил в закладки ... буду чекать обновления и дополнения информации
Только вроде Ethernet мрдуль через USB интерфейс Малины не может дать больше 5 MB/s в связи с ограниченностью порта USB
Уже не раз качал торренты/ISO-образы с рабочей станции, которая подключена к малинке, а та в свою очередь подключена к интернет-провайдеру через USB-Ethernet.
Скорость закачки во многих случаях достигала и держалась стабильно: 10-12MB/s (80-96Mbit/s). Нагрузка на ядра CPU малинки составляла примерно 5-13%, причем в топе по потреблению этих ресурсов - скрипт rrouter.py. Использование ОЗУ - 65МБ.
Сперва сам был приятно удивлен, рассчитывал получить хотя-бы 40-50MBit.
USB-Ethernet адаптер - из не дорогих (~10$), на его корпусе указан только серийный номер, больше никаких опознавательных признаков нет, упаковку не сохранил. Команда 'lsusb' говорит что имеем дело с сетевым чипом от Realtek:
Пытаюсь третий день настроить это. При подключении инета напрямую от роутера к малине через эзернет инет есть. Сработало один раз на 15=минут до появлении странной аномалии при отключении инета во всей квартире. Некоторые устройства не подключены по вайфаю были и не должны быть связаны с малиной или компом. Восстановил инет в доме, но уже не работала малина тоесть инет есть на любом из инет (стандарт и адаптер) разъемов, но напрочь отсутствует при коммутации с компом. Что на компе, что на самой малине. Что я не так делаю? Раньше малина получала айпи инета 250... сейчас при подключении инета показывает 192.168.1.1 если без компа и 1.2 соответственно с компом. Инет не работает при подключении второго устройства в порт эзернет.
Ещё при ребуте писалось на винде про конфликт айпи адресов в сети но это не должно повлиять на доступ к инету на малине. Стоит поменять местами подключения конфликт уходит, eth0 становится 192.168.1.8 а инета по-прежнему нету на малине
Здравствуйте.
Дополнил информацией раздел "Структура сети и ее работа", нарисовал наглядную иллюстрацию (рисунок 2) с двумя вариантами подключения малинового роутера к интернету.
Изучите эту информацию и приступайте к перенастройке.
У вас на домашнем роутере уже используется IP-адрес 192.168.1.1, также на нем работает служба раздачи динамический адресов (DHCP) для подсети 192.168.1.x, а еще там возможно есть Wi-FI со своей подсетью, которая отличается от 192.168.1.x, например - 192.168.2.x .
При подключении малинки к этому роутеру с настройками, что указаны в статье, возникают конфликты адресов в сети.
Для интерфейсов eth0 и wlan0 вам нужно выбрать и прописать другие номера подсетей (чтобы они не конфликтовали с подсетями 192.168.1.x, 2.x) и заменить эти адреса во всех конфигурационных файлах и скриптах для служб, где эти адреса были задействованы.
Например заменить адресацию так, как показано на рисунке 2:
После этого цепочка "INTERNET --- HOME ROUTER --- RASPBERRY PI ROUTER" должна заработать исправно.
Потрясающий проект и статья. Скажите, а как можно настроить open vpn клиент.
Здравствуйте. Установка самого OpenVPN клиента не сложна - установить программу, импортировать конфигурационный файл с ключами шифрования и настроить в системе автозапуск.
Более сложно в этом проекте будет продумать структуру правил файрвола iptables: разрешить с внешних интрефейсов подключение только к VPN-серверу, сделать чтобы весь интернет-трафик с внутренних подсетей (LAN, WLAN) и с самой малинки шел через VPN-туннель и никак иначе (это так называемый Kill-Switch), позаботиться о безопасности.
Возможно со временем напишу об этом отдельную статью.
Здравствуйте. Скажу сразу мой вопрос уже реализован на другом железе, но ввиду необходимости теперь нужна реализация на малине.
Общая часть:
wlan0: Подключён к одной сети через маршрутизатор с провайдером предоставляющим интернет и раздаваемый в этой сети.
eth0: Подключён к другой сети имеющей другой сервер с провайдером предоставляющим интернет и раздаваемый в этой сети.
На eth0 поднят pptpd входящие соединения из текущей сети в малину.
Вопрос не могу понять где не так сделал, клиенты подсети после подключения к малине по VPN должны, но не получают интернет (на самом деле доступ к определённым частям сети) . Если подключить из напрямую в сеть то всё работает.
Так понимаю малина должна передать параметры которые получает сама от провайдера wlan0 соединения.
Ранее всё реализовано на плате Intel Atom и ос debian 8 правила iptables и копировал и за нова прописывал, так что считаю проблема где-то на уровне конфигурации интерфейсов.
Поделитесь своими идеями о реализации VPN туннеля.
Здравствуйте, Евген. Попробую что-то подсказать по вашей схеме.
Я имел небольшой опыт работы с туннелями при связывании удаленных офисов посредством PPTP, OpenVPN, там все делалось очень просто и буквально по мануалам, которые можно найти в свободном доступе.
Вы упомянули что сервер с работающей конфигурацией на Атоме у вас под Debian 8. Вот некоторые замечания, которые возможно будут полезны:
Потому, желательно:
Некоторые команды для сбора информации и диагностики (думаю вы их и так знаете):
Также, в качестве эксперимента, можно порекомендовать записать на Micro-SD карту Raspbian более старой версии, соответствующей Debian 8 (как в вашей рабочей конфигурации на Intel Atom), это будет Raspbian Jessie.
Потом перенести туда все настройки с рабочего сервера и проверить на работоспособность. Если на Raspbian Jessie все заработает, то скорее всего в Raspbian Stretch и выше проблема кроется где-то в измененных новых настройках или сетевых службах, что пришли с новой версией ОС.
Я бы первым делом попробовал это реализовать на основе OpenVPN, поскольку это очень гибкий инструмент с широким набором возможностей, не сложным конфигурационным файлом с множеством настроек. Из коробки имеем поддержку надежного шифрования трафика с использованием современных протоколов, управление интерфейсами, параметрами сетевых пакетов, маршрутами на стороне сервера и клиента и много всего другого. И это свободный продукт, Open Source!
Спасибо, буду пробовать.
Добавлен раздел "Устранение неполадок". Описал в нем решение некоторых проблем, привел команды для диагностики системы и ее служб.
Отличная статья!!
Воспользовался, спасибо большое.
Но интернет не раздавался ни на eth0, ни на wlan0.
Причину нашел в файерволе, его еще нужно настроить.
А после все заработало!!
Еще раз спасибо!!!
Все очень доступно и подробно!
Пожалуйста! Приятно знать что пригодилось и во всем разобрались.
Проверена работа всех программ на новой Raspberry Pi OS (Debian 10 Buster) - все отлично!
Загружена новая версия скрипта 'rrouter':
У меня Orange Pi 2E+ на Armbian уже около пяти лет работает как маршрутизатор со всеми сетевыми плюшками, файло - торенто - качалкой и медиа сервером, MQTT сервер, хаб для умного дома и многое другое. В принципе на нём или ему подобном можно реализовать все свои серверные фантазии. Минус - стабильность, раз в месяц подвисает, нужно вручную перегружать, ну и шифрование сильно может загружать процессор. А в нормальном, обычном режиме загрузка не более десяти процентов. Цена, возможности и низкое энергопотребление прилично выделяют его на фоне прогрессивного бытового сетевого оборудования.
Статья супер. 3G также работает и раздается, но перед подключением нужно снять PIN-код с СИМ- карты, иначе не пропускает.
Вопрос, как можно реализовать NAS, пытаюсь подключить samba - ничего не получается?
Спасибо
С настройкой SAMBA думаю вы разберетесь - есть официальная документация, описания в многих книгах и статьях на любой вкус. Простой конфигурационный файл с множеством настроек, для каждой общей папки (шары) можно задать свои уникальные опции, права доступа и т.п.
Рекомендую взять отдельную micro-SD карту памяти, записать на нее чистую Raspberry Pi OS и там уже установить SAMBA, поэкспериментировать с настройками, создать нужную конфигурацию расшаренных папок.
После этого на сборке системы по моей статье достаточно будет установить пакет SAMBA и перенести туда уже отлаженный конфигурационный файл smb.conf.
В изложенной в статье конфигурации SAMBA не заработает по причине блокировки подключений к ее портам нашими правилами файрвола. Для разрешения подключений к системе по протоколам SMB/CIFS нужно открыть следующие порты: 137, 138, 139, 445.
В операционной системе GNU/Linux в папке "/etc" есть файл "services", в котором перечислено огромное количество портов и связанных с ними служб.
Чтобы посмотреть описания и протоколы по указанным выше портам достаточно выполнить следующую команду в консоли (вывод содержимого файла с фильтрацией регулярным выражением):
Пример вывода:
CIFS (Common Internet File System) - протокол для обмена файлами между серверами Windows и совместимыми NAS устройствами.
Получается что в файрвол нужно добавить 8 правил - по 2шт. для каждого из портов для протоколов TCP и UDP. Но у нас два интерфейса локальной сети для подключения устройств (ETH - проводное, WLAN - беспроводное) и поэтому весь этот набор правил должен быть применен к сетевым пакетам на каждом из этих интерфейсов.
В результате нужно 16 правил (2 интерфейса Х 2 протокола Х 4 порта)! Но, использовав в IPTables опцию "-m multiport" вместе с "--dports" теперь можно будет указывать не один порт, а перечислить до 15 портов на одно правило.
После разрешающего правила для подключений по SSH (22-й порт):
нужно добавить следующие для SMB/CIFS:
Таким образом, все сетевые пакеты, приходящие через локальные Wi-Fi ($WLAN) и проводное ($ETH) подключения на указанные нами порты будут пропущены, соединение будет установлено. Входящие пакеты на другие порты, ассоциируемые с этими соединениями будут пропущены уже выше стоящим в цепочке правилом:
Попытки подключения к этим портам через внешние интерфейсы с интернетом $PPP и $ETH_EXT будут безуспешными, пакеты будут отброшены. Cервер SMB будет недоступен из интернета (если у вас серый или белый IP на малинке) и для вашего интернет-провадера (если интернет через NAT), только локальный доступ.
Если SAMBA будет сконфигурирована в качестве контроллера домена то на малинке должен работать еще и DNS-сервер, придется его сконфигурировать и добавить еще разрешающие правила для приема подключений по порту 53 с протоколом UDP.
Так кроме Github есть как минимум GitLab и Bitbucket.
Владимир, вы правы. Я знаю об этих проектах, хорошо что есть альтернативы. К тому же, репозиторий с кодом можно настроить на собственном сервере. Позже возможно рассмотрю эти варианты и что-то выберу среди них.
Добрый день!
Статья супер. Все понятно изложено.
Не получается получить интернет с модема E3372h.
После команды sudo wvdial IP получает, DNS тоже выдается.
Но интернета нет. Не нужно ли прописать ppp в /etc/network/interfaces?
Здравствуйте. После запуска wvdial интернет на малинке должен появиться, в /etc/network/interfaces при этом ничего прописывать не нужно.
Несколько рекомендаций:
Если ваш провайдер интернета требует указания APN, то можно использовать пример следующего конфигурационного файла wvdial:
Обратите внимание на номер USB-порта, который указан, в вашем случае он может быть 0, 1, 2... Также важно задать правильный номер дозвона, ну и логин с паролем, если такие требуются.
Процесс настройки каждого отдельно взятого модема может отличаться, поэтому нужно искать информацию по модели, читать форумы (на RU и EN), изучать логи работы, экспериментировать.
Спасибо за ответ! Подключал модем к компу на 7 и 10 windows - работает. Строчка "AT^PREFMODE=8" была убрана ранее , модем при конфигурировании ругался ошибкой на нее. С IPtables что только не делал. Уровень приема приемлемый, проверял при подключении к ПК. Питание у меня через hub с 4 портами и 2.5 ампер БП.
Так и не смог заставить его раздать Интернет в режиме модема ppp со Stick прошивкой .
Перешил его обратно из Stick в Hi-Link. Увиделся он как eth2. Пришлось переделать в Iptables интерфейс вместо ppp0 eth2. И все заработало. Программа wvdial не нужна. Переключать Интернет с ETH1 на ETH2 и обратно получается только после перезагрузки. На горячую не работает. А так все супер. Огромное спасибо за ваш труд.