Назад | Перейти на главную страницу

Получение 408 ошибок в наших журналах без запроса или пользовательского агента

Я получаю много запросов в наших журналах apache, которые выглядят следующим образом

www.example.com:80 10.240.1.8 - - [06/Mar/2013:00:39:19 +0000] "-" 408 0 "-" "-" -

Кажется, нет ни запроса, ни пользовательского агента. Кто-нибудь видел это раньше?

Вы случайно не запускаете свои веб-серверы в Amazon за Elastic Load Balancer?

Похоже на то они генерируют множество ответов 408 из-за их проверок состояния.

Некоторые из решений из этой ветки форума:

  • RequestReadTimeout header=0 body=0

    Это отключает 408 ответов, если время ожидания запроса истекло.

  • Измените проверку работоспособности ELB на другой порт.
  • Отключите ведение журнала для IP-адресов ELB с помощью:

    SetEnvIf Remote_Addr "10\.0\.0\.5" exclude_from_log
    CustomLog logs/access_log common env=!exclude_from_log
    

И из это сообщение в блоге:

  • Установите таймаут запроса на 60 или больше.

Здесь уже есть довольно много хороших ответов, но я хотел бы отметить еще одно замечание, которое не было специально рассмотрено. Как уже упоминалось многими предыдущими комментаторами, 408 означает тайм-аут; и существует целый ряд обстоятельств, при которых на веб-сервере происходят тайм-ауты.

С учетом сказанного, 408 ошибок могут быть сгенерированы во множестве случаев, когда ваш сервер сканируется на наличие эксплойтов. В таких случаях клиенты редко представляют пользовательский агент и часто внезапно завершают соединения, что приводит к аварийному завершению работы этого соединения, что может вызвать ошибку 408.

Например, предположим, что я подлый хакер, который сканирует Интернет в поисках компьютеров, которые все еще уязвимы для уязвимости POODLE. Поэтому я написал сценарий, который открывает соединения с большими блоками IP-адресов, чтобы найти серверы, которые будут принимать SSL версии 3 - позже я буду использовать этот список для сканирования эксплойта POODLE. Все, что делает этот первый сценарий, - это устанавливает соединение с помощью openssl для проверки SSLv3, например:

openssl s_client -connect [IP]:443 -ssl3

Эта команда во многих конфигурациях Apache будет возвращать сообщение 408 точно так, как вы описали. Выполнение этой команды на двух моих собственных серверах привело к такой записи в журнале доступа:

<remote IP address>  - - [04/Nov/2015:08:09:33 -0500] "-" 408 - "-" "-"

Я хотел прояснить это, поскольку даже в ситуации, когда OP не использовал какую-либо форму балансировки нагрузки, ошибки 408 могут возникать при различных обстоятельствах - некоторые злонамеренные, некоторые указывают на проблемы с клиентом, а некоторые указывают на проблемы с сервером. (Я заметил в журнале, предоставленном OP, что локальный IP-адрес был указан как удаленный IP-адрес, но OP конкретно не упомянул использование балансировщика нагрузки, поэтому я не был уверен, что OP просто использовал немаршрутизируемый IP-адрес для этих целей демонстрации, как он сделал с URL)

В любом случае, хотя мой пост явно слишком поздно, чтобы помочь OP, надеюсь, он может помочь другим, которые прибывают сюда в поисках решения всех этих чертовых ошибок тайм-аута.

Что-то подключается к порту, а данные не отправляются. HTTP 408 - ошибка «тайм-аут». Здесь есть хорошая запись: http://www.checkupdown.com/status/E408.html

Существует несколько причин тайм-аута 408. Но давайте начнем с того, что все в порядке, тогда в какой-то момент эти 408-е начинают появляться в вашем журнале доступа - то есть 408 0 "-" "-".

Как многие указывают в сети, 408 означает, что соединение установлено, но запрос не отправляется в соответствующем временном масштабе, поэтому сервер разрывает соединение с 408. Один высокомерный человек на самом деле ответил кому-то, просившему помощи по этой проблеме, с помощью - «Какую часть таймаута вы не понимаете».

Я думаю, что это ответ новичка, и он демонстрирует полное непонимание того, как некоторые методы безопасности работают с программным обеспечением веб-сервера.

