如何检查服务器是否启用了SSL

17

你们中有没有人知道,我是否可以通过我的应用程序代码检查服务器是否启用了ssl以及如何检查?


你能提供一下你写代码的环境信息吗? - Tom Haigh
你不能这样做。服务器没有 SSL,网站才有。 - Kuzgun
1
@Kuzgun,那是错误的!服务器可以在任意端口上支持SSL/TLS连接,用于非HTTP协议,而不一定使用它来保护HTTP连接。 - Yan Foto
8个回答

12

"宁愿问后原谅,也不要事前获准"

例如,若想通过 SSL 读取 stackoverflow.com,不必询问是否支持 SSL,直接操作即可。在 Python 中:

>>> import urllib2
>>> urllib2.urlopen('https://stackoverflow.com')
Traceback (most recent call last):
...
urllib2.URLError: <urlopen error (10060, 'Operation timed out')>
>>> html = urllib2.urlopen('http://stackoverflow.com').read()
>>> len(html)
146271
>>> 

这表明 stackoverflow.com 不支持 SSL (2008)。


更新: 现在 stackoverflow.com 支持 https。


7

11年后...

我来到这里,因为我有同样的问题(在终端内)。

我想最简单的解决方案是使用s_clientopenssl

openssl s_client -quiet -connect google.com:443

如果返回退出状态码为0(使用echo "$?"检查),则主机在给定端口(这里是443)支持SSL/TLS。

只有当端口支持SSL 并且 OpenSSL能够验证服务器证书时,它才会返回0。如果您不关心服务器证书是否有效,只想知道是否有一个SSL服务器在监听,则将2>&1 | grep -q '^depth'添加到上述命令行中。我很乐意学习更优雅的方法。 - András Korn
“SSL服务器”是什么意思?是指可以处理SSL握手并返回证书的服务器吗? - Yan Foto
在我的测试中,除了0以外的退出状态,只要能够列出证书,也是好的 :) - Edza
@Edza 你是对的! - Yan Foto

6
您没有指定编程语言,但您可以通过命令行完成此操作。
bash-3.2$ echo ^D | telnet www.google.com https
Trying 66.102.11.104...
Connected to www.l.google.com.
Escape character is '^]'.
Connection closed by foreign host.
bash-3.2$ echo ^D | telnet www.stackoverflow.com https
Trying 69.59.196.211...
telnet: connect to address 69.59.196.211: Connection refused
telnet: Unable to connect to remote host

看这里……Google可以,StackOverflow不行。


1
这只是检查端口443是否打开,而不是该端口(或任何其他端口)是否正在使用ssl。 - Emirikol
1
@Emirikol。是的。12年后,这不是我会给出的答案。https://dev59.com/8XRC5IYBdhLWcg3wW_lk#58754527 更好。 - johnsyweb

3

这是一个C#单元测试,可以在不需要正确的HTTPContext的情况下执行检测:

    [TestMethod]
    public void DetectSslSupport()
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.someinsecuresite.com");
        try
        {
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                //some sites like stackoverflow will perform a service side redirect to the http site before the browser/request can throw an errror.
                Assert.IsTrue(response.ResponseUri.Scheme == "https");
            }
        }
        catch (WebException)//"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."}
        {
            Assert.IsTrue(false);
        }
    }

2

我不确定您偏好的语言是什么,但以下是用C#编写的代码:

public bool IsSecureConnection()
{
    return HttpContext.Current.Request.IsSecureConnection || 
           HttpContext.Current.Request.Headers["HTTP_X_SSL_REQUEST"].Equals("1");
}

请注意,此标题是自定义的,但我认为你已经明白了。我见过一些人只查询“https”的请求,除了看起来不太好看之外,这可能是相当可以接受的,这取决于您的安全模型。
或者您是在询问它是否完全可用?

谢谢,dove。我认为这是在服务器端,我想知道在客户端如何知道服务器是否接受SSL连接(如果有可能的话)。我认为我可以通过一些异常处理来实现,如果我尝试启用ssl连接到服务器并且出现异常,则服务器(可能)没有启用ssl。但是我还有其他方法吗? - Bruno Costa

0

批量 SSL/TLS 测试给定输入文件 http.parsed 的形式为

10.31.11.5:443
10.31.11.25:443
10.31.11.37:55000
10.31.11.116:80

使用GNU Parallel

parallel -j10 'curl -k https://{} 1> /dev/null 2> /dev/null && echo https://{}' :::: http.parsed

我们获得输出

https://10.31.11.5:443
https://10.31.11.25:443
https://10.31.11.37:55000

0

如果您在服务器上运行PHP或ASP代码,简短的答案是您无法确定是否有SSL。您可以尝试与非SSL IP地址建立套接字连接,并查看是否获得了SSL证书,并枚举其通用名称和主题备用名称,但总体而言,简单的答案是您无法确定是否有SSL。Apache的常见(误)配置是在没有SSL证书的情况下监听端口443,因此能够建立连接并不能保证存在SSL。无法建立连接可能意味着您的应用程序没有网络权限。因为设置SSL很麻烦,所以您应该知道是否有SSL,这是一项配置决策。这就像想知道您有多少个孩子-您应该知道。


0

您需要指定您正在使用哪种协议 -- HTTP、IMAP、POP 等都有 SSL 版本。

假设您感兴趣的是 HTTPS,您可以检查服务器上是否有端口 443 上正在监听的东西,然后从那里开始...


是的,我也考虑过这个问题,但我认为服务端口取决于服务器的配置,我说得对吗?顺便说一下,我正在使用https和smtp,抱歉。 我的首选语言是C#,但如果有答案,我接受任何语言:P。感谢你们两个;) - Bruno Costa
是的,端口确实取决于配置——但如果您只是尝试使用HTTPS访问随机网站,那么端口将是443。 - genehack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接