Безопасность
Авторизация
По умолчанию веб-интерфейс доступен без пароля. Для ограничения доступа по логину и паролю:
- Перейдите в Настройки, Система, Веб-сервер
- Заполните поля Имя пользователя и Пароль
- Сохраните настройки
После этого при открытии веб-интерфейса потребуется ввести учётные данные.
Поля карточки Веб-сервер перечислены в разделе Настройки, Система, Веб-сервер.
Без авторизации любой, кто дотянется до порта веб-интерфейса, получает полный доступ к управлению. Адрес привязки по умолчанию 0.0.0.0 слушает на всех адресах, включая IPv6, поэтому на хосте, чей файрвол принимает входящие соединения, например на VPS без файрвола, это кто угодно в интернете. Переключатель Доступ из интернета у веб-интерфейса не включается без имени пользователя и пароля; см. Доступ из интернета.
Если авторизация включена, но HTTPS не настроен - логин и пароль передаются по сети открытым текстом. Любой, кто может перехватить трафик (например, в публичной Wi-Fi сети), их увидит. При включённой авторизации рекомендуется включать и HTTPS, особенно если b4 доступен не только из локальной сети.
HTTPS
Для включения HTTPS:
- Подготовьте файлы сертификата и ключа (
.crt/.pemи.key/.pem) - В настройках веб-сервера укажите пути к файлам:
- TLS Сертификат - путь к файлу сертификата (
.crtили.pem) - TLS Ключ - путь к файлу ключа (
.keyили.pem)
- TLS Сертификат - путь к файлу сертификата (
- Сохраните и перезапустите
Для самоподписанного сертификата (подходит для локальной сети):
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=b4"
Файлы можно скопировать в директорию конфигурации (например, /etc/b4/) и указать пути к ним в настройках.
После включения HTTPS веб-интерфейс будет доступен по https://.
Ключ должен быть PEM-файлом без пароля. Ключ, защищённый паролем (ENCRYPTED PRIVATE KEY или Proc-Type: 4,ENCRYPTED в заголовке), отклоняется при сохранении настроек; пароль снимается командой openssl pkey -in key.pem -out key-plain.pem. Сохранение также не проходит, если файл отсутствует или сертификат не соответствует ключу.
Если файлы станут непригодными позже (перемещены, удалены, заменены защищённым ключом), b4 всё равно стартует, записывает ошибку в лог, показывает её в списке Требует внимания на дашборде и отдаёт веб-интерфейс по обычному HTTP, пока пара не будет исправлена.
WEB-прокси Telegram Desktop отдаётся тем же веб-сервером, если у него нет собственного порта релея, на отдельном хосте и до проверки авторизации, описанной выше. Telegram Desktop требует для этого хоста публично доверенный сертификат на порту 443, поэтому самоподписанной пары здесь недостаточно, а запросы к нему не видят учётных данных веб-интерфейса.
Доступ из интернета
У веб-интерфейса, MTProto-прокси, порта релея WEB-прокси Telegram Desktop и SOCKS5-прокси рядом с полем порта есть переключатель Доступ из интернета, по умолчанию выключенный. Когда он включён, b4 добавляет на своём хосте правило файрвола, которое принимает TCP-соединения на этот порт с любого адреса источника, и файрвол, отбрасывающий входящие соединения, как это делают WAN-сторона роутера и многие образы VPS, их пропускает. Переключатели применяются при сохранении, без перезапуска сервиса.
| Слушатель | Где | Поле конфигурации | Порт открывается, только если |
|---|---|---|---|
| Веб-интерфейс | Настройки, Система, Веб-сервер | system.web_server.expose | Заданы и имя пользователя, и пароль |
| MTProto-прокси | Настройки, Telegram, MTProto Прокси | system.mtproto.expose | Прокси включён |
| Порт релея WEB-прокси | Настройки, Telegram, WEB-прокси Telegram Desktop | system.mtproto.web_proxy.expose | Включены прокси и WEB-канал, а в поле Порт relay указан порт |
| SOCKS5-прокси | Настройки, Основные, SOCKS5, SOCKS5 Прокси | system.socks5.expose | Прокси включён, у него есть учётные данные или список разрешённых источников, а у веб-интерфейса заданы имя пользователя и пароль или он выключен (порт 0) с момента последнего запуска |
Правило
Слушатель на 0.0.0.0 (значение по умолчанию) или на :: принимает соединения и по IPv4, и по IPv6, поэтому правило добавляется для обоих семейств. Слушатель, привязанный к одному адресу, получает правило только для этого адреса назначения и его семейства, а привязанный к loopback-адресу не получает никакого, потому что снаружи до него не дойти.
Порт открывается, только пока его держит собственный слушатель b4. Слушатель, который не запустился, например потому что порт раньше заняла другая программа, правила не получает, а причиной указывается not_listening; окно «Поделиться ссылкой» у MTProto показывает её как предупреждение. При каждой проверке своих правил b4 заново смотрит на слушателей, поэтому слушатель, остановившийся позже, например порт релея WEB-прокси, тоже теряет правило.
Правило ставится везде, где файрвол хоста может отбросить соединение, какой бы Движок файрвола ни был выбран для собственных правил b4:
- iptables. Цепочка
B4_EXPOSEв таблицеfilterсодержит по одномуACCEPTна каждый открытый порт, и в неё ведёт единственный переход изINPUT. Переход ставится сразу под последним правилом списков блокировки вINPUT, поэтому адрес, заблокированный там, остаётся заблокированным и на портах b4, а если таких правил нет, переход ставится в началоINPUT. Правило списка блокировки - это переход в цепочку fail2banf2b-*или в цепочку CrowdSec или sshguard,DROPилиREJECTпо ipset с адресами источников либо переход ufw вufw-before-input, за которым ufw держит свои запрещающие правила и блокировки fail2ban через ufw. Если инструмент блокировки позже добавит своё правило ниже перехода b4, при следующей проверке переход опускается под него. Правила IPv4 ставятся черезiptables, правила IPv6 - черезip6tables, и в вариант nf_tables, и в legacy-вариант, если у этого варианта уже есть таблицаfilter. Модули ядра legacy-варианта b4 ради неё не загружает. - nftables.
acceptвставляется в начало каждой цепочки типа filter на хуке input в таблицах, которые не принадлежат b4, напримерinet fw4 inputна OpenWrt 22.03 и новее иinet filter inputиз/etc/nftables.conf, с комментарием видаb4-expose:mtproto. Цепочка с политикойacceptи приоритетом нижеfilterправила не получает. Такие цепочки создают fail2ban вf2b-table, CrowdSec в таблицахcrowdsecи banIP, поэтому заблокированные ими адреса остаются заблокированными и на портах b4; такая же цепочка -mangle_inputу fw4. ЦепочкаINPUTв таблицеfilter, которую создаёт iptables-nft, получает правило через утилиты iptables, потому что нативное правило nftables в ней ломает эти утилиты; нативная цепочка в одноимённой таблице, напримерtable ip filter { chain input ... }, обрабатывается как любая другая.
На хосте, где таких цепочек нет вовсе, отбросить соединение нечему, и правило b4 там не добавляет.
В nftables accept завершает путь пакета только по одной базовой цепочке. Все остальные базовые цепочки на хуке input пакет всё равно видят, а drop в любой из них окончателен. accept в собственной таблице b4 оставил бы порт закрытым за drop системного файрвола.
Перезагрузка файрвола
Прошивки роутеров перестраивают файрвол сами и уносят вместе с ним правило b4. В OpenWrt fw4 очищает свою таблицу при каждой перезагрузке, которую запускает поднятие интерфейса. Прошивка ASUS перестраивает таблицу filter при каждом перезапуске файрвола. NDMS в Keenetic при каждой перезаписи удаляет цепочки, которые ему не принадлежат. b4 проверяет свои правила с интервалом из поля Интервал мониторинга файрвола (секунды) (system.tables.monitor_interval, по умолчанию 10 секунд) и по SIGUSR1, возвращает пропавшие и добавляет правило в каждую цепочку input, появившуюся после предыдущей проверки. При интервале 0 проверка по таймеру выключена, и искать пропавшие правила b4 заставляет только SIGUSR1. Проверка работает при любом движке пакетов: и в режиме TUN, и когда движок не запустился.
Выключение переключателя, выключение слушателя или остановка b4 удаляют правило, как и b4 --clear-tables; после удаления при остановке ни одна проверка его не возвращает. Сохранение удаляет правила портов, которые оно закрывает, до того как слушатели получат новые настройки. Правило, которое не удалось удалить, например пока блокировку xtables держит другая программа, b4 отмечает в отчёте и удаляет при следующей проверке. При запуске b4 удаляет правила, оставшиеся от предыдущей работы, которая завершилась без очистки, если не включена настройка Пропустить настройку IPTables/NFTables: тогда b4 файрвол не трогает, а такие правила удаляет b4 --clear-tables.
Выключенный переключатель ничего не добавляет
При выключенном переключателе b4 не добавляет правила, но и не блокирует порт. На хосте, чей файрвол принимает входящие соединения, например на VPS без настроенного файрвола, каждый включённый слушатель на 0.0.0.0 доступен из интернета по IPv4 и IPv6, что бы ни показывал переключатель. Закрытым слушатель остаётся за счёт адреса привязки, адреса LAN или 127.0.0.1, либо за счёт собственного файрвола хоста.
По слушателям
- Веб-интерфейс. На том же порту работают API, MCP-эндпоинт и, если у WEB-прокси нет собственного порта релея, сам релей, поэтому открываются они все вместе. Сохранение, которое включает переключатель без имени пользователя и пароля, отклоняется, как и сохранение, которое стирает одно из них при включённом переключателе; если в файле конфигурации переключатель всё же включён без них, правило для веб-интерфейса не добавляется. Соединение, открытое, пока требовался вход, или в течение двух минут после его выключения, требует токен сессии всё время, пока остаётся открытым, при любом протоколе, а отклонённый на нём запрос закрывает соединение, поэтому стирание имени пользователя или пароля не позволяет ему продолжить работу без токена. Без HTTPS логин и каждый токен сессии идут через интернет открытым текстом, о чём предупреждает страница настроек. Веб-сервер занимает порт один раз, при запуске, поэтому правило следует за портом, который слушает работающий сервер, а изменённый порт или адрес привязки переносит правило при следующем перезапуске.
- MTProto-прокси. Доступ ограничивают секреты. На соединение, не прошедшее fake-TLS рукопожатие, отвечают так, как описано в разделе Что видит нераспознанное соединение, а сканирование и пробы расходуют Макс. подключений.
- Порт релея WEB-прокси. Переключатель виден, пока в поле Порт relay указан порт, а также пока он включён при пустом поле, чтобы его можно было выключить. При пустом поле релей отдаётся на порту веб-сервера, и собственного порта, который можно открыть, у него нет; снаружи он тогда доступен только через переключатель веб-интерфейса, который открывает вместе с ним и сам интерфейс.
- SOCKS5-прокси. Прокси без учётных данных и без списка разрешённых источников пропускает трафик любого, кто до него дотянется, поэтому сохранение, которое открыло бы его в таком виде, отклоняется, а если файл конфигурации всё же содержит такое сочетание, правило не добавляется. Правило принимает любой адрес источника; список разрешённых источников по-прежнему применяет сам прокси, на этапе accept. Назначения прокси не ограничивает: принятый клиент может подключиться к любому адресу, включая LAN и порты самого роутера, а среди них и веб-интерфейс. Поэтому, пока веб-сервер включён, для открытия прокси нужны ещё имя пользователя и пароль веб-интерфейса: сохранение, которое открыло бы прокси, пока у интерфейса их нет, отклоняется, как и сохранение, которое стирает одно из них при открытом прокси; если файл конфигурации всё же содержит такое состояние, правило для прокси не добавляется. SOCKS5 передаёт имя пользователя и пароль без шифрования. Правило покрывает только TCP: UDP ASSOCIATE ведёт каждую ассоциацию через порт, который выбирает ядро, поэтому на хосте, отбрасывающем входящие соединения, UDP через прокси снаружи не работает.
Что переключатель открыть не может
Правило открывает порт на хосте, где работает b4, и больше нигде.
- CGNAT. WAN-адрес из
100.64.0.0/10находится за NAT самого провайдера, и соединения из интернета по IPv4 до него не доходят. Публичного IPv6-адреса на WAN, если провайдер его выдаёт, это не касается. - Роутер или модем перед b4. Частный WAN-адрес (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16) означает, что перед b4 адреса транслирует ещё одно устройство, и порт нужно пробросить и на нём. Некоторые провайдеры держат CGNAT в частном адресном пространстве, и тогда проброс невозможен. - Облачные файрволы. Группы безопасности AWS, группы безопасности сети Azure, правила файрвола Google Cloud и списки безопасности Oracle Cloud фильтруют трафик до того, как он дойдёт до машины, и каждому нужно собственное правило. У облачной машины на сетевой карте часто есть только частный адрес, а публичный провайдер сопоставляет с ним сам; такому сопоставлению проброс не нужен, нужно только правило провайдера.
- Контейнер MikroTik. b4 меняет файрвол внутри контейнера, а всё, что приходит из WAN, фильтрует и транслирует RouterOS. Соединение снаружи доходит до контейнера только через правило
dst-natна RouterOS, описанное в разделе MikroTik. - Таблица, принадлежащая другой программе. Ядро не принимает изменения от других программ в таблицу nftables, которую создатель пометил как свою. firewalld 2.2 и новее помечает так свою таблицу (
NftablesTableOwner=yes, значение по умолчанию), если это поддерживают ядро и nftables, начиная с Linux 6.9 и nftables 1.1, как в Fedora 42, RHEL 10 и Debian 13. b4 распознаёт отказ,Operation not permitted, повторяет попытку для этой таблицы раз в 10 минут, а не при каждой проверке, и сообщает об отказе в логе и вGET /api/system/addresses; для firewalld в сообщении указаны команды, открывающие порт в самом firewalld,firewall-cmd --permanent --add-port=<порт>/tcpи затемfirewall-cmd --reload, и альтернатива,NftablesTableOwner=noв/etc/firewalld/firewalld.conf. Без этого флага цепочкаfilter_INPUTу firewalld принимает правило b4, как любая другая цепочка input. Правило тогда стоит в началеfilter_INPUT, выше зон firewalld, поэтому адрес, заблокированный через зону, rich rule или действия fail2ban для firewalld, всё равно доходит до открытых портов. - Пропустить настройку IPTables/NFTables. Пока эта настройка включена, b4 не добавляет правил, открывающих порты. Переключатели неактивны, уже включённый можно выключить, а включение этой настройки удаляет правила, которые b4 успел добавить.
У слушателя DNS поверх TCP (system.dns.tcp_port, по умолчанию 5453) и у слушателей прозрачного прокси для proxy-сетов и «Telegram через WebSocket» переключателя нет. Они существуют только как цели собственных правил перенаправления b4.
Изменить переключатели через MCP нельзя, а запись через MCP, которая открыла бы порт при включённом переключателе, отклоняется, например включение MTProto-прокси или смена его порта при включённом system.mtproto.expose. См. MCP-сервер.
Каждое изменение записывается в лог строками, начинающимися с Expose:. В них указаны открытые порты и цепочки с их правилами, включённый переключатель, который ничего не открыл, и причина, правило, которое не удалось добавить или удалить, и правила, возвращённые после перезагрузки файрвола. GET /api/system/addresses сообщает открытые порты, цепочки, ошибку для цепочки, где правило не удалось добавить или удалить, и, для переключателя с невыполненным условием, причину, одну из no_auth, web_no_auth, open_relay, shared_port, loopback, invalid_bind и not_listening. Окно «Поделиться ссылкой» у MTProto читает этот отчёт, чтобы предупредить, что порт прокси не открыт.