Итак, вернемся к началу, почему я вижу все эти 408-е. Одна вещь, которая у вас будет общего с остальными из нас, управляющих сервером, - это огромное количество атак, которые вы получаете ежедневно. Что теперь делать с этим? Что ж: вы используете выбранные вами методы безопасности, чтобы бороться с ними, это то, что меняется.

Возьмем очень простой пример: Отбросьте IP-адрес. Включенный в файл iptabes (rules.v4) у вас есть "-A ufw-user-input -s 37.58.64.228 -j DROP". Итак, идет 37.58.64.228, брандмауэр распознает IP и разрывает соединение. Во многих конфигурациях вы даже не подозреваете, что кто-то постучал в дверь.

Теперь давайте рассмотрим более сложный пример. Отбросьте соединение по некоторым критериям. Включенный в файл iptabes (rules.v4) у вас есть «-A INPUT -p tcp -m tcp --dport 80 -m string --string« cgi »--algo bm --to 1000 -j DROP». Это отличается, потому что в этом правиле iptable мы говорим, посмотрите на первые 1000 байтов строки запроса и посмотрите, сможете ли вы найти подстроку «cgi», и если вы найдете эту подстроку, то не переходите далее просто разорвите соединение.

Здесь метод безопасности хороший, но в том, что касается ваших логов, вводящих в заблуждение. Сгенерированный 408 0 "-" "-" - лучшее, что может сделать apache в этих обстоятельствах. Соединение было установлено, и запрос должен был быть принят до определенного момента, чтобы применить правило сравнения строк, которое в конечном итоге приводит к ошибке 408, потому что ваше правило соответствует критериям для разрыва соединения. Так что наши маленькие новички не могли ошибиться больше, если бы попытались. Установлено соединение и получен запрос (при таких обстоятельствах вы просто не сможете его увидеть). Хотя генерируется 408, это не «Тайм-аут»; ваш сервер просто разорвал соединение после того, как запрос был сделан в соответствии с вашим правилом брандмауэра. Есть много других правил, которые могут создать ту же ситуацию 408. Не принимайте слишком буквально объяснение кода ошибки сервера 408 - «Истекло время ожидания запроса».

В идеале был бы другой код ошибки, сгенерированный Apache, например, «499», что означало бы «Сервер прочитал ваш запрос и решил, что это просто не может вас беспокоить, развлекая вас - черт возьми, ха-ха».

С помощью новейшего программного обеспечения веб-сервера вы можете практически исключить DOS-атаки, а новый ген браузеров, включающий возможности прогнозирования, не вызывает этой проблемы, как некоторые предполагают.

Короче говоря, 408 генерируется, потому что сервер не ответил на запрос, так что с точки зрения клиента тайм-аут соединения истек, когда на самом деле сервер прочитал запрос, но разорвал соединение по причинам, отличным от тайм-аута, ожидающего запрос.

У нас была именно эта проблема, и мы долго ломали над ней голову. Лучшее решение, которое мы придумали, было предложено командой ELB службы поддержки AWS. По сути, это зависит от того, чтобы настройки тайм-аута вашего httpd-сервера были больше, чем ваш ELB. idle timeout значение (по умолчанию 60 секунд).

  • Убедитесь, что ваш apache Timeout значение директивы вдвое больше idle timeout настройка вашего ELB.
  • Включите KeepAlive функция, убедитесь, что MaxKeepAliveRequests очень большой (либо 0 для бесконечности, либо очень высокий, например 2000), и что KeepAliveTimeout больше, чем у вашего ELB idle timeout.

Мы обнаружили, что KeepAlive (и соответствующие настройки) настройка специально уменьшила количество 408 до фактически 0 (мы видим несколько, но очень мало).

У меня возникла эта проблема с AWS Elastic Load Balancer. Проверки работоспособности генерировали ужасное количество 408 ответов в журнале.

Единственное решение, которое сработало для меня, - это иметь Тайм-аут простоя балансировщика нагрузки установка ниже чем его Тайм-аут ответа проверки работоспособности.

Коллега недавно заметил, что, хотя в моем последнем посте дается обоснованное объяснение того, как 408-й может иметь связь с мерой безопасности, он не предлагает решения.

Журнал Piped Access - мое личное решение.

