
Полнофункциональный WiFi NAT-роутер (а теперь также и WiFi-репитер)
Полнофункциональный WiFi NAT-маршрутизатор (а теперь также WiFi-ретранслятор, он же L2-мост)
НОВИНКА 2026: Спустя 10 лет после первого релиза он наконец стал тем, чем всегда притворялся: настоящим WiFi-ретранслятором. Чтобы не ломать существующую документацию и ссылки, стандартная редакция по-прежнему остаётся известной версией NAT-маршрутизатора со всеми расширенными функциями. Но если вас интересует урезанный настоящий L2-мост, смотрите ниже раздел ESP8266 WiFi Repeater - L2 bridge.
Это реализация WiFi NAT-маршрутизатора на esp8266 и esp8285. Она также включает поддержку межсетевого экрана с фильтрацией пакетов и ACL, проброс портов, формирование трафика, хуки для удалённого мониторинга (или перехвата пакетов), интерфейс управления MQTT, простое взаимодействие с GPIO и управление питанием. Для настройки с несколькими маршрутизаторами в mesh-сети для покрытия большей площади добавлен новый режим «Automesh».
Если вы ищете способ интегрировать функцию NAT в свой проект Arduino — смотрите здесь .
EPS32 NAT Router — это продвинутый проект для ESP32.
Типичные сценарии использования включают:
По умолчанию ESP работает как STA и как soft-AP и прозрачно передаёт любой IP-трафик через себя. Поскольку используется NAT, записи маршрутизации не требуются ни на стороне сети, ни на подключённых станциях. По умолчанию станции настраиваются через DHCP в сети 192.168.4.0/24 и получают адрес DNS-резолвера из существующей WiFi-сети.
Измерения показывают, что он может достигать примерно 5 Мбит/с в обоих направлениях, так что возможна даже потоковая передача.
Некоторые детали объяснены в этом видео.
Для прямой прошивки устройства используйте Web-Installer.
esp_wifi_repeater запускается со следующей конфигурацией по умолчанию:
После первой загрузки (или сброса к заводским настройкам) он будет предлагать WiFi-сеть с открытой точкой доступа и SSID «MyAP». При этом он ещё не пытается автоматически переподключаться к вышестоящей точке доступа (поскольку не знает корректный SSID или пароль).
Подключитесь к этой WiFi-сети и выполните базовую настройку либо через простой веб-интерфейс, либо через консоль — полную настройку со всеми параметрами.
Веб-интерфейс позволяет настраивать все параметры, необходимые для базовой функции пересылки. Спасибо rubfi за основную работу над этим: https://github.com/rubfi/esp_wifi_repeater/ . Укажите в браузере адрес «http://192.168.4.1». Должна появиться эта страница:
Сначала введите подходящие значения для вышестоящей WiFi-сети — «STA Settings». Для открытых сетей используйте пароль «none». Установите флажок «Automesh» только в том случае, если вы действительно хотите использовать режим automesh. Нажмите «Connect». ESP перезагрузится и подключится к вашему WiFi-маршрутизатору. Через несколько секунд светодиод состояния должен начать мигать.
Если вы выбрали automesh, настройка завершена. Настраивать «Soft AP Settings» не требуется, поскольку в режиме automesh эти параметры идентичны «STA Settings». Тот же SSID будет предлагаться всеми подключёнными ESP-ретрансляторами.
Если вы не используете automesh, теперь можно перезагрузить страницу и изменить «Soft AP Settings». Нажмите «Set» — ESP снова перезагрузится. Теперь он готов пересылать трафик через только что настроенный Soft AP. Имейте в виду, что эти изменения также влияют на интерфейс настройки: для дальнейшей настройки подключайтесь к ESP через одну из новонастроенных WiFi-сетей. Для доступа через Soft AP запомните адрес сети Soft AP, если вы его изменили (в этой сети ESP всегда имеет адрес x.x.x.1).
Если хотите, можете отметить флажок «lock» и нажать «Lock». Теперь конфигурацию нельзя изменить, пока вы не разблокируете её паролем вышестоящей WiFi-сети (задайте его, даже если сеть открыта).
Если вы хотите ввести не-ASCII или специальные символы в веб-интерфейсе, вам нужно использовать HTTP-подобное шестнадцатеричное кодирование, например «My%20AccessPoint». В результате получится строка «My AccessPoint». С помощью этого шестнадцатеричного кодирования можно ввести любое байтовое значение, кроме 0 (по внутренним причинам C).
Если вы ошиблись и потеряли всякую связь с ESP, вы всё ещё можете использовать последовательную консоль для восстановления («reset factory», см. ниже).
Расширенная настройка выполняется через командную строку в консольном интерфейсе. Эта консоль доступна либо через последовательный порт со скоростью 115200 бод, либо через TCP-порт 7777 (например, «telnet 192.168.4.1 7777» с подключённой STA).
Используйте следующие команды для первоначальной настройки:
Опять же, если вы хотите ввести не-ASCII или специальные символы, вы можете использовать HTTP-подобное шестнадцатеричное кодирование (например, «My%20AccessPoint») или, только в CLI, в качестве сокращения — C-подобные кавычки с обратной косой чертой (например, «My\ AccessPoint»). Оба метода дадут строку «My AccessPoint».
Командная строка понимает гораздо больше команд:
Достаточно, чтобы заработать почти в любом окружении.
Большинство set-команд вступают в силу только после save и reset.
Любая часть ввода командной строки после одиночного символа «#» до конца строки будет рассматриваться как комментарий и игнорироваться.
В конфигурации по умолчанию GPIO2 настроен на управление светодиодом состояния (подключённым к GND) со следующими индикациями:
С помощью «set status_led GPIOno» вывод GPIO можно изменить (любое значение > 16, например, «set status_led 255» полностью отключит светодиод состояния). При настройке на GPIO1 он работает со встроенным синим светодиодом на платах ESP-01. Однако, поскольку GPIO1 также является выводом UART-TX, это означает, что последовательная консоль не работает. Тогда настройка ограничивается сетевым доступом.
Если прижать выбранный GPIO к низкому уровню более чем на 3 секунды, ретранслятор выполнит сброс к заводским настройкам и перезапустится с конфигурацией по умолчанию. С помощью «set hw_reset GPIOno» вывод GPIO можно изменить (любое значение > 16, например, «set hw_reset 255» отключит функцию аппаратного сброса).
Для многих модулей, включая ESP-01s и NodeMCU, вероятно, хорошей идеей будет использовать для этого GPIO 0, так как он всё равно используется. Однако это не вывод по умолчанию, поскольку он может помешать при подтягивании к земле во время прошивки. Поэтому, если вы хотите использовать существующую кнопку на GPIO 0 для аппаратного сброса, настройте её с помощью «set hw_reset 0» и «save» после прошивки. Сброс, вызванный аппаратным выводом, НЕ сбросит настроенный номер GPIO для hw_reset (это сделает «reset factory» из консоли).
Чтобы разрешить клиентам из внешней сети подключаться к серверному порту во внутренней сети, порты должны быть сопоставлены. Внешний порт сопоставляется с внутренним портом конкретного внутреннего IP-адреса. Используйте для этого команду «portmap add». Сопоставления портов можно вывести командой «show», и они сохраняются вместе с текущей конфигурацией.
Однако, чтобы гарантировать, что нужное устройство прослушивает определённый IP-адрес, необходимо убедиться, что это устройство имеет тот же IP-адрес после перезагрузки его самого или ESP. Для этого можно либо настроить фиксированные IP-адреса на устройствах, либо ESP должен запоминать свои DHCP-аренды. Это достигается командой «save dhcp». Она сохраняет текущее состояние и все DHCP-аренды, чтобы они были восстановлены после перезагрузки. Список DHCP-аренд можно вывести командой «show stats».
Поддержка WPA2 Enterprise (PEAP) теперь включена в проект. Она позволяет создать «конвертер», который преобразует корпоративную сеть WPA2 с аутентификацией PEAP в сеть WPA2-PSK. Это решает распространённую проблему, особенно в университетской среде: локальная WiFi-сеть является корпоративной сетью WPA2 с аутентификацией PEAP-MSCHAPv2. Очень яркий пример — сеть «eduroam», доступная во многих университетах по всему миру. Проблема в том, что многие устройства IoT не могут работать с аутентификацией WPA2 Enterprise. Поэтому разработка и демонстрации затруднены. Очень полезен «конвертер», который входит в сеть WPA2 Enterprise и предлагает своим клиентам более простую сеть WPA-PSK.
Для его использования задайте следующие параметры конфигурации: ssid, use_peap, peap_identity, peap_username и peap_password (обычный параметр password не нужен). Эта настройка должна выполняться (и сохраняться) через CLI и недоступна в веб-интерфейсе.
Код в настоящее время не проверяет сертификат RADIUS-сервера. Он уязвим для MITM-атак, когда кто-то разворачивает мошенническую точку доступа и RADIUS-сервер. Хотя пароль не передаётся в открытом виде, используемый MSCHAPv2, как известно, взломан. Также имейте в виду, что ESP8266 теперь содержит пароль вашей корпоративной сети. Весь трафик, который он пересылает, теперь может быть соотнесён сетевым администратором с вашей учётной записью. Не злоупотребляйте этим и не предоставляйте его недоверенным лицам, например, настраивая открытую сеть. И даже когда устройство заблокировано, пароль вашей корпоративной сети может быть извлечён через последовательный порт из flash ESP в открытом виде.
Иногда вам может потребоваться использовать несколько esp_wifi_repeaters подряд или в mesh-сети, чтобы покрыть большее расстояние или площадь. В целом это можно сделать без каких-либо проблем с NAT-маршрутизаторами; фактически у вас будет несколько уровней NAT. Однако это означает, что связность ограничена: все узлы могут выходить в интернет, но обычно между узлами нет прямой IP-связности. И, конечно, доступная пропускная способность снижается с каждым дополнительным хопом. Но пользователи сообщают, что даже 5 esp_wifi_repeaters подряд работают вполне хорошо.
В такой конфигурации настройка является довольно трудоёмким и чреватым ошибками занятием. Чтобы упростить это, esp_wifi_repeater теперь имеет новый режим: «Automesh». Просто настройте SSID и пароль и включите «automesh» (либо в CLI командой «set automesh 1», либо в веб-интерфейсе, просто установив флажок). Это приведёт к следующему:Каждый esp_wifi_repeater, настроенный таким образом, будет автоматически предоставлять сеть WiFi на AP с тем же SSID/паролем, к которому он подключён. Клиенты могут использовать те же настройки WiFi для исходной сети или для повторённых. Каждый esp_wifi_repeater, настроенный с "automesh", сначала ищет лучшую другую AP для подключения. Это та, которая находится ближе всего к исходной сети WiFi и имеет наилучшую мощность сигнала (RSSI).
Мощность сигнала легко измерить с помощью сканирования, но как определить, какая из нескольких AP с одинаковым SSID находится ближе всего к исходной сети WiFi? Поэтому протокол использует несколько грязный трюк: esp_wifi_repeater'ы в режиме "automesh" манипулируют своим BSSID (на самом деле, согласно стандарту IEEE 802.11, это "ESSID", так как это AP, но SDK называет его "BSSID"), т.е. MAC-адресом своего AP-интерфейса, который отправляется в каждом beacon-кадре примерно 10 раз в секунду. Используется формат: 24:24:mm:rr:rr:rr. "24:24" — это просто уникальный идентификатор повторителя (существует минимальная вероятность коллизии с MAC реальных AP, но этим можно пренебречь, так как при необходимости этот префикс можно изменить). "mm" означает "уровень mesh" — это расстояние в переходах до исходной сети WiFi. Последние три "rr:rr:rr" — просто случайные числа для различения различных ESP. Исходная AP сохраняет свой BSSID, т.е. та, что без префикса "24:24", распознаётся как корневая и называется уровнем mesh 0.
Теперь каждый esp_wifi_repeater может узнать, какой другой esp_wifi_repeater находится ближе всего к исходной сети WiFi, подключиться к нему и соответствующим образом выбрать свой BSSID. Также IP-адрес внутренней сети корректируется в соответствии с уровнем mesh: 10.24.m.0. Это создаёт дерево (весьма особый mesh) с исходной WiFi AP в качестве корня и повторяющими узлами на нескольких уровнях mesh (на самом деле это работает примерно так же, как Spanning Tree Protocol (STP) на канальном уровне или маршрутизация на сетевом уровне с использованием протокола вектора расстояния). Как только обнаруживается потеря uplink-соединения, конфигурация перезапускается. Это должно предотвращать петли, так как во время (пере)конфигурации также не отправляются beacon-кадры с BSSID.
Для удобства esp_wifi_repeater после настройки "automesh" сначала пытается проверить, может ли он подключиться к uplink AP. Если это не удаётся, даже когда AP с правильным SSID найдена, он предполагает, что пользователь ошибся с паролем, и сбрасывается к заводским настройкам. После того как он однажды успешно подключился, он предполагает, что конфигурация верна, и продолжает попытки после потери соединения или сброса столько, сколько потребуется (чтобы избежать DoS-атаки с неправильно настроенной AP).
Если в зоне действия находится более одного ESP, может возникнуть компромисс между более коротким "плохим" путём и более длинным "хорошим" путём (хорошим и плохим с точки зрения качества канала). Параметр am_threshold определяет, что считается плохим соединением: если RSSI при сканировании меньше этого порога, соединение плохое, и предпочтителен путь с ещё одним переходом. Т.е. при am_threshold, равном 85, и при обнаружении в сканировании двух automesh-узлов: A с уровнем 1 и RSSI -88 dB и B с уровнем 2 и RSSI -60 dB, соединение с A считается слишком плохим (-88 dB < -am_threshold), и предпочитается B. Новый узел станет узлом уровня 3 с uplink через B. am_threshold задаётся как положительное значение, но означает отрицательный dB. Чем меньше значение, тем лучше.
Если вы хотите получить больше информации о топологии automesh-сети, вы можете подключить все узлы к MQTT-брокеру и позволить им публиковать тему "Topology" (см. ниже). Если затем подписаться на "/WiFi/+/system/Topology", вы получите всю информацию об узлах и связях, включая RSSI (подключённых ESP), необходимую для восстановления полного графа и обнаружения слабых связей в mesh. Тема TopologyInfo содержит следующую JSON-структуру, которую можно использовать для восстановления полного графа automesh-сети:``` { "nodeinfo" { "id":"ESP_07e37e", "ap_mac":"24:24:01:72:c7:f9", "sta_mac":"60:01:bc:07:e3:7e", "uplink_bssid":"00:1a:54:93:23:0a", "ap_ip":"10.24.1.1", "sta_ip":"192.168.178.33", "rssi":"-66", "mesh_level":"1", "no_stas":"2" }, "stas":[ {"mac":"5c:cf:45:11:7f:13","ip":"10.24.1.2"}, {"mac":"00:14:22:76:99:c5","ip":"10.24.1.3"} ] }
Используя два параметра _am_scan_time_ и _am_sleep_time_, можно реализовать управление питанием в режиме automesh, если вы подключили GPIO16 к RST. После загрузки esp_wifi_repeater сканирует доступные вышестоящие точки доступа (AP) в течение _am_scan_time_ секунд. Если ни одна не найдена, он переходит в глубокий сон на _am_sleep_time_ секунд и после перезагрузки пробует снова (по умолчанию 0 = отключено для обоих параметров).
# Мониторинг
Из консоли можно запустить службу мониторинга ("monitor on [portno]"). Эта служба зеркалирует трафик внутренней сети в формате pcap в TCP-поток. Например, с помощью "netcat [external_ip_of_the_repeater] [portno] | sudo wireshark -k -S -i -" с компьютера во внешней сети вы можете наблюдать трафик внутренней сети в реальном времени. Используйте это, например, для наблюдения за тем, с какими интернет-сайтами общаются ваши внутренние клиенты. Учтите, что это как минимум удваивает нагрузку на ESP и Wi-Fi сеть. При высокой нагрузке это может привести к тому, что некоторые пакеты будут обрезаны или даже отброшены в сеансе мониторинга. ВНИМАНИЕ: оставление этого порта открытым потенциально создаёт угрозу безопасности. Любой из локальных сетей может подключиться и наблюдать за вашим трафиком.
# Брандмауэр
Маршрутизатор ESP имеет встроенный базовый брандмауэр. ACL (списки управления доступом) могут применяться к интерфейсу SoftAP. Это краеугольный камень безопасности Интернета вещей (IoT), когда маршрутизатор используется для подключения других IoT-устройств к интернету. Его можно использовать, чтобы предотвратить, например, "звонки домой" сторонних IoT-устройств, их использование в качестве ботов вредоносных программ, а также защитить вашу домашнюю сеть с ПК, планшетами и телефонами от видимости устройствам домашней автоматизации.
Четыре списка ACL называются "from_sta", "to_sta", "from_ap" и "to_ap" для входящих и исходящих пакетов на обоих интерфейсах ("sta" означает интерфейсы к подключённым клиентам, "ap" — интерфейс к вышестоящей точке доступа). ACL определяются в стиле "CISCO IOS".
Следующий пример полезен для гостевой подсети. Он разрешает доступ к интернету, но не к любым другим локальным адресам (используйте свой диапазон локальной сети для адреса xx.xx.xx.xx). Этот набор правил разрешает исходящие локальные широковещательные пакеты (для DHCP) и UDP 53 (DNS), любые другие пакеты в подсеть вышестоящего маршрутизатора будут блокироваться, все остальные пакеты могут проходить в интернет:```
acl from_sta clear
acl from_sta IP any 255.255.255.255 allow
acl from_sta UDP any any any 53 allow
acl from_sta IP any xx.xx.xx.xx/24 deny
acl from_sta IP any any allow
Следующий пример является более строгим и полезен, когда вы планируете подсеть IoT с очень ограниченным доступом на точке доступа ESP. Он также разрешит исходящие локальные широковещательные пакеты (для DHCP), UDP 53 (DNS) и TCP 1883 (MQTT) к локальному брокеру, но все остальные пакеты будут заблокированы, включая произвольный доступ в интернет (вы можете адаптировать четвёртое правило в соответствии со своими потребностями, чтобы разрешить доступ к другим узлам):``` acl from_sta clear acl from_sta IP any 255.255.255.255 allow acl from_sta UDP any any any 53 allow acl from_sta TCP any any 192.168.0.0/16 1883 allow acl from_sta IP any any deny
ACLs for the "to_sta" direction may be defined as well, but this is usually not required, as the reverse direction is quite well protected against unsolicited traffic by the NAT transation.
ACLs consist of filtering rules that are processed for each packet. Each rule consists of a protocol (IP, TCP, or UDP), source address/port, destination address/port, as well as an action "allow" or "deny". In case of plain IP no ports, only addresses are given. IP rules include TCP and UDP packets. Addresses can be given as subnet addresses in the "/" notation, e.g. 192.168.178.0/24. Also "any" can be used as wildcard, it matches on any address or portnumber. A rule is defined by the "acl" command:
- acl [from_sta|to_sta|from_ap|to_ap] [TCP|UDP|IP] _src-ip_ [_src_port_] _desr-ip_ [_dest_port_] [allow|deny|allow_monitor|deny_monitor]
The rules are processed top-down in the order of their appearance in the list. The first rule that matches a packet is applied and determies whether a packet is allowed (and forwarded) or denied (and dropped). This means, special cases first, general rules at the end. If there are rules in an ACL all packets that don't match any rule are denied by default. Thus, the last rule "from_sta IP any any deny" in the example above is not really needed, as it is the default anyway. If an ACL is empty, all packets are allowed.
Definition of ACL rules works also top-down: a new rule is always added at the end of a list. To change an ACL you first have to clear it completely (acl from_sta clear) and then rebuild it. ACLs are saved with the config. "show acl" will print out the ACLs plus statistics on the number of hits for each rule and the overall number of allowed and denied packets.
With the command "set acl_debug 1" a summary of all denied packets is printed to the console. Also, an MQTT topic can publishe this summary. This can be used for firewall configuration to determine which rules are required to get the connected devices working. It also gives a hint if, if unexpected traffic happens (and is denied).
For deeper analysis the monitoring service can be used (even denied packets are reported to the monitor before they are dropped). When the monitor is started with the "monitor acl _port_" command, ACLs can be used as online filters. All rules that are defined as
"allow_monitor" instead of "allow" and "deny_monitor" instead of "deny" are processed as usual, resulting in allowing of forwarding a packet, but they also send the packet to the monitor. Thus a list of rules that basically "allow" or "allow_monitor" all packets still makes sense, as it can be used to select already during catpure time which packet should be recorded. E.g. a lists:```
acl from_sta clear
acl from_sta IP 192.168.0.0/16 any allow_monitor
acl from_sta IP any any allow
acl to_sta clear
acl to_sta IP any 192.168.0.0/16 allow_monitor
cl to_sta IP any any allow
разрешит все пакеты, а также выберет для мониторинга все пакеты, идущие от станции в подсеть 192.168.0.0/16 (локальную) и из 192.168.0.0/16 к станции. Конечно, такой фильтр можно применить и после захвата к полной трассе мониторинга, но если вы уже знаете, что ищете, эти онлайн-фильтры помогут значительно снизить накладные расходы на мониторинг. Его также можно использовать для отладки всех deny-правил брандмауэра, просто используя "deny_monitor" вместо deny.
По умолчанию интерфейс AP работает через NAT, поэтому любой узел, подключенный к AP, сможет прозрачно выходить во внешний мир через интерфейс STA модуля ESP. Так что никаких дополнительных действий не требуется, если вы не настоящий сетевой гик.
Для тех, кому действительно интересна дальнейшая сетевая настройка: стек lwip IPv4 ESP расширен для этого проекта поддержкой статических маршрутов: "show route" отображает таблицу маршрутизации со всеми известными маршрутами, включая связи с подключенными сетевыми интерфейсами (интерфейсами AP и STA). Маршрутизация между этими двумя интерфейсами работает без дополнительной настройки. Дополнительные маршруты к другим сетям можно задать командой "route add network gateway", известной по Linux-системам или маршрутизаторам. Команда "save" записывает текущее состояние таблицы маршрутизации во flash-конфигурацию.
Вот простой пример того, что можно сделать с помощью статических маршрутов. Дана следующая сетевая конфигурация с двумя ESP, подключенными через интерфейсы STA к центральному домашнему маршрутизатору:``` | 10.0.1.1 AP-ESP1-STA 192.168.1.10 | <-> |Home Router| <-> | 192.168.1.20 STA-ESP2-AP 10.0.2.1|
Каждый ESP имеет вторую сеть за своей точкой доступа с разными сетевыми адресами: 10.0.1.0/24 и 10.0.2.0/24. ESP1 может пинговать ESP2 по адресу 192.168.1.20, но не 10.0.2.1, так как не знает, что может достичь его через 192.168.1.20. Это изменится, если добавить два статических маршрута. На ESP1:```
route add 10.0.2.0/24 192.168.1.20
и на ESP2:``` route add 10.0.1.0/24 192.168.1.10
Теперь «ping 10.0.2.1» на ESP1 будет успешным. Он отправляется на 192.168.1.20, а затем на него отвечает ESP2.
Теперь в каждой сети подключается дополнительный клиент (с адресами 10.0.1.2 и 10.0.2.2):```
| STA1 10.0.1.2 | <-> | 10.0.1.1 ESP1 192.168.1.10 | <-> |Home Router| <-> | 192.168.1.20 ESP2 10.0.2.1| <-> | STA2 10.0.2.2 |
Теперь даже клиент STA1 с локальным адресом 10.0.1.2 может пинговать STA2 с адресом 10.0.2.2, поскольку он сначала отправляет свой запрос своему маршрутизатору по умолчанию ESP1, а тот знает, что все пакеты на адрес 10.0.2.0/24 должны пересылаться на 192.168.1.20. Там ESP2 знает, как доставить их до STA2. То же самое применимо и к ответу в обратном направлении.
Это позволяет настроить звездообразную топологию с несколькими центрами из ESP, в которой каждый ESP и его STA-клиенты могут напрямую связываться друг с другом (без необходимости в пробросе портов). Настройка требуемых маршрутов может быть несколько утомительной, но это хорошее упражнение по сетевым технологиям. Следующим шагом мог бы стать перенос динамического протокола маршрутизации, например RIP, на ESP...
Установив параметры upstream_kbps и downstream_kbps в значение, отличное от 0 (по умолчанию используется 0), вы можете ограничить максимальный битрейт точки доступа ESP. Это значение является лимитом, который применяется к трафику всех подключённых клиентов. Пакеты, превышающие заданный битрейт, отбрасываются. Формирователь трафика использует алгоритм «Token Bucket» с размером ведра, равным в настоящее время четырёхкратному битрейту в секунду, что позволяет допускать всплески, если до этого трафика не было.
Начиная с версии 1.3 в маршрутизаторе есть встроенный MQTT-клиент (благодаря Tuan PM за его библиотеку https://github.com/tuanpmt/esp_mqtt). Это помогает интегрировать маршрутизатор/репитер в Интернет вещей (IoT). Система домашней автоматизации может, например, принимать решения на основе информации о текущих подключённых станциях, включать и выключать репитеры (например, по расписанию) или просто использоваться для контроля нагрузки. Маршрутизатор может подключаться как к локальному MQTT-брокеру, так и к публично доступному брокеру в облаке. Однако в настоящее время TLS-шифрование не поддерживается.
По умолчанию MQTT-клиент отключён. Его можно включить, задав конфигурационному параметру «mqtt_host» имя хоста, отличное от «none». Для настройки MQTT можно задать следующие параметры:
Параметры MQTT можно просмотреть с помощью команды «show mqtt».
Маршрутизатор может периодически публиковать следующие темы состояния (каждые mqtt_interval):
Кроме того, репитер может публиковать сообщения на основе событий:
В качестве LWT и отчёта о состоянии репитер публикует:
Маршрутизатор можно настраивать с помощью следующих тем:
Если вы хотите, чтобы маршрутизатор публиковал, например, только Vdd, свой IP-адрес и вывод командной строки, установите mqtt_mask в 0x0001 | 0x0002 | 0x0040 (= «set mqtt_mask 0043»).
Теперь esp_wifi_repeater поддерживает сетевой контроллер ENC28J60, подключаемый через SPI (благодаря Эндрю Кроллу https://github.com/xxxajk за его отличную работу по доведению этого до ума), если включить параметр компиляции HAVE_ENC28J60 в «user_config.h». Ethernet-интерфейс будет поддерживать пропускную способность около 1 Мбит/с при работе ESP на частоте 160 МГц. Если включить интерфейс AP и использовать Ethernet в качестве восходящего канала, esp_wifi_repeater превратится в недорогую точку доступа для WiFi-устройств (например, других ESP).
Подключение через SPI должно быть следующим:``` NodeMCU/Wemos ESP8266 ENC28J60
D6 GPIO12 <---> MISO
D7 GPIO13 <---> MOSI
D5 GPIO14 <---> SCLK
D8 GPIO15 <---> CS
D1 GPIO5 <---> INT
D2 GPIO4 <---> RESET
Q3/V33 <---> 3.3V
GND <---> GND
Короткие и пропаянные провода работают лучше всего. Кроме того, вам понадобится транзистор для развязки GPIO15, иначе ваш ESP больше не загрузится, см.: https://esp8266hints.wordpress.com/category/ethernet/ . Также важно иметь хороший источник питания: ENC28j60 потребляет около 160 мА в активном режиме. У меня это не работает, если я пытаюсь использовать 3.3V с платы ESP.
Теперь вы можете настроить новый интерфейс Ethernet:
- set eth_enable [0|1]: включает/отключает сетевой адаптер ENC28J60 Ethernet на шине SPI (по умолчанию: 0 - выключено)
- set eth_ip _ip-addr_: задаёт статический IP-адрес для интерфейса ETH
- set eth_netmask _netmask_: задаёт статическую маску подсети для интерфейса ETH
- set eth_gw _gw-addr_: задаёт статический адрес шлюза для интерфейса ETH
- set eth_dhcpd [0|1]: запускает DHCP-сервер для раздачи динамических IP-адресов на интерфейсе ETH, (по умолчанию: 0 - выключено)
# Управление питанием
Ретранслятор контролирует текущее напряжение питания (отображается в команде "show stats"). Это работает только в том случае, если 107-й байт в esp_init_data_default.bin, называемый vdd33_const, установлен в 255 (0xFF). Самый простой способ добиться этого — записать esp_init_data_default_v08_vdd33.bin во flash (см. ниже).
Если _vmin_ (в мВ, по умолчанию 0) установлен в значение > 0 и напряжение питания падает ниже этого значения, устройство перейдёт в режим глубокого сна на _vmin_sleep_ секунд. Если вы подключили GPIO16 к RST (что сложно пропаять на ESP-01), оно перезагрузится после этого интервала, попытается переподключиться и продолжит измерения. Если _vmin_ сохранён в конфигурации, устройство будет засыпать снова и снова, пока напряжение питания не поднимется выше порога. Эти настройки особенно (только?) полезны, если вы питаете ESP от (литиевой) батареи без защиты от глубокого разряда. Тогда значение 2900mV-3000mV, вероятно, будет полезно, так как оно снижает энергопотребление ESP до минимума, и у вас будет гораздо больше времени, чтобы зарядить или заменить батарею до повреждения. Это имеет смысл только в том случае, если ESP подключён напрямую к батарее. Если у вас есть дополнительная логика, она всё равно будет разряжать батарею.
Вы можете отправить ESP в сон вручную один раз, используя команду "sleep".
Внимание: Если вы сохраните значение _vmin_ выше максимального напряжения питания во flash, ретранслятор будет немедленно выключаться каждый раз после перезагрузки. Тогда вам придётся стереть всю конфигурацию, прошив blank.bin (или любой другой файл) по адресу 0x0c000.
# WiFi Repeater - L2 Bridge
Теперь проект предлагает два различных режима работы: **NAT Router** и **Layer 2 Bridge** (называемый «режимом ретранслятора»). Хотя оба режима расширяют зону покрытия сети, они принципиально различаются тем, как обрабатывают трафик и идентичность устройств.
### Режим NAT Router (стандартный)
В этом режиме, как описано выше, устройство действует как стандартный шлюз. Оно создаёт новую подсеть и выполняет трансляцию сетевых адресов (NAT) для всех устройств, подключённых к его точке доступа (AP).
* **Изоляция подсети**: Подключённые клиенты находятся в частной подсети (например, 192.168.4.x) и изолированы от основной сети.
* **Идентификация трафика**: Весь трафик от клиентов выглядит для основного маршрутизатора так, как будто он исходит от собственного IP/MAC-адреса ESP8266.
* **Простота**: Не требует специальной настройки вышестоящего маршрутизатора и совместим практически со всеми стандартными Wi-Fi сетями.
* **Ограничение**: Устройства в основной сети не могут легко инициировать подключение к устройствам за ретранслятором из-за барьера NAT, если не использовать проброс портов.
### Режим Layer 2 Bridge (вариант «ретранслятора»)
Этот режим реализует прозрачный мост на втором (канальном) уровне. ESP8266 расширяет существующую основную сеть, а не создаёт вторичную подсеть.
* **Прозрачный мост**: ESP8266 мостит трафик на уровне кадров Ethernet. Подключённые клиенты получают IP-адреса напрямую от DHCP-сервера основной сети (через DHCP snooping/relay).
* **Единая сеть**: Все устройства (и за ретранслятором, и на основном маршрутизаторе) находятся в одном широковещательном домене L2.
* **Видимость устройств**: Устройства за ретранслятором сохраняют свои исходные MAC и IP-адреса в основной сети. Это позволяет протоколам локального обнаружения (таким как mDNS/Bonjour, UPnP или сетевое обнаружение) работать без проблем во всей сети.
* **Сложность**: Требует продвинутой обработки, такой как Proxy ARP и DHCP snooping, чтобы вышестоящая сеть правильно маршрутизировала трафик обратно к «скрытым» клиентам, подключённым через ретранслятор.
* **Сценарий применения**: Идеально, когда требуется обнаружение устройств (например, управление принтером или устройством умного дома через приложение на телефоне) во всей сети.
Режим ретранслятора имеет меньше функций: маршрутизация, проброс портов и DHCP не требуются, ACL и Automesh также не имеют особого смысла, как и сетевой мониторинг через pcap. Поэтому все эти функции недоступны в режиме ретранслятора. Также MQTT был удалён. Остальные функции по-прежнему доступны через консоль или удалённую консоль.
Предварительно скомпилированные бинарные файлы можно найти в папке "firmware-repeater".
Первоначальная настройка версии режима ретранслятора в целом так же проста, как и для NAT Router. Через последовательную консоль просто задайте ssid, password, ap_ssid и ap_password, затем сохраните и перезагрузите устройство. Если вы хотите сделать это через веб-интерфейс, это тоже просто, но нужно соблюдать правильный порядок:
- Подключитесь клиентом к Wi-Fi "MyAP"
- Направьте браузер на "http://192.168.4.1"
- Введите **сначала** ssid и пароль в AP Settings, примените настройки и перезагрузите устройство
- Затем подключитесь к только что заданному ssid точки доступа и снова направьте браузер на "http://192.168.4.1"
- Теперь введите ssid и пароль в STA settings и подключитесь
Как только STA ssid задан, ретранслятор больше не запускает собственный DHCP-сервер, а получает IP-адрес от вышестоящего DHCP (адрес 192.168.4.1 больше не используется). Чтобы подключиться к его веб-странице или удалённой консоли, вы можете использовать имя "esp-wifi-repeater.local", если ваш клиент поддерживает mDNS, либо вам придётся узнать назначенный адрес в вышестоящем маршрутизаторе (или через последовательную консоль с помощью "show stats"). Вы всегда можете сбросить ESP через консоль и команду "reset factory".
### Сводка ключевых различий
| Feature | NAT Router | Layer 2 Bridge |
| :--- | :--- | :--- |
| **Сетевая архитектура** | Создаёт новую изолированную подсеть | Расширяет существующий широковещательный домен |
| **IP-адресация** | Клиенты используют вторичный пул адресов | Клиенты используют вышестоящий DHCP-сервер |
| **Обнаружение (mDNS/UPnP)** | Часто блокируется/затруднено | Полностью поддерживается (прозрачно) |
| **Видимость в вышестоящей сети** | Идентичность клиента скрыта (NAT) | Идентичность клиента сохраняется |
| **Реализация** | Стандартные сетевые механизмы | Продвинутое проксирование (Proxy ARP/Snooping) |
# Сборка и прошивка
Для непосредственной прошивки предварительно скомпилированных бинарных файлов на устройство используйте [Web-Installer](https://martin-ger.github.io/esp_wifi_repeater/).
Если у вас установлен Docker, самый простой способ получить доступ к полной среде сборки — подключить ваш ESP8266 к /dev/ttyUSB0 и запустить образ следующей командой:```
git clone https://github.com/martin-ger/esp_wifi_repeater.git
docker run -it --rm --device=/dev/ttyUSB0 -v $(pwd)/esp_wifi_repeater:/home/esp/esp_wifi_repeater martinfger/iot_devel:1.0
cd esp_wifi_repeater
make
make flash
Чтобы собрать версию L2 WiFi Repeater, просто используйте опцию VARIANT=bridge для команды make:``` git clone https://github.com/martin-ger/esp_wifi_repeater.git docker run -it --rm --device=/dev/ttyUSB0 -v $(pwd)/esp_wifi_repeater:/home/esp/esp_wifi_repeater martinfger/iot_devel:1.0 cd esp_wifi_repeater make VARIANT=bridge make flash
Чтобы настроить среду сборки с нуля и собрать этот бинарный файл, скачайте и установите esp-open-sdk (я предлагаю эту версию с базовым NONOS SDK 2.2: https://github.com/xxxajk/esp-open-sdk). Убедитесь, что вы можете скомпилировать и прошить включённый пример "blinky".
Затем скачайте это дерево исходников в отдельный каталог и настройте переменную BUILD_AREA в Makefile и любые нужные параметры в user/user_config.h. Изменения конфигурации по умолчанию можно внести в user/config_flash.c. Соберите прошивку esp_wifi_repeater командой "make". "make flash" прошивает её на esp8266.
Дерево исходников включает бинарную версию liblwip_open плюс необходимые дополнительные заголовочные файлы из моего форка esp-open-lwip и бинарный файл инструмента rboot. *Для этого не требуется дополнительных действий по установке.* Только если вы не хотите использовать предварительно скомпилированную библиотеку, получите исходники с https://github.com/martin-ger/esp-open-lwip . Используйте их, чтобы заменить каталог "esp-open-lwip" в дереве esp-open-sdk. Выполните "make clean" в каталоге esp_open_lwip и снова "make" в верхнем каталоге esp_open_sdk. Это скомпилирует liblwip_open.a, содержащую функции NAT. Замените liblwip_open_napt.a этим бинарным файлом. Также вы можете собрать бинарный файл "rboot.bin" из https://github.com/raburton/rboot и заменить его в корневом каталоге проекта.
*Обновление*: если вы где-то в интернете встречали инструкции по установке с использованием "0x10000.bin" — из-за OTA теперь это изменено на "0x02000.bin".
Если вы хотите использовать готовые предварительно скомпилированные бинарные файлы прошивки, вы можете прошить их с помощью "esptool.py --port /dev/ttyUSB0 write_flash -fs 4MB -ff 80m -fm dio 0x00000 firmware/0x00000.bin 0x02000 firmware/0x02000.bin" (для ESP-01 используйте -fs 1MB). Для esp8285 необходимо использовать -fs 1MB и -fm dout.
В Windows вы можете прошить её с помощью "ESP8266 Download Tool", доступного по адресу https://espressif.com/en/support/download/other-tools. Скачайте два файла 0x00000.bin и 0x02000.bin из каталога firmware. Для обычного ESP12, NodeMCU или Wemos D1 используйте следующие настройки (для ESP-01 измените FLASH SIZE на "8Mbit"):
<img src="https://raw.githubusercontent.com/martin-ger/esp_wifi_repeater/master/FlashRepeaterWindows.jpg">
Если режим "QIO" не работает на вашем устройстве, попробуйте "DIO". Также обратите внимание на "Detected Info", чтобы проверить размер и режим микросхемы flash. Если загруженная прошивка всё равно не запускается должным образом, проверьте с помощью прилагаемых контрольных сумм, не повреждены ли бинарные файлы. Если вы сомневаетесь, что бинарные файлы прошивки повреждены, скачайте полный репозиторий в виде zip-архива и извлеките бинарные файлы из этого zip — это позволяет избежать проблем при загрузке по HTTP (например, преобразований CR-LF).
# Поддержка обновления OTA (Over the air)
Основано на использовании библиотеки rboot: https://github.com/raburton/rboot и благодаря вкладу christianchristensen.
Процесс сборки создаёт две копии бинарного файла esp_wifi_repeater в каталоге firmware: 0x02000.bin и 0x82000.bin. Для первоначальной установки достаточно прошить только 0x00000.bin (загрузчик rboot) и 0x02000.bin (одну копию программы). esp_wifi_repeater будет работать.
Если у вас есть как минимум 1 МБ flash, вы можете выполнить обновление OTA (Over the air) другой версией. То есть вы можете в интерактивном режиме загрузить новый бинарный файл из CLI и переключиться на него. Другой бинарный файл загружается в текущую неактивную область памяти (либо 0x02000 (rom0), либо 0x82000 (rom1)) и запускается в случае успеха. Вы также можете в интерактивном режиме переключаться между двумя установленными бинарными файлами. Текущая конфигурация будет использоваться для обоих бинарных файлов (пока её формат не изменился).
Вы можете управлять функциями OTA с помощью следующих команд:
- show ota: показывает текущий активный бинарный файл и URL следующего обновления
- set ota_host _hostname_: задаёт имя хоста или IP-адрес OTA-сервера (по умолчанию: "none")
- set ota_port _portno_: задаёт номер порта OTA-сервера (по умолчанию: 80)
- ota update: пытается загрузить новый бинарный файл (0x02000.bin или 0x82000.bin) по HTTP с ota_host:ota_port и запускает его
- ota switch: переключает на другой бинарный файл (если он установлен)
Чтобы проверить функцию OTA, настройте ваш ESP (как STA или AP) на подключение к сети с сервером обновлений. Затем запустите простой веб-сервер в каталоге firmware, например;```
cd firmware
python -m SimpleHTTPServer 8080
Установите параметр hostname на имя хоста или IP вашего компьютера, установите portno на 8080 и нажмите «Сохранить». Затем введите в командной строке:``` ota update
Если настроено правильно, обновление начнётся, и ESP перезагрузится с новой прошивкой.
# Известные проблемы
- Из-за ограничений реализации SoftAP в ESP существует максимум 8 одновременно подключённых станций.
- ESP8266 требует хорошего источника питания, так как при передаче возникают скачки тока до 170 мА (обычное среднее потребление составляет около 70 мА при включённом Wi-Fi). Сначала проверьте источник питания, если ваш ESP работает нестабильно и время от времени перезагружается. Большой конденсатор между Vdd и Gnd может помочь, если вы столкнулись с такими проблемами.
# Лицензии
Программное обеспечение с открытым исходным кодом. Сторонние исходные файлы имеют собственный заголовок лицензии. Ко всем остальным файлам применяется лицензия MIT.