Der Openssl-Befehl s_client sagt immer 400 Bad Request

10

Ich versuche, einen Server zu testen, der im Webbrowser normal funktioniert, mit der Option openssl s_client. Wenn ich ihn direkt mit openssl verbinde, wird die 400 Bad Request zurückgegeben:

openssl s_client -servername example.com -connect example.com:443 -tls1
(some information about the certificate)

GET / HTTP/1.1 
(and the error occurs **immediately** - no time to include more headers like Host:)

Wichtig: Ich habe bereits versucht, den Host: -Header zu setzen. Wenn ich GET ausführe, tritt der Fehler sofort auf, sodass ich keine Chance mehr habe, weitere Header einzuschließen. Ersetzen Sie example.com durch meinen Host ...

Luciano Andress Martini
quelle
1
Ich normalerweise echo: echo -e "GET / HTTP/1.1\r\nHost: example.com.br\r\n\r\n" | openssl s_client .... Das \r\nist wichtig, weil der HTTP-Standard dies vorschreibt. Zwei CRLF-Paare am Ende der Anforderung sind ebenfalls von Bedeutung, da der Standard dies vorschreibt. Siehe auch Wie leitet man "Echo" in "openssl"?
Es heißt FERTIG, aber keine Antwort für die Website, ist das normal? Beachten Sie, dass ich den Host: -Header nicht in der von mir angeforderten Form schreiben kann. Er gibt mir den Fehler am Ende des Abrufs.
Luciano Andress Martini
Ich vermute (und es ist nur eine Vermutung), aber Sie geben nicht den richtigen Dokumentnamen an. oder Sie liefern kein Cookie oder Zugriffstoken. Der Server erhält Ihre Anforderungen und dann Fehler mit einem 4xx-Fehlercode, um einen Clientfehler anzuzeigen. Möglicherweise müssen GET /index.html ...Sie ein Cookie setzen oder ein Cookie setzen. Sie sollten es wahrscheinlich mit curloder versuchen wgetund die vollständige Anfrage und Antwort einschließlich des Fehlers veröffentlichen. Andernfalls müssen Sie einen echten Servernamen und eine URL angeben, damit wir die Tests ausführen können.
Ich kenne den richtigen Namen für die URL, als ich den Server konfiguriert habe, und das Seltsame ist, dass er im Webbrowser funktioniert. Es ist sehr seltsam, nicht mit openssl arbeiten zu wollen, selbst wenn ich den richtigen Domainnamen auf dem Host angegeben habe: Header. Der 500-Fehler ist sehr wahrscheinlich, dass ich Daten im Klartext sende (zum Beispiel mit Telnet), aber openssl wurde verwendet ... Ich denke, ich werde einfach aufgeben ... Ist nicht so wichtig, ist nur, weil ich sehe Ein Beispiel dafür, wie man eine SSL-Website telnet und es ausprobieren möchte, aber es funktioniert nicht gut.
Luciano Andress Martini
"Ich denke, ich werde einfach aufgeben ..." - Wenn Sie in den Ruhestand gehen, löschen Sie bitte die Frage. Die Fragen und Antworten werden nicht abgeschlossen, und die Frage wird niemals akzeptiert. In diesem Zustand kann es zu Problemen für zukünftige Besucher kommen. Wenn Sie Hilfe beim Löschen der Frage benötigen, markieren Sie sie zur Aufmerksamkeit des Moderators.

Antworten:

19

Laut https://bz.apache.org/bugzilla/show_bug.cgi?id=60695 war mein Befehl:

openssl s_client -crlf -connect www.pgxperts.com:443

wobei -crlf laut Hilfe des Befehls openssl bedeutet,

-crlf - LF vom Terminal in CRLF konvertieren

Dann konnte ich mehrzeilige Befehle und keine "schlechte Anfrage" als Antwort nach der ersten Kommandozeile mehr eingeben.

Wei He
quelle
Es ist jetzt besser, funktioniert aber nicht, wenn ich versuche, einen Host anzugeben, nur wenn ich ein einfaches Get mache.
Luciano Andress Martini
4

OK hatte das gleiche selbst und brauchte eine Weile, um es herauszufinden.

Ich kann keine Möglichkeit finden, mehrere Zeilen in der Anfrage zu senden, wenn s_client interaktiv verwendet wird. Die Anfrage wird immer sofort gesendet, sobald Sie die erste Zeile eingegeben haben. Wenn jemand weiß, wie man das umgeht, dann lass es mich wissen!

Bearbeiten : Ich sehe Wei Er hat den Weg dazu gepostet - benutze die -crlfFlagge, aber lasse diese Antwort hier als alternative Methode.

In der Zwischenzeit müssen Sie, wie von jww vorgeschlagen, Folgendes verwenden echo:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client ...

Das nächste Problem ist, dass openssl standardmäßig die Verbindung schließt, wenn die Eingabedatei geschlossen wird. Was bei sofortiger Verwendung sofort funktioniert echo. Sie haben also keine Zeit, die Antwort zu sehen, sondern nur die DONE-Ausgabe! :-(

Sie können sleepdem Echo-Befehl ein hinzufügen , um dies zu umgehen (beachten Sie, dass die Klammern wichtig sind):

(echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"; sleep 10) | openssl s_client ...

Oder, besser noch, Sie können die -ign_eofOption verwenden, um die Verbindung offen zu lassen:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client -ign_eof ...

Oder noch besser, wenn Sie sich nur mit den HTTP-Antworten befassen, verwenden Sie die -quiteOption, die den größten Teil des TLS-Rauschens verbirgt und die Option -ign_eof für Sie festlegt:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client -quiet ...
Barry Pollard
quelle
3

Soweit ich sehen kann, hängt die 400 Bad Request wahrscheinlich mit der Verwendung von HTTP / 1.1 in Ihrer GET-Leitung zusammen.

Haben Sie nach der GET-Anforderung einen "Host:" - Header hinzugefügt? Der RFC gibt an, dass für HTTP / 1.1 ein Host-Header erforderlich ist:

https://www.ietf.org/rfc/rfc2616.txt

19.6.1.1 Änderungen zur Vereinfachung von Multi-Homed-Webservern und zur Erhaltung von IP-Adressen

Die Anforderungen, dass Clients und Server den Host-Anforderungsheader unterstützen, einen Fehler melden, wenn der Host-Anforderungsheader (Abschnitt 14.23) in einer HTTP / 1.1-Anforderung fehlt, und absolute URIs (Abschnitt 5.1.2) akzeptieren, gehören zu den wichtigsten Änderungen, die durch diese Spezifikation definiert sind.

elem103
quelle
2

Sie können eine GET-Anfrage mit OpenSSL stellen:

openssl s_client -quiet -connect cdn.sstatic.net:443 <<eof
GET /stackexchange/js/universal-login.js HTTP/1.1
Connection: close
Host: cdn.sstatic.net

eof

Beachten Sie, dass Sie auch "HTTP / 2" verwenden können. Seien Sie jedoch vorsichtig, da einige Server (z. B. github.com) dies nicht unterstützen.

Steven Penny
quelle