Il comando Openssl s_client dice sempre 400 Richiesta errata


10

Sto provando a testare un server che funziona normalmente nel browser web, con l'opzione openssl s_client, collegandolo direttamente usando openssl restituisce la 400 richiesta errata:

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:)

Importante: ho già provato a inserire l'header Host: il fatto è che quando eseguo GET, l'errore si verifica immediatamente e non ho alcuna possibilità di includere più intestazioni. Sostituisci example.com con il mio host ...


1
Io di solito echo: echo -e "GET / HTTP/1.1\r\nHost: example.com.br\r\n\r\n" | openssl s_client .... Il \r\nè significativo perché è quello che lo standard HTTP dice di fare. Anche due coppie CRLF alla fine della richiesta sono significative perché è ciò che la norma dice di fare. Vedi anche Come installi “echo” in “openssl”?

Dice FATTO, ma nessuna risposta per il sito Web, è normale? Nota che non posso scrivere l'Host: header nel modulo che ho chiesto, mi dà l'errore alla fine del get.
Luciano Andress Martini,

Sto indovinando (ed è solo una supposizione), ma non stai fornendo il nome corretto del documento; o non stai fornendo un cookie o un token di accesso. Il server riceve le richieste e quindi gli errori con un codice di errore 4xx per indicare un errore del client. Potrebbe essere necessario GET /index.html ...o potrebbe essere necessario impostare un cookie. Probabilmente dovresti provare con curlo wgete pubblicare la richiesta completa e la risposta, incluso l'errore. Altrimenti, devi fornire un nome server e un URL reali in modo da poter eseguire i test.

Conosco il nome giusto per l'URL mentre ho configurato il server, e la cosa strana è che sta funzionando sul browser web, è molto strano non voler lavorare usando openssl anche se specifico il nome di dominio giusto su Host: intestazione. L'errore 500 è molto probabile che sto inviando dati in testo normale (usando telnet per esempio), ma openssl è stato usato ... Penso che mi arrenderò ... Non è così importante, è solo perché vedo un esempio di come telnetare un sito Web SSL e voler provarlo, ma non va bene.
Luciano Andress Martini,

"Penso che mi arrenderò e basta ..." - Se hai intenzione di andare in pensione, ti preghiamo di eliminare la domanda. Le domande e risposte non verranno completate e la domanda non avrà mai una risposta accettata. In questo stato, potrebbe causare problemi ai futuri visitatori. Se hai bisogno di aiuto per eliminare la domanda, segnalala per l'attenzione del moderatore.

Risposte:


19

Secondo https://bz.apache.org/bugzilla/show_bug.cgi?id=60695 il mio comando era:

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

dove -crlf significa, secondo l'aiuto del comando openssl,

-crlf - converte LF dal terminale in CRLF

Quindi ho potuto inserire comandi multilinea e nessuna "richiesta errata" come risposta dopo la prima riga di comando.


Ora è meglio, ma non funziona quando provo a specificare un host, solo se faccio un semplice get.
Luciano Andress Martini,

4

OK ha avuto la stessa cosa me stesso e ha impiegato un po 'di tempo per capire.

Non riesco a trovare un modo per inviare più righe nella richiesta quando si utilizza s_client in modo interattivo. Invia sempre la richiesta immediatamente dopo aver inserito la prima riga. Se qualcuno sa come aggirare questo, per favore fatemelo sapere!

Modifica : vedo che Wei ha pubblicato il modo per farlo - usa la -crlfbandiera ma lasciando questa risposta qui come metodo alternativo.

Nel frattempo, come suggerito da jww, devi usare echoper questo:

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

Il prossimo problema è che per impostazione predefinita openssl chiude la connessione alla chiusura del file di input. Che è immediatamente quando si utilizza in echoquesto modo. Quindi non hai tempo per vedere la risposta e invece vedi solo l'output DONE! :-(

È possibile aggiungere sleepa al comando echo per aggirare questo (notare che le parentesi sono importanti):

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

In alternativa, puoi utilizzare l' -ign_eofopzione per lasciare aperta la connessione:

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

O ancora meglio, se ti preoccupi solo delle risposte HTTP, usa l' -quiteopzione che nasconde la maggior parte del rumore TLS e imposta anche l'opzione -ign_eof per te:

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

3

Da quello che posso vedere, la 400 Bad Request è probabilmente correlata all'uso di HTTP / 1.1 nella tua linea GET.

Hai aggiunto un'intestazione "Host:" dopo la richiesta GET? La RFC afferma che per HTTP / 1.1 è richiesta un'intestazione Host:

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

19.6.1.1 Modifiche per semplificare i server Web multihomed e conservare gli indirizzi IP

I requisiti che client e server supportano l'intestazione della richiesta host, segnalano un errore se l'intestazione della richiesta host (sezione 14.23) manca da una richiesta HTTP / 1.1 e accettano URI assoluti (sezione 5.1.2) sono tra i più importanti modifiche definite da questa specifica.


2

Puoi inviare una richiesta GET con OpenSSL:

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

Nota che puoi anche usare "HTTP / 2", ma fai attenzione perché alcuni server (es. Github.com) non lo supportano.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.