Что значит \x16\x03 в access.log

4 мин чтения · обновлено 9 октября 2026

Если просмотреть access.log nginx на сервере с открытым портом 80, в нём найдутся странные строки: вместо GET / HTTP/1.1 там \x16\x03\x01\x02\x00\x01 и ответ 400. Это не сбой и не взлом nginx, а сканеры, которые проверяют, какие протоколы слушает ваш сервер. Разберём, что значат эти байты, кого стоит банить и почему пустые запросы и запросы без User-Agent банить нельзя.

Откуда в журнале байты

nginx ждёт на HTTP-порту текстовый запрос. Если вместо него приходит что-то другое, он отвечает 400 Bad Request и записывает в журнал то, что получил. Непечатаемые байты при этом экранируются как \xHH. Первые байты обычно однозначно выдают протокол, которым пытались говорить с сервером.

Что означают типичные строки

Начало запроса в журналеЧто это
\x16\x03\x01...TLS ClientHello: HTTPS-запрос на HTTP-порт. 0x16 — тип записи «рукопожатие», 0x03 0x01 — версия TLS в заголовке записи.
\x00\x00\x00\x85\xFFSMB... или ...\xFESMBПроба SMB, протокола файловых шар Windows. Ищут открытые шары и уязвимые версии.
\x03\x00\x00/*\xE0...Cookie: mstshash=Начало подключения RDP. Сканер проверяет, не висит ли удалённый рабочий стол на этом порту.
\x05\x01\x00 или \x04\x01...Приветствие SOCKS5 или SOCKS4. Ищут открытые прокси, чтобы ходить через них.
SSH-2.0-GoКлиент SSH на HTTP-порту.

Так выглядят эти строки в журнале (адреса заменены на тестовые):

198.51.100.23 - - [09/Oct/2026:02:14:07 +0300] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03" 400 157 "-" "-"
198.51.100.41 - - [09/Oct/2026:02:31:55 +0300] "\x03\x00\x00/*\xE0\x00\x00\x00\x00\x00Cookie: mstshash=Administr" 400 157 "-" "-"
203.0.113.77 - - [09/Oct/2026:03:02:19 +0300] "\x05\x01\x00" 400 157 "-" "-"

\x16\x03 иногда бывает и от живого клиента, у которого в настройках перепутан порт, например https://site:80. Но живой клиент повторяет ошибку пару раз и уходит, а сканер приходит с новым набором проб.

Сколько этого на реальных серверах

Анализ журналов KIPBan за сутки на 9 октября 2026 года нашёл мусор вместо HTTP-запроса на 7 серверах из 13: 3 319 запросов от 160 адресов. 155 из этих адресов не были заблокированы ничем, хотя на части серверов fail2ban настраивал опытный администратор. Готового фильтра для таких запросов в поставке fail2ban нет, поэтому их обычно никто не ловит.

Чего банить нельзя

Рядом с мусорными запросами в журнале есть строки, которые очень хочется забанить заодно. Делать этого не нужно:

  • Пустой запрос ("" 400). Клиент открыл соединение и закрыл его, ничего не отправив. Так делают проверки доступности, балансировщики и браузеры, которые заранее открывают соединение «про запас» и не используют его.
  • Запрос без User-Agent ("-" в последнем поле). Так ходят мониторинг, вебхуки, платёжные уведомления и клиенты API. Отсутствие User-Agent ничего не говорит об атаке.
  • curl, Wget, python-requests в User-Agent. Это те же мониторинг и интеграции. Шаблоны KIPBan их не блокируют.

Правило «банить всё с кодом 400» поймает всех перечисленных. Банить стоит только запросы, которые начинаются с байтов чужого протокола.

Фильтр для fail2ban

Простой фильтр для журнала nginx в формате combined, который ловит TLS, SOCKS, RDP и SMB на HTTP-порту:

# /etc/fail2ban/filter.d/nginx-binary.conf
[Definition]
failregex = ^<HOST> \S+ \S+ \[[^\]]*\] "\\x(?:16\\x03|05\\x01|04\\x01|03\\x00\\x00|00\\x00\\x00)
ignoreregex =
# /etc/fail2ban/jail.d/nginx-binary.local
[nginx-binary]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 1
findtime = 10m
action   = dummy

Перед включением проверьте его на своём журнале и посмотрите, кто попадает:

fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-binary.conf --print-all-matched

Строка action = dummy включает режим наблюдения: jail считает, кого забанил бы, но ничего не блокирует. Как его читать и когда переключать на бан, описано в статье «Режим наблюдения: как включить jail и не забанить своих».

Фильтр рассчитан на журнал, где IP посетителя стоит в начале строки. Если сайт за Cloudflare или другим прокси, сначала настройте запись реального IP, иначе забаните прокси. Подробнее в статье «fail2ban за Cloudflare».

Как это сделано в KIPBan

В каталоге KIPBan есть шаблон «Мусор вместо HTTP-запроса»: TLS на HTTP-порт, пробы SMB, RDP, SOCKS, SSH и двоичный мусор, порог 1. Пустые запросы и запросы без User-Agent он не трогает. Анализ журналов сам находит журналы nginx и Apache на сервере, в том числе в папках панели управления, и показывает, сколько таких адресов приходит и сколько из них уже заблокировано. Jail с этим шаблоном включается кнопкой из отчёта и сначала работает в режиме наблюдения.

Анализ журналов работает на Linux с агентом KIPBan 21.5 и новее, а журналы не покидают сервер: в кабинет приходят только счётчики.

Вопросы

Что значит \x16\x03\x01 в access.log nginx?

Это начало TLS-рукопожатия: кто-то отправил HTTPS-запрос на HTTP-порт. Чаще всего это сканер, который проверяет протоколы на всех портах подряд, реже клиент с неверно указанным портом. nginx отвечает на такой запрос кодом 400.

Можно ли банить запросы без User-Agent?

Нет. Без User-Agent ходят мониторинг, вебхуки, платёжные уведомления и клиенты API. Отсутствие User-Agent не признак атаки, и такой бан сломает интеграции.

Почему в access.log пустые запросы с кодом 400?

Клиент открыл соединение и закрыл его, ничего не отправив. Так делают проверки доступности, балансировщики и браузеры, которые открывают соединение заранее. Банить такие адреса нельзя.