OpenSSL命令s_client总是说400错误请求


10

我正在尝试使用openssl s_client选项测试在Web浏览器中正常工作的服务器,使用openssl直接连接它会返回400错误请求:

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

重要说明:我已经尝试放置Host:标头,问题是当我运行GET时,立即发生错误,使我没有机会包含更多标头。用我的主机替换example.com ...


1
我通常echoecho -e "GET / HTTP/1.1\r\nHost: example.com.br\r\n\r\n" | openssl s_client ...。这\r\n很重要,因为这就是HTTP标准所说的。请求末尾的两个CRLF对也很重要,因为这就是标准所说的。另请参阅如何将“ echo”通过管道传输到“ openssl”?

它说“完成”,但网站没有回应,这正常吗?请注意,我无法以我要求的形式编写Host:标头,它在获取末尾给了我错误。
Luciano Andress Martini

我正在猜测(仅是猜测),但是您没有提供正确的文档名称;或者您没有提供Cookie或访问令牌。服务器收到您的请求,然后收到带有4xx错误代码的错误,以指示客户端错误。您可能需要GET /index.html ...或可能需要设置cookie。您可能应该尝试使用curlwget,然后发布完整的请求和响应,包括错误。否则,您必须提供真实的服务器名称和URL,以便我们运行测试。

我在配置服务器时就知道URL的正确名称,而且奇怪的是它在Web浏览器上运行,即使我在主机上指定了正确的域名,也不想使用openssl进行工作,这很奇怪:标头。500错误很可能是我以纯文本格式发送数据(例如,使用telnet),但是已使用openssl ...我想我只会放弃...。不是那么重要,只是因为我看到了如何通过telnet一个ssl网站并想要尝试的示例,但效果不佳。
Luciano Andress Martini

“我想我会放弃...” -如果您要退休,请删除问题。问答将不会完成,问题将永远不会有一个可接受的答案。在这种状态下,可能会给以后的访客带来麻烦。如果您需要删除问题的帮助,请标记它以引起管理员注意。

Answers:


19

根据https://bz.apache.org/bugzilla/show_bug.cgi?id=60695,我的命令是:

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

其中-crlf表示,根据openssl命令的帮助,

-crlf-将LF从终端转换为CRLF

然后,我可以输入多行命令,并且在第一个命令行之后不再输入“错误请求”作为响应。


现在比较好,但是当我尝试指定主机时,仅当我执行简单的get操作时,它才起作用。
Luciano Andress Martini

4

OK我本人也有同样的事情,花了一段时间才弄清楚。

交互式使用s_client时,我找不到在请求中发送多行的方法。输入第一行后,它总是立即发送请求。如果有人知道如何解决这个问题,请告诉我!

编辑:我看到卫和已经发布了执行此操作的方法-使用-crlf标记,但在此处将此答案保留为替代方法。

同时,如jww所建议,您必须使用echo此方法:

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

下一个问题是,默认情况下,openssl在输入文件关闭时关闭连接。这样使用时会立即执行echo。因此,您没有时间看到响应,而只是看到DONE输出!:-(

您可以sleep在echo命令中添加a 来解决此问题(注意括号很重要):

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

或者,更好的是,您可以使用该-ign_eof选项将连接保持打开状态:

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

-quite更妙的是,如果您只关心HTTP响应,则使用该选项可隐藏大多数TLS噪声并为您设置-ign_eof选项:

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

3

您可以使用OpenSSL发出GET请求:

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

请注意,您也可以使用“ HTTP / 2”,但是要小心,因为某些服务器(例如github.com)不支持它。


2

据我所知,400错误请求很可能与GET行中HTTP / 1.1的使用有关。

您是否在GET请求之后添加了“ Host:”标头?RFC声明对于HTTP / 1.1,需要Host标头:

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

19.6.1.1简化多宿主Web服务器并保留IP地址的更改

客户端和服务器支持主机请求标头,如果HTTP / 1.1请求中缺少主机请求标头(第14.23节),则报告错误以及接受绝对URI(第5.1.2节)的要求是最重要的要求之一。本规范定义的更改。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.