Следующее должно работать сразу после установки в большинстве конфигураций Ubuntu и с минимальными изменениями в других конфигурациях Apache. Я выбрал PHP, потому что он самый простой для понимания. Есть два сценария: первый предотвращает запись 408 в ваш журнал доступа. Второй сценарий отправляет все сообщения 408 в отдельный файл журнала. В любом случае в вашем журнале доступа не будет больше 408. Какой сценарий реализовать - решать вам.

Используйте свой любимый текстовый редактор, я использую nano. Откройте файл с директивами LogFormat и CustomLog. Закомментируйте оригиналы обычным # и добавьте следующее. Вы можете найти эти директивы в файле ниже.

Судо нано / и т. д. / apache2 / сайты-доступные / по умолчанию

LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" AccessLogPipe

CustomLog "|/var/log/apache2/PipedAccessLog.php" AccessLogPipe env=!dontlog

ПРИМЕЧАНИЕ. Я не записываю изображения в журнал доступа. В моем файле etc / apache2 / httpd.conf я включаю строку

SetEnvIfNoCase Request_URI ".(gif)|(jpg)|(png)|(css)|(js)|(ico)$" dontlog

Если это вас не интересует, удалите env=!dontlog из CustomLog директива.

Теперь создайте один из следующих скриптов PHP (#!/usr/bin/php является ссылкой на расположение интерпретатора, убедитесь, что расположение соответствует вашей системе - вы можете сделать это, набрав в командной строке $; whereis php - это должно вернуть что-то вроде php: /usr/bin/php /usr/bin/X11/php /usr/share/man/man1/php.1.gz. Как вы видете #!/usr/bin/php подходит для моей установки).

sudo nano /var/log/apache2/PipedAccessLog.php

#!/usr/bin/php
<?php
  $file = '/var/log/apache2/access.log';
  $no408 = '"-" 408 0 "-" "-"';
  $stdin = fopen ('php://stdin', 'r');
  ob_implicit_flush (true);
  while ($line = fgets ($stdin)) {
    if($line != "") {
      if(stristr($line,$no408,true) == "") {
        file_put_contents($file, $line, FILE_APPEND | LOCK_EX);
      }
    }
  }
?>

sudo nano /var/log/apache2/PipedAccessLog.php

#!/usr/bin/php
<?php
  $file = '/var/log/apache2/access.log';
  $file408 = '/var/log/apache2/408.log';
  $no408 = '"-" 408 0 "-" "-"';
  $stdin = fopen ('php://stdin', 'r');
  ob_implicit_flush (true);
  while ($line = fgets ($stdin)) {
    if($line != "") {
      if(stristr($line,$no408,true) != "") {
        file_put_contents($file408, $line, FILE_APPEND | LOCK_EX);
      }
      else {
        file_put_contents($file, $line, FILE_APPEND | LOCK_EX);
      }
    }
  }
?>

Сохранив PipedAccessLog.php сценарий; убедитесь, что root имеет право собственности, выполнив в командной строке $ следующее.

sudo chown -R root:adm /var/log/apache2/PipedAccessLog.php

В PipedAccessLog.php script потребуются разрешения на чтение / запись и выполнение, поэтому выполните следующее в командной строке $.

sudo chmod 755 /var/log/apache2/PipedAccessLog.php

Наконец, чтобы все заработало, вам нужно перезапустить службу Apache. Выполните следующее в командной строке $.

sudo service apache2 restart

Если ваши журналы Apache находятся в другом месте, измените пути в соответствии с вашей конфигурацией. Удачи.

Я обнаружил, что количество ошибок 408 увеличивается как по количеству, так и по частоте. Также увеличивается диапазон IP-адресов, с которых они исходят (они записываются в отдельный файл). Существуют также очевидные шаблоны журнала, отображающие последовательные 408 из одних и тех же групп IP, которые не связаны с обычными тайм-аутами сервера, поскольку отправитель пытается подключиться с интервалом примерно 2 или 3 секунды в циклическом шаблоне (нет ожидания тайм-аута перед другим попытка подключения) Я рассматриваю это как простые попытки подключения в стиле DDOS. На мой взгляд, это тип подтверждающего сообщения для создателя о том, что сервер находится в сети ... затем они возвращаются позже с другими инструментами .... Если вы увеличиваете интервал тайм-аута, вы просто даете им большее time_allocation для запуска их программы взлома внутри.