Закройте сервер и поставьте WAF перед приложением
С первого развёртывания
erpc worker пускает SSH только с вашего адреса и отбрасывает все остальные входящие соединения. Таблица [waf] ставит фильтрующий прокси перед вашим API.Эта страница описывает ERPC CLI
v0.1.0-rc.4 — пререлиз.Брандмауэр
Развёртывание настраивает брандмауэр сервера до первого запуска приложения:
- SSH — только с адресов из
firewall.ssh_allowи с адреса, с которого идёт развёртывание; - все остальные входящие соединения отбрасываются, кроме
run.portдля адресов изfirewall.app_allow; для приложения за WAF вместо него — порт WAF, и только там, где WAF на сервере уже работает по правилам, которые сейчас задаёт[waf](ниже).
Каждое изменение выполняется под 120-секундным таймером отката и сохраняется только после того, как проходит новое соединение, поэтому ошибочное изменение не может закрыть вам доступ.
Однако allowlist переживает адрес, с которого он был составлен: если ваш домашний адрес изменится, вернуть доступ можно через поддержку ERPC для сервера ERPC или через консоль провайдера для собственного сервера. Прежде чем полагаться на домашний адрес, добавьте в
firewall.ssh_allow второй адрес, с которого можно достучаться до сервера (офис, выход VPN).Если ваш адрес меняется, добавьте все постоянные адреса, которые используют ваши администраторы:
bash
Поставьте WAF перед приложением
Добавьте в
erpc.toml одну таблицу:toml
После этого
erpc worker deploy запускает на сервере обратный HTTP-прокси в отдельном юните systemd (erpc-waf-<app>-<env>): от имени непривилегированного динамического пользователя без ключа, без секрета и без чего-либо, принадлежащего воркеру, с ограничением в 1 GiB памяти. Он слушает waf.port, читает каждый запрос раньше приложения, отклоняет то, что названо в его правилах, и передаёт остальное приложению на 127.0.0.1:<run.port>.-
Приложение остаётся на loopback. Его собственный порт никогда не открывается снаружи.
erpc worker apiи проверка работоспособности обращаются к приложению через loopback, в обход WAF. -
Кто может подключаться, по-прежнему определяет список брандмауэра, и порт WAF — единственное место, где этот список может разрешить всех:shЕсли в списке никого нет, WAF слушает, но никто не пропускается, и развёртывание сообщает об этом.
-
Порт открывается только после того, как WAF начнёт его слушать, и никогда раньше. Развёртывание, при котором WAF не запустился, завершается ошибкой и сообщает причину, а приложение продолжает работать.
-
Когда вы меняете
[waf], порт не открывается ни для кого нового, пока развёртывание не установит новые правила. -
Если убрать
[waf]изerpc.tomlи выполнить развёртывание, WAF будет удалён с сервера.
Настройки WAF
Обязателен только
port. Все ключи со значениями по умолчанию:toml
rate, max_connections_per_address, ban и new_connections отключаются значением false (ban = false), а пропущенный ключ принимает значение по умолчанию. erpc worker check ещё до любого развёртывания сообщает, что будет делать таблица [waf] и что в ней не так.Что WAF делает без всяких настроек
- Запрос, который не читается как один однозначный запрос HTTP/1, получает 400; то же получает путь, записанный не в нормальной форме.
- Запрос на смену протокола (
Upgrade) получает 501. - Каждый отказ засчитывается в бан, и каждый отказ завершает своё соединение.
- Адресом считается адрес IPv4 или IPv6
/64. - WAF не передаёт дальше заголовки соединения клиента с прокси (
Connectionи названные в нём заголовки,Keep-Alive,Proxy-Authenticate,Proxy-Authorization,Proxy-Connection,TE,Trailer),Expect, заголовки, в имени которых есть подчёркивание, а также собственныеForwarded,X-Real-IPиX-Forwarded-Protoклиента. Он устанавливает вX-Real-IPадрес, с которого пришло соединение, и добавляет этот адрес в конецX-Forwarded-For; только последняя записьX-Forwarded-Forисходит от самого прокси.
Как увидеть, что делает WAF
Переданный запрос не оставляет строки в журнале, а заголовки и тела никогда не записываются в журнал; query заблокированного запроса записывается — насколько хватает этих 200 байт. То, что отправляет клиент, не может ничего написать в вашем терминале: WAF пишет свой журнал печатаемыми символами ASCII.
Чего WAF не делает
- Нет TLS. На своём порту он работает по обычному HTTP/1.1.
- Нет HTTP/2: на него он отвечает 400.
- Нет WebSocket и никакого другого
Upgrade: 501. - Не заглядывает в тела. Тело измеряется, но никогда не читается. Список запросов сканеров короткий и служит фильтром шума, а не гарантией: приложение по-прежнему само проверяет свои входные данные.
- Нет аутентификации. Кто может вызывать приложение, решает само приложение и список брандмауэра.
- Один адрес — один клиент. Клиенты за одним NAT, прокси или CDN делят одно ограничение скорости и один бан; у клиента с несколькими адресами столько же ограничений скорости, сколько адресов.
- Баны и счётчики забываются при перезапуске WAF.
- Он запоминает не более 8192 адресов и одновременно держит не более 1024 соединений.
- Он слушает только IPv4, поэтому запись IPv6 в
app_allowпока ни к чему не ведёт. - Путь сравнивается как байты, в которые он декодируется. До приложения, которое читает пути менее строго (без учёта регистра, с параметрами
;, с двойным декодированием), можно добраться по имени, котороеdeny_pathsне покрывает. Уallow_pathsтакой бреши нет: то, что не указано, не передаётся. - Медленный читатель обслуживается до конца. Клиент, который продолжает принимать ответ, как бы медленно он это ни делал, обслуживается до конца.
- Наплыв запросов может оборвать большую загрузку. WAF работает в одном потоке, поэтому наплыв запросов может оборвать большую загрузку с кодом 408. Приложение, принимающее большие тела, повышает
body_timeout_secsвместе сmax_body_bytes.
Руководство по воркерам содержит все правила, включая то, когда изменение
app_allow откладывается до следующего развёртывания.





