web-dev-qa-db-fra.com

Obtenir 408 erreurs sur nos journaux sans demande ni agent utilisateur

Je reçois beaucoup de demandes dans nos journaux Apache qui ressemblent à ceci

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

Il ne semble y avoir ni demande ni agent utilisateur. Quelqu'un a-t-il déjà vu cela avant?

38
Glenn Slaven

Êtes-vous par hasard en train d'exécuter vos serveurs Web sur Amazon derrière un Elastic Load Balancer?

Il semble ils génèrent beaucoup de réponses 408 en raison de leurs contrôles de santé .

Certaines des solutions de ce fil de discussion:

  • RequestReadTimeout header=0 body=0

    Cela désactive les 408 réponses si une demande expire.

  • Modifiez le contrôle de santé ELB sur un autre port.
  • Désactivez la journalisation des adresses IP ELB avec:

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

Et de ce billet de blog :

  • Ajustez le délai d'expiration de votre demande à 60 ou plus.
32
Ladadadada

Il y a déjà pas mal de bonnes réponses ici, mais je voudrais risquer une note supplémentaire qui n'a pas été spécifiquement abordée. Comme plusieurs des commentateurs précédents l'ont déjà mentionné, 408 indique un délai d'attente; et il existe toute une série de circonstances dans lesquelles des délais d'attente se produisent sur un serveur Web.

Cela dit, 408 erreurs peuvent être générées dans une variété de cas où votre serveur est analysé pour détecter les exploits. Dans de tels cas, les clients présentent rarement un agent utilisateur et mettent souvent fin aux connexions brusquement, ce qui entraîne un arrêt avorté de cette connexion qui peut générer une erreur 408.

Par exemple, disons que je suis un pirate ignoble qui recherche sur Internet des ordinateurs qui sont toujours vulnérables à la vulnérabilité POODLE. En tant que tel, j'ai écrit un script qui ouvre des connexions à de gros morceaux d'adresses IP pour trouver des serveurs qui accepteront SSL version 3 - plus tard, j'utiliserai cette liste pour rechercher spécifiquement l'exploit POODLE. Tout ce que ce premier script fait est d'établir une connexion en utilisant openssl pour vérifier SSLv3, comme ceci:

openssl s_client -connect [IP]:443 -ssl3

Cette commande entraînera, dans de nombreuses configurations d'Apache, un message 408 exactement comme vous l'avez décrit. L'exécution de cette commande sur deux de mes propres serveurs a entraîné cette entrée dans le journal d'accès:

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

Je voulais que cela soit clair car même dans une situation où OP n'utilisait aucune forme d'équilibrage de charge, 408 erreurs peuvent se produire dans diverses circonstances - certaines malveillantes, certaines indiquant des problèmes avec le client et d'autres indiquant des problèmes avec le serveur. (J'ai remarqué dans le journal fourni par OP qu'une IP locale était indiquée comme IP distante, mais OP ne mentionnait pas spécifiquement l'utilisation d'un équilibreur de charge, donc je ne savais pas si OP avait simplement utilisé une IP non routable à ces fins de démonstration, comme il l'a fait avec l'URL)

Quoi qu'il en soit, même si mon message est évidemment trop tard dans la journée pour aider le PO, j'espère qu'il pourrait aider ceux qui arrivent ici à la recherche d'une solution à toutes ces fichues erreurs de dépassement de délai.

11
Josh Wieder

Quelque chose se connecte au port et n'envoie jamais de données. HTTP 408 est une erreur de "timeout". Il y a un bon résumé ici: http://www.checkupdown.com/status/E408.html

9
Insyte

Il existe plusieurs raisons pour un délai d'attente 408. Mais partons du principe que tout va bien, puis à un moment donné, ces 408 commencent à apparaître dans votre journal d'accès - c'est-à-dire 408 0 "-" "-".

Comme beaucoup le soulignent sur le net, un 408 représente une connexion est établie mais aucune demande n'est envoyée dans l'échelle de temps appropriée, donc le serveur abandonne la connexion avec un 408. Une personne arrogante a en fait répondu à quelqu'un demandant de l'aide sur ce problème avec - "Quelle partie de Timeout ne comprenez-vous pas".

Je pense que c'est une réponse très novice et démontre un manque total de compréhension du fonctionnement de certaines méthodes de sécurité avec un logiciel de serveur Web.

Revenons donc au début, pourquoi je vois toutes ces 408. Une chose que vous aurez en commun avec le reste d'entre nous qui gère un serveur est la grande quantité d'attaques que vous recevez quotidiennement. Maintenant, que faites-vous à ce sujet? Eh bien: vous utilisez vos méthodes de sécurité choisies pour y faire face, c'est ce qui change.

Prenons un exemple très simple: supprimer une adresse IP. Inclus dans un fichier iptabes (rules.v4) vous avez "-A ufw-user-input -s 37.58.64.228 -j DROP". Ainsi vient le 37.58.64.228, le pare-feu reconnaît l'IP et abandonne la connexion. Dans de nombreuses configurations, vous ne sauriez même pas qu'il est frappé à la porte.

Prenons maintenant un exemple plus avancé, Supprimer la connexion en fonction de certains critères. Inclus dans un fichier iptabes (rules.v4) vous avez "-A INPUT -p tcp -m tcp --dport 80 -m string --string" cgi "--algo bm --to 1000 -j DROP". C'est différent parce que dans cette règle iptable, nous disons regardez les 1000 premiers octets de la chaîne de requête et voyez si vous pouvez trouver une sous-chaîne de "cgi" et si vous trouvez cette sous-chaîne, alors n'allez pas en outre, il suffit de supprimer la connexion.

