Wie kann ich das HTTP-Anforderungsproblem auf meinem Webserver effektiv debuggen?
1326
Horseman
Ich habe ein seltsames Problem mit meinem Webserver in meinem LAN. HTTP-Requests laufen für immer, geben jedoch keinen aussagekräftigen Fehlercode.
Dieses Problem tritt bei meinem ASUS-Router und meinem Cisco-Router auf, aber bei meinem alten DLink-Router tritt dies paradoxerweise nicht auf. Einige Analyse der Unterschiede unten.
[Update Feb19 10:30 PM] Ich habe versucht, von Apache auf den Nginx-Server zu wechseln (basierend auf Kevins Kommentar), und sie zeigen ein identisches Ergebnis. Es scheint, dass es sich um TCP-Paketprobleme handelt, die unabhängig vom Server sind (siehe die folgenden tcpdumps). Ich habe auch mit der TCP-Datenmenge experimentiert, und die Ausfallwahrscheinlichkeit sinkt mit der Anforderungsgröße. Wenn weniger als ~ 800 Bytes vorhanden sind, kann er nach der Schleife 5-10 etwa die Hälfte der Zeit laden, bevor er die seltene ACK erhält. Bei ~ 2000 Bytes funktioniert es selten, aber manchmal funktioniert es. Bei ~ 6000 Bytes kein Weg. Der DLink-Router arbeitet sofort mit jeder dieser Dateigrößen. Ich habe geprüft, ob störende Pakete über die Loopback-Schnittstelle kommen, nichts dort. Ich habe Kabel / Anschlüsse gewechselt (aber keine NICs, nur die eine).
Ich habe versucht, mit Telnet eine manuelle HTTP-Anforderung für eine einfache Seite auszuführen:
telnet 192.168.0.101 80 GET /index.html HTTP/1.0
Dort erscheint dasselbe Problem und hängt einige Sekunden lang.
Der tcpdump-dump scheint ein fehlendes "ACK 2921" -Paket nach dem Push-Paket anzuzeigen. Dann wiederholt der Server das Push-Paket, immer noch kein ACK. Dann fährt es fort, eine Reihe von seq 1: 1461 ACKs durchzuführen, bevor ein abschließendes F-Paket aufgibt.
Ich bin kein Experte für TCP-Pakete, aber dies ist aus der Analyse des fehlerhaften Falls (ASUS-Router) im Vergleich zum erfolgreichen Fall (Dlink-Router). Auf der DLink gibt es ein klares ACK 2921-Paket. Vorher zeigen beide dieselbe Ausgabe.
Ein offensichtlicher Unterschied besteht darin, dass der Server beim DLink den Client über seine IP-Adresse (192.168.0.104) sieht, während der Server auf dem ASUS den Client anhand seines Hostnamens (Gin) sieht - aber er experimentiert mit den Regeln des dritten Routers (Cisco) Dies ist ein Teil des Problems, da es den Client auch per IP sieht, sich ansonsten jedoch wie ASUS verhält.
simon@fire:~$ sudo tcpdump -i eth0 port 80 or port 443 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 19:43:37.815448 IP Gin.60309 > fire.http: Flags [S], seq 4284943091, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0 19:43:37.815490 IP fire.http > Gin.60309: Flags [S.], seq 1854464822, ack 4284943092, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0 19:43:37.815684 IP Gin.60309 > fire.http: Flags [.], ack 1, win 16425, length 0 19:43:37.816701 IP Gin.60309 > fire.http: Flags [P.], seq 1:344, ack 1, win 16425, length 343: HTTP: GET / HTTP/1.1 19:43:37.816729 IP fire.http > Gin.60309: Flags [.], ack 344, win 237, length 0 19:43:37.818341 IP fire.http > Gin.60309: Flags [.], seq 1:2921, ack 344, win 237, length 2920: HTTP: HTTP/1.1 200 OK 19:43:37.818357 IP fire.http > Gin.60309: Flags [P.], seq 2921:4155, ack 344, win 237, length 1234: HTTP -- There seems to be a missing [.] ack 2921 packet here!? Then the server tries again -- 19:43:37.827311 IP fire.http > Gin.60309: Flags [P.], seq 2921:4155, ack 344, win 237, length 1234: HTTP 19:43:38.051329 IP fire.http > Gin.60309: Flags [.], seq 1:1461, ack 344, win 237, length 1460: HTTP: HTTP/1.1 200 OK 19:43:38.499322 IP fire.http > Gin.60309: Flags [.], seq 1:1461, ack 344, win 237, length 1460: HTTP: HTTP/1.1 200 OK 19:43:39.395318 IP fire.http > Gin.60309: Flags [.], seq 1:1461, ack 344, win 237, length 1460: HTTP: HTTP/1.1 200 OK 19:43:41.191327 IP fire.http > Gin.60309: Flags [.], seq 1:1461, ack 344, win 237, length 1460: HTTP: HTTP/1.1 200 OK 19:43:42.823524 IP fire.http > Gin.60309: Flags [F.], seq 4155, ack 344, win 237, length 0 19:43:42.823736 IP Gin.60309 > fire.http: Flags [.], ack 1, win 16425, length 0 19:43:44.783318 IP fire.http > Gin.60309: Flags [.], seq 1:1461, ack 344, win 237, length 1460: HTTP: HTTP/1.1 200 OK 19:43:51.967338 IP fire.http > Gin.60309: Flags [.], seq 1:1461, ack 344, win 237, length 1460: HTTP: HTTP/1.1 200 OK 19:43:52.825832 IP Gin.60309 > fire.http: Flags [.], seq 343:344, ack 1, win 16425, length 1: HTTP 19:43:52.825875 IP fire.http > Gin.60309: Flags [.], ack 344, win 237, options [nop,nop,sack 1 ], length 0 19:44:02.826426 IP Gin.60309 > fire.http: Flags [.], seq 343:344, ack 1, win 16425, length 1: HTTP 19:44:02.826464 IP fire.http > Gin.60309: Flags [.], ack 344, win 237, options [nop,nop,sack 1 ], length 0 19:44:06.335330 IP fire.http > Gin.60309: Flags [.], seq 1:1461, ack 344, win 237, length 1460: HTTP: HTTP/1.1 200 OK 19:44:12.827029 IP Gin.60309 > fire.http: Flags [.], seq 343:344, ack 1, win 16425, length 1: HTTP 19:44:12.827067 IP fire.http > Gin.60309: Flags [.], ack 344, win 237, options [nop,nop,sack 1 ], length 0 19:44:22.827563 IP Gin.60309 > fire.http: Flags [.], seq 343:344, ack 1, win 16425, length 1: HTTP 19:44:22.827592 IP fire.http > Gin.60309: Flags [.], ack 344, win 237, options [nop,nop,sack 1 ], length 0 19:44:32.828133 IP Gin.60309 > fire.http: Flags [.], seq 343:344, ack 1, win 16425, length 1: HTTP 19:44:32.828157 IP fire.http > Gin.60309: Flags [.], ack 344, win 237, options [nop,nop,sack 1 ], length 0 19:44:35.039322 IP fire.http > Gin.60309: Flags [.], seq 1:1461, ack 344, win 237, length 1460: HTTP: HTTP/1.1 200 OK 19:44:42.828692 IP Gin.60309 > fire.http: Flags [.], seq 343:344, ack 1, win 16425, length 1: HTTP 19:44:42.828734 IP fire.http > Gin.60309: Flags [.], ack 344, win 237, options [nop,nop,sack 1 ], length 0 19:45:08.571555 IP Gin.60309 > fire.http: Flags [F.], seq 344, ack 1, win 16425, length 0 19:45:08.571581 IP fire.http > Gin.60309: Flags [.], ack 345, win 237, length 0 (Pressed CTRL C after 30 seconds) ^C 32 packets captured 32 packets received by filter 0 packets dropped by kernel
Das tcpdump-Szenario bei Verwendung des DLink-Routers (funktioniert gut) ist nachstehend aufgeführt:
simon@fire:/sbin$ sudo tcpdump -B 4096 -i eth0 port 80 or port 443 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 21:48:20.209920 IP 192.168.0.104.53696 > fire.http: Flags [S], seq 1043812686, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0 21:48:20.209954 IP fire.http > 192.168.0.104.53696: Flags [S.], seq 639467520, ack 1043812687, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0 21:48:20.210290 IP 192.168.0.104.53696 > fire.http: Flags [.], ack 1, win 16425, length 0 21:48:20.211575 IP 192.168.0.104.53696 > fire.http: Flags [P.], seq 1:344, ack 1, win 16425, length 343: HTTP: GET / HTTP/1.1 21:48:20.211603 IP fire.http > 192.168.0.104.53696: Flags [.], ack 344, win 237, length 0 21:48:20.213190 IP fire.http > 192.168.0.104.53696: Flags [.], seq 1:2921, ack 344, win 237, length 2920: HTTP: HTTP/1.1 200 OK 21:48:20.213199 IP fire.http > 192.168.0.104.53696: Flags [P.], seq 2921:4155, ack 344, win 237, length 1234: HTTP 21:48:20.213959 IP 192.168.0.104.53696 > fire.http: Flags [.], ack 2921, win 16425, length 0 21:48:20.415317 IP fire.http > 192.168.0.104.53696: Flags [P.], seq 2921:4155, ack 344, win 237, length 1234: HTTP 21:48:20.416066 IP 192.168.0.104.53696 > fire.http: Flags [.], ack 4155, win 16116, options [nop,nop,sack 1 ], length 0 21:48:25.215387 IP fire.http > 192.168.0.104.53696: Flags [F.], seq 4155, ack 344, win 237, length 0 21:48:25.215864 IP 192.168.0.104.53696 > fire.http: Flags [.], ack 4156, win 16116, length 0 21:48:25.216086 IP 192.168.0.104.53696 > fire.http: Flags [F.], seq 344, ack 4156, win 16116, length 0 21:48:25.216093 IP fire.http > 192.168.0.104.53696: Flags [.], ack 345, win 237, length 0 ^C 14 packets captured 14 packets received by filter 0 packets dropped by kernel
Ich überprüfte auch die Firewall, fand keine Pakete, die die "Deny" -Regeln beachteten, und führte den empfohlenen iptables-Befehl aus, aber es half nicht: / sbin / iptables -I INPUT -p TCP --dport 80 -j ACCEPT
Ein ähnliches Problem tritt auf, wenn ich versuche, vom Server aus über Port 80 auf das Internet zuzugreifen (extrem langsam, dreht sich oder kann nach einer sehr langen Zeit eine einfache Seite laden).
Dies ist ein LAMP-Server (Ubuntu 16.4).
Danke im Voraus!
"telnet" im 21. Jahrhundert ??? Sie sind mutig ... Wenn dieser Server mit wildem Internet konfrontiert ist, empfehle ich dringend, dass Sie zu SSH wechseln. Führen Sie zu Ihrem Problem "sudo netstat -lntp" aus und fügen Sie das Ergebnis Ihrer Frage hinzu
Alex vor 7 Jahren
0
Danke Alex - Ich habe die Frage netstat -lntp hinzugefügt. Irgendetwas interessantes dort? :)
Horseman vor 7 Jahren
0
@Alex - `telnet` wird hier nicht zur Ausgabe von Befehlen verwendet, sondern nur zur Ausgabe einer rohen HTTP-Anforderung. Während "nc" dafür ein bisschen besser ist, ist es kein Sicherheitsrisiko. Das Sicherheitsrisiko besteht darin, einen Telnet * -Server * auszuführen und nicht den Telnet * -Befehl * zum manuellen Senden von Daten über einen Socket zu verwenden.
LawrenceC vor 7 Jahren
0
@LawrenceC Ich stimme zu, wenn ich sehe, dass Leute heute immer noch Telnet-Server verwenden, wirkt sich das auf mich wie ein rotes Tuch in einem Stierkampf aus. Laut der Ausgabe von "netstat" wartet der Server von OP auf eingehende Verbindungen an Port 23, also ist es immer noch der Fall . Wie auch immer, ich freue mich über Ihren Kommentar;) vor der Ausgabe von "netstat" klingt dies nach meiner Meinung nicht wirklich gut!
Alex vor 7 Jahren
0
Ahh Mist Ja, jetzt wo ich genau hinschaute, hast du recht.
LawrenceC vor 7 Jahren
0
2 Antworten auf die Frage
1
Kevin
Haben Sie versucht, tcpdump auf dem Server auszuführen?
sudo tcpdump -i eth0 port 80 or port 443
Wenn Sie die Pakete nicht sehen, müssen Sie möglicherweise Ihre Firewall noch einmal überprüfen.
Sie können Apache außerdem beenden und einen temporären netcat-Webserver auf Port 80 ausführen
Sie können tcpdump verwenden, um in eine Datei zu schreiben und diese dann auf einem Client-Computer mit Wireshark zu übertragen und zu öffnen, um zu sehen, welche Informationen in den Paketen übertragen werden.
sudo tcpdump -i eth0 port 80 or port 443 -w httpdebug.pcap
Kopieren Sie diese Datei dann auf einen Computer mit Wireshark. Wenn Sie Wireshark auf einem Windows-Computer installieren müssen, können Sie die Installation von Winpcap überspringen.
Einige andere Schritte, die Sie ausprobieren können:
Mit Apache eine Datei mit "Hello World!" oder etwas sehr kurzes.
Verwenden Sie den netcat-Webserver, um Ihre index.html zu testen und zu hosten
Wenn letzteres funktioniert, kann es sein, dass entweder viele Inhalte blockiert werden oder der Apache falsch konfiguriert ist. Ich würde versuchen, Apache zu löschen und erneut zu installieren, anstatt nach dem Konfigurationsproblem zu suchen.
+1 für das Check-Firewall-Bit - Versuchen Sie, "/ sbin / iptables -I INPUT -p tcp --dport 80 -j ACCEPT" auf dem Server auszuführen, damit der Verkehr auf Port 80 akzeptiert werden kann, bis der Neustart erfolgt ist / die Firewall neu gestartet wird.
davidgo vor 7 Jahren
0
Vielen Dank Kevin und Davidgo - Ich habe der Beschreibung den TCPpdump und die Netcat-Info hinzugefügt. Auch versucht iptables (keine Hilfe). netcat funktioniert an Port 80. TCPdump scheint zu zeigen, dass es die gleiche Anforderung immer wieder wiederholt ... aber keine tatsächlich verworfenen Pakete ?!
Horseman vor 7 Jahren
0
Dies ist nicht unbedingt eine gute Antwort (Behebung Ihres Problems), aber haben Sie in Betracht gezogen, Nginx entweder vor dem Apache auszuführen oder diesen zu ersetzen. Ich benutze Nginx und fand es viel einfacher zu konfigurieren und zu verwenden. Es ist auch (angeblich) bei der Bereitstellung statischer Inhalte viel effizienter.
Kevin vor 7 Jahren
0
Kevin, ich habe nichts von Nginx gehört, ich schaue nach, aber ich hoffe, ich kann das auch mit Apache lösen.
Horseman vor 7 Jahren
0
Für den tcpdump scheint es einen fehlenden ACK 2921 zu geben, der dem Push-Paket entspricht ... und interessanterweise auf einem anderen Router, wo der Server den Client nur über seine IP sieht und seinen "Gin" -Hostnamen, alles funktioniert und t I werde das desc mit ein paar mehr Infos dazu aktualisieren. 19: 43: 37.818357 IP fire.http> Gin.60309: Flags [P.], seq 2921: 4155, ack 344, win 237, Länge 1234: HTTP - Fehlende ACK hier für 2921, und es kommt nie. - 19: 43: 37.827311 IP fire.http> Gin.60309: Flags [P.], seq 2921: 4155, ack 344, gewinnen 237, Länge 1234: HTTP
Horseman vor 7 Jahren
0
@ kevin Interessanter neuer Datenpunkt, ich habe versucht, Apache zu deinstallieren und zu Nginx zu wechseln. Die Installation war sehr einfach (sehr erfreulich), führt jedoch zu einem identischen Ergebnis. Also das Problem ist vielleicht eine Schicht über dem Webserver, etwas mit TCP ... aber der Dlink-Router funktioniert irgendwie wie Magie.
Horseman vor 7 Jahren
0
@Horseman Ich vermute, es hat etwas mit dem Routing / Einschalten Ihres Netzwerks zu tun. Nicht wirklich sicher, wie man das Debuggen / Beheben von Fehlern bewerkstelligen könnte.
Kevin vor 7 Jahren
0
0
Alex
Entsprechend der sudo netstat -lntpAusgabe apachehört Ihr Setup nicht auf IPv4.
Sie müssen Ihrer Apache-Konfiguration Folgendes hinzufügen:
#NameVirtualHost *:80 Listen 0.0.0.0:80
Wenn Sie das SSL-Protokoll auf Ihrer Website verwenden möchten, fügen Sie Folgendes hinzu:
Diese Einstellungen gelten für Apache 2.4 + -Versionen. Wenn Sie 2.2-Versionen verwenden, fügen Sie auch hinzu
NameVirtualHost *:80 NameVirtualHost *:443
im (apache|httpd|ports)\.conf
Ich habe es aktualisiert, wie Sie erwähnt haben, aber es hat nicht geholfen. Bei der Recherche sieht es so aus, als würden sowohl IPv4 als auch v6 in der vorherigen Einstellung funktionieren, aber netstat stellt es lediglich als tcp6 dar. Einige Informationen hierzu hier [link] (http://unix.stackexchange.com/questions/106502/apache2-does -nicht-run-on-ipv4-tcp-port)
Horseman vor 7 Jahren
0
@Horseman "es sieht so aus, als würden sowohl IPv4 als auch v6 in der vorherigen Einstellung funktionieren, aber netstat stellt es nur als tcp6 dar" - Nein, das sollte nicht sein. Wenn Sie "Listen 0.0.0.0: 80" verwendet haben, wird der Listener auf TCP6 effektiv deaktiviert. Haben Sie Ihren Apache-Server ("sudo service apache2 restart") nach dem Hinzufügen der von mir erwähnten Änderungen angepasst?
Alex vor 7 Jahren
0
Ja, der Server wurde neu gestartet. Das Problem scheint nicht auf ipv4 / v6 zurückzuführen zu sein. (habe den nginx-server seitdem auch mit ipv4 / v6 aktiviert)
Horseman vor 7 Jahren
0
@Horseman Können Sie mit diesem Befehl eine Ausgabe erhalten: `wget -O - http: // 127.0.0.1`? Könnten Sie auch die Ausgabe von "ifconfig" und "iptables -L -n" hinzufügen
Alex vor 7 Jahren
0
Ich habe oben die Ausgabe von ifconfig und iptables hinzugefügt. Die Verwendung von wget -O - http://127.0.0.1 scheint gut zu funktionieren, zeigt die HTML-Seite sofort vollständig an. Vielen Dank, dass Sie weiterhin Vorschläge machen, Sie sind meine Lebensader: o)
Horseman vor 7 Jahren
0