Openssl command s_client always says 400 Bad Request
Solution 1
According to https://bz.apache.org/bugzilla/show_bug.cgi?id=60695 my command was:
openssl s_client -crlf -connect www.pgxperts.com:443
where -crlf means, according to help of the openssl command,
-crlf - convert LF from terminal into CRLF
Then I could input multiline commands and no "bad request" as response after the first commandline any more.
Solution 2
OK had the same thing myself and took a while to figure out.
I can't find a way to send multiple lines in the request when using s_client interactively. It always sends the request immediately as soon as you've entered the first line. If someone knows how to get around this then please let me know!
Edit: I see Wei He has posted the way to do this - use the -crlf
flag but leaving this answer here as an alternative method.
In the meantime, as jww suggested, you have to use echo
for this:
echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client ...
The next issue is that by default openssl closes the connection when the input file closes. Which is does immediately when using echo
like this. So you don't get time to see the response and instead just see the DONE output! :-(
You can add a sleep
to the echo command to get around this (note the brackets are important):
(echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"; sleep 10) | openssl s_client ...
Or, better than that, you can use the -ign_eof
option to leave the connection open:
echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client -ign_eof ...
Or better yet, if you're only concerned with the HTTP responses then use the -quite
option which hides most of the TLS noise and also sets that -ign_eof option for you:
echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client -quiet ...
Solution 3
You can issue a GET request with 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
Note that you can also use "HTTP/2", but be careful because some servers (e.g. github.com) do not support it.
Solution 4
From what I can see, the 400 Bad Request is likely to be related to the use of HTTP/1.1 in your GET line.
Did you add a "Host:" header after the GET request? The RFC states that for HTTP/1.1, a Host header is required:
https://www.ietf.org/rfc/rfc2616.txt
19.6.1.1 Changes to Simplify Multi-homed Web Servers and Conserve IP Addresses
The requirements that clients and servers support the Host request- header, report an error if the Host request-header (section 14.23) is missing from an HTTP/1.1 request, and accept absolute URIs (section 5.1.2) are among the most important changes defined by this specification.
Related videos on Youtube
Comments
-
Luciano Andress Martini over 1 year
I am trying to test a server that is working normal in web browser, with openssl s_client option, connecting it directly using openssl returns the 400 Bad Request:
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:)
Important: I already tried to put the Host: header, the thing is that when i run GET, the error occur immediately leaving me no chance to include more headers. Replace example.com with my host...
-
Admin almost 7 yearsI usually
echo
:echo -e "GET / HTTP/1.1\r\nHost: example.com.br\r\n\r\n" | openssl s_client ...
. The\r\n
is significant because that's what the HTTP standard says to do. Two CRLF pairs at the end of the request is also significant because that's what the standard says to do. Also see How do you pipe “echo” into “openssl”? -
Luciano Andress Martini almost 7 yearsIt says DONE, but no response for the website, is that normal? Note that i cant write the Host: header in the form that i asked, it gives me the error at the end of the get.
-
Admin almost 7 yearsI'm guessing (and its just a guess), but you are not supplying the correct document name; or you are not supplying a cookie or access token. The server gets your requests, and then errors with a 4xx error code to indicate a client error. You may need to
GET /index.html ...
or you may need to set a cookie. You should probably try withcurl
orwget
, and post the full request and response, including the error. Otherwise, you have to provide a real server name and URL so we can run the tests. -
Luciano Andress Martini almost 7 yearsI know the right name for the URL as i configured the server, and the strange thing is that it is working on the web browser, is very strange to do not want to work using openssl even if i specify the right domain name on Host: header. The 500 error is very likely that i am sending data in plain text (using telnet for example), but openssl has being used... I think i will just give up.... Is not so important, is just because i see a example of how to telnet a ssl website, and want to try it, but it does not doing fine.
-
Admin almost 7 years"I think i will just give up..." - If you are going to retire, then please delete the question. The Q&A will not complete, and the question will never have an accepted answer. In this state, it could cause problems for future visitors. If you need help deleting the question, then flag it for moderator attention.
-
Luciano Andress Martini almost 7 yearsI cannot delete the question... is giving me a error. Note that is not solved, but my experience with stack exchange is that questions with some issue that nobody experiences results in some bad reputation... specially if i dont accept any answers. This is very sad, because i am being honestly, and i am following the right procedures until now. Why you want to remove the telnet tag? It is related to telnet, openssl s_client is sometimes used to emulate the telnet effect in TCP protocols but with SSL, like HTTPS. The HTTP port is working fine on the same server, with telnet, get and host header
-
Luciano Andress Martini almost 7 yearsWell some people can get angry why just you dont accept my answer? Or this wonderful upvoted answer? and start to downvote, i haved this problems sometimes, not in this specifc community... But thank you i will leave the question if someone can emulate my problem i will appreciate, note i am running apache2 with a virtual host configured.
-
-
Luciano Andress Martini almost 7 yearsIt is better now, but does not work when i try to specify a host, only if i do a simple get.
-
Barry Pollard almost 4 yearsYou do to put the host in. OpenSSL will send that automatically.