当我尝试使用curl(或libcurl)连接到任何服务器(例如google.com)时,我得到错误消息:

curl:(35)错误:1408F10B:SSL例程:ssl3_get_record:错误的版本号

详细输出:

$ curl www.google.com --verbose  
* Rebuilt URL to: www.google.com/  
* Uses proxy env variable no_proxy == 'localhost,127.0.0.1,localaddress,.localdomain.com'  
* Uses proxy env variable http_proxy == 'https://proxy.in.tum.de:8080'  
*   Trying 131.159.0.2...  
* TCP_NODELAY set  
* Connected to proxy.in.tum.de (131.159.0.2) port 8080 (#0)  
* successfully set certificate verify locations:  
*   CAfile: /etc/ssl/certs/ca-certificates.crt  
  CApath: none  
* TLSv1.3 (OUT), TLS handshake, Client hello (1):  
* error:1408F10B:SSL routines:ssl3_get_record:wrong version number  
* Closing connection 0  
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number'  

出于某种原因,curl似乎使用TLSv1.3,即使我使用命令——TLSv1.2强制它使用TLSv1.2(它仍然会打印TLSv1.3 (OUT),…” 我正在使用最新版本的Curl和OpenSSL:

$ curl -V  
curl 7.61.0-DEV (x86_64-pc-linux-gnu) libcurl/7.61.0-DEV OpenSSL/1.1.1 zlib/1.2.8  
Release-Date: [unreleased]  
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp  
Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP UnixSockets HTTPS-proxy  

我想这是我安装程序的问题。 有人能解释一下这个错误信息是什么意思吗?


*使用代理环境变量http_proxy == 'https://proxy.in.tum.de:8080' ^ ^ ^ ^ ^

https://是错误的,应该是http://.代理本身应该通过HTTP访问,而不是HTTPS,即使目标URL是HTTPS。代理将正确地处理HTTPS连接并保持端到端加密。详细信息请参见HTTP CONNECT方法。


简单的答案

如果您使用代理服务器,请将代理设置为curl。curl无法连接到服务器,因此显示错误的版本号。 通过打开subl ~/来设置代理。Curlrc或使用任何其他文本编辑器。然后在文件中添加如下一行:

proxy= proxyserver:proxyport

例如proxy = 10.8.0.1:8080

如果您不在代理后面,请确保curlrc文件不包含代理设置。


如果有人在使用Nginx时得到这个错误,试着在你的服务器配置中添加以下内容:

server {
    listen 443 ssl;
    ...
}

这个问题源于Nginx为客户端提供HTTP服务器,而客户端希望在你监听的任何端口上使用HTTPS。当你在listen指令中指定ssl时,你在服务器端清除了这个。


更简单的一句话:

proxy=192.168.2.1:8080;curl -v example.com

如。$proxy=192.168.2.1:8080;curl -v example.com

xxxxxxxxx-ASUS:~$ proxy=192.168.2.1:8080;curl -v https://google.com|head -c 15  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
*   Trying 172.217.163.46:443...
* TCP_NODELAY set
* Connected to google.com (172.217.163.46) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]

在我的情况下,这个错误的原因是我的web服务器没有配置为侦听SSL端口443上的IPv6。启用后,错误消失了。

下面是Apache的操作方法:

<VirtualHost ip.v4.address:443 ip:v::6:address:443>
...
</VirtualHost>

对于nginx:

listen 443 ssl http2;
listen [::]:443 ssl http2; 

导致这个问题的另一个可能的原因是,如果你没有在Apache中启用虚拟主机的配置文件(或者你根本没有那个虚拟主机),而Apache中的默认虚拟主机只配置为非SSL连接——也就是说,没有默认的虚拟主机可以使用SSL。在本例中,由于Apache监听端口443,对不存在的虚拟主机的请求将到达默认虚拟主机——但该虚拟主机不使用SSL。


这是一个提示错误,说明您正在从HTTPS端口提供HTTP服务。

您可以很容易地使用telnet进行测试

telnet FQDN 443
GET / HTTP/1.0
[hit return twice]

如果你在这里看到普通的HTTP文档[不是某种错误],你知道你的配置是不正确的,响应服务器没有SSL加密响应。


还要检查/etc/hosts文件。浪费了2个小时。如果您将url重路由到127.0.0.1或任何其他环回,这将导致ssl握手失败。


感谢@bret-weinraub,

我发现服务器的回复有点奇怪。经过一些调查,发现我在/etc/hosts文件中有一个目标域的静态IP,由于他们已经更改了IP地址,我没有到达正确的服务器。


在使用MySQL CLI连接到外部MySQL DB的情况下,根据MySQL的版本,你可以像这样传递——ssl-mode=disabled:

$ mysql --ssl-mode=disabled -h yourhost.tld -p

或者简单地在你的客户端配置中,例如在/etc/my.cnf.d/client.cnf:

[client]
ssl-mode=DISABLED

这是为了开发,有时是为了安全,在封闭的私有开发环境中,这些东西在某些情况下可能会丧失。