Ici, la méthode de sécurité est bonne, mais en ce qui concerne vos journaux, ils sont trompeurs. Le 408 0 "-" "-" généré est le meilleur qu'Apache puisse faire dans ces circonstances. La connexion a été établie et la demande a dû être acceptée jusqu'à un certain point afin d'appliquer la règle de comparaison de chaînes qui aboutit finalement à un 408 car votre règle répondait aux critères de la connexion à abandonner. Donc, nos petits chéris novices ne pourraient pas se tromper plus s'ils essayaient. Une connexion a été établie et une demande a été reçue (vous n'en aurez tout simplement pas la visibilité dans ces circonstances). Bien qu'un 408 soit généré, ce n'est pas un 'Timeout'; votre serveur a simplement abandonné la connexion après que la demande a été faite en association avec votre règle de pare-feu. Il existe de nombreuses autres règles, qui créeraient la même situation 408. N'acceptez pas trop littéralement l'explication du code d'erreur du serveur 408 - "Demande expirée".

Idéalement, il y aurait un autre code d'erreur généré par Apache, par exemple - '499' qui signifierait 'Le serveur a lu votre demande et a décidé qu'il ne pouvait tout simplement pas être dérangé de vous divertir - Sod Off HaHa'.

Avec le dernier logiciel de serveur Web, vous pouvez pratiquement exclure les attaques DOS et le nouveau gène des navigateurs intégrant des capacités prédictives ne cause pas ce problème comme certains l'ont suggéré.

En bref, le 408 est généré parce que le serveur n'a pas répondu à la demande, de sorte que pour le client, la connexion a expiré, alors qu'en réalité le serveur a lu la demande mais a abandonné la connexion pour des raisons autres qu'un délai d'attente une requête.

6
Kev

Nous avons eu ce même problème, et nous y sommes perplexes pendant un bon moment. La meilleure solution que nous avons trouvée a été suggérée par l'équipe ELB du support AWS. Il s'agit essentiellement de s'assurer que les paramètres de délai d'expiration de votre serveur httpd sont tous supérieurs à votre ELB idle timeout paramètre (par défaut à 60 secondes).

  • Assurez-vous que la valeur de votre directive Apache Timeout est le double de idle timeout réglage de votre ELB.
  • Activez la fonction KeepAlive, assurez-vous que MaxKeepAliveRequests est très grand (soit 0 pour infini ou très haut, comme 2000), et que KeepAliveTimeout est supérieur à _ idle timeout.

Nous avons constaté que le paramètre KeepAlive (et les paramètres associés) réduisait spécifiquement la quantité de 408 à 0 (nous en voyons quelques-uns, mais très peu).

5
dsummersl

J'ai eu ce problème derrière AWS Elastic Load Balancer. Les contrôles d'intégrité ont généré une quantité affreuse de 408 réponses dans le journal.

La seule solution qui a fonctionné pour moi était d'avoir Load Balancer's Idle Timeout setting lower than its Health Check's Response Délai d'attente.

3
Přemysl Růžička

Un collègue a récemment fait remarquer que même si mon dernier message expliquait comment un 408 pouvait être associé à une mesure de sécurité, il n'offrait aucune solution.

Le journal d'accès pipé est ma solution personnelle.

Les éléments suivants devraient fonctionner immédiatement sur la plupart des configurations Ubuntu et avec un minimum de bricolage sur les autres configurations Apache. J'ai choisi PHP parce que c'est le plus facile à comprendre. Il y a deux scripts: le premier empêche l'écriture d'un 408 dans votre journal d'accès. Le second script envoie tous les 408 dans un fichier journal séparé. Quoi qu'il en soit, le résultat n'est plus 408 dans votre journal d'accès. C'est votre choix de script à implémenter.

Utilisez votre éditeur de texte préféré, j'utilise nano. Ouvrez le fichier dans lequel se trouvent vos directives "LogFormat" et "CustomLog". Mettez en commentaire les originaux avec le # habituel et ajoutez ce qui suit. Vous pouvez trouver ces directives dans le fichier ci-dessous.

Sudo nano/etc/Apache2/sites-available/default

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

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

REMARQUE: je n'enregistre pas d'images dans mon journal d'accès. Dans mon fichier etc/Apache2/httpd.conf j'inclus la ligne

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

Si cela ne vous intéresse pas, supprimez le env=!dontlog de la directive CustomLog.

Créez maintenant l'un des scripts PHP (#!/usr/bin/php est une référence à l'emplacement de l'interpréteur, assurez-vous que l'emplacement est correct pour votre système - vous pouvez le faire en tapant à l'invite $; whereis php - cela devrait renvoyer quelque chose comme php: /usr/bin/php /usr/bin/X11/php /usr/share/man/man1/php.1.gz. Comme vous pouvez le voir #!/usr/bin/php convient à ma configuration).

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);
      }
    }
  }
?>

Après avoir enregistré le PipedAccessLog.php script; assurez-vous que root est propriétaire en exécutant ce qui suit à l'invite $.

Sudo chown -R root:adm /var/log/Apache2/PipedAccessLog.php

Le PipedAccessLog.php le script aura besoin d'autorisations de lecture/écriture et d'exécution, exécutez donc ce qui suit à l'invite $.

Sudo chmod 755 /var/log/Apache2/PipedAccessLog.php

Enfin, pour que tout fonctionne, vous devez redémarrer le service Apache. Exécutez la commande suivante à l'invite $.

Sudo service Apache2 restart

Si vos journaux Apache se trouvent ailleurs, modifiez les chemins d'accès en fonction de votre configuration. Bonne chance.

0
Kev