10

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

Luciano Andress Martini
  • 6,490
  • 4
  • 26
  • 56
  • 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”?](https://stackoverflow.com/q/19147280/608639) –  Jun 14 '17 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. – Luciano Andress Martini Jun 14 '17 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. –  Jun 14 '17 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. – Luciano Andress Martini Jun 16 '17 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. –  Jun 16 '17 at 13:33
  • I 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 Jun 16 '17 at 13:54
  • @LucianoAndressMartini I'm not sure what you mean by "bad reputation", but you have no downvotes at the moment. If you want the question deleted we can do that, but having unanswered questions doesn't negatively affect you at all – Michael Mrozek Jun 16 '17 at 14:51
  • Well 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 Jun 16 '17 at 20:27

4 Answers4

28

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.

Wei He
  • 396
  • 2
  • 2
8

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 ...
Barry Pollard
  • 204
  • 1
  • 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 Jul 09 '20 at 13:23
  • You do to put the host in. OpenSSL will send that automatically. – Barry Pollard Jul 09 '20 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 Jul 10 '20 at 05:20
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.

Zombo
  • 1
  • 5
  • 43
  • 62
2

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.

elem103
  • 29
  • 1