12

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...

8
  • 1
    I 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”?
    – user56041
    Commented Jun 14, 2017 at 12:54
  • It 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. Commented Jun 14, 2017 at 13:29
  • I'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 with curl or wget, 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.
    – user56041
    Commented Jun 14, 2017 at 20:46
  • I 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. Commented Jun 16, 2017 at 13:21
  • "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.
    – user56041
    Commented Jun 16, 2017 at 13:33

4 Answers 4

29

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.

1
  • It is better now, but does not work when i try to specify a host, only if i do a simple get. Commented Jul 25, 2017 at 18:36
9

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 -quiet 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 ...
4
  • why do i still get an error after using carefully the above points. I have used option -crlf and then connected with wikipedia.org site : openssl.exe s_client -connect -crlf www.wikipedia.org:443 -servername www.wikipedia.org and when i try to get HEAD request : "HEAD / HTTP/1.1\r\nHost: www.wikipedia.org\r\n\r\n" - but getting an error "HTTP/1.0 400 Invalid HTTP Request" . can someone help me out
    – danny
    Commented Jul 9, 2020 at 13:23
  • You do to put the host in. OpenSSL will send that automatically. Commented Jul 9, 2020 at 20:05
  • -Sorry , I could not get what you are trying to convey. You mean to say, i need to mention hostname in the openssl s_client cmd request?
    – danny
    Commented Jul 10, 2020 at 5:20
  • This is gold, appreciate the thought process walk through too, very helpful.
    – Sysfu
    Commented Oct 9, 2023 at 18:11
5

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.

3

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.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .