curl: (60) SSL 证书问题:在代理后上传时
curl: (60) SSL certificate problem: when uploading behind proxy
我需要在公司代理后面进行 curl 上传。根据我尝试的网站,我遇到了以下两类问题,
- curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong 版本号
- curl: (60) SSL 证书问题:无法获取本地颁发者证书
详情如下:
案例一:
. . .
< HTTP/1.1 200 Connection established
< Proxy-agent: CCProxy
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* 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 -vX POST -d "userId=5&title=Hello World&body=Post body." https://jsonplaceholder.typicode.com/posts
Note: Unnecessary use of -X or --request, POST is already inferred.
* Uses proxy env variable https_proxy == 'http://10.xx.xx.xx:808/'
* Trying 10.xx.xx.xx:808...
* TCP_NODELAY set
* Connected to 10.xx.xx.xx port 808 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to jsonplaceholder.typicode.com:443
> CONNECT jsonplaceholder.typicode.com:443 HTTP/1.1
> Host: jsonplaceholder.typicode.com:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
< Proxy-agent: CCProxy
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
不是上述CCProxy的问题,而是我们公司使用的是Zscaler透明代理,它使用自己的证书拦截SSL请求。
请问有什么办法可以解决吗?
$ curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1g zlib/1.2.11 brotli/1.0.7 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.8.0 nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux bullseye/sid
Release: testing
Codename: bullseye
此错误 (SSL certificate problem
) 表示 curl 用于验证服务器对等点的 CA 存储不包含证书,因此无法验证服务器。
如果想要 curl 与终止 TLS 的透明代理一起工作,您必须将该代理的证书添加到 CA 包或完全忽略证书检查(我建议不要这样做)。
TLS 的透明代理当然会使连接完全不可靠并且破坏了安全属性。
答案是 “将该代理的证书添加到 CA 包”,感谢 。然后我想我应该填写其余部分。所以这是我尝试解决剩余的 problems/questions --
- 问:获得 Zscaler 证书的最简单方法是什么?
答:来自 here:
Go to Policy > SSL Inspection. In the Intermediate Root Certificate Authority for SSL Interception section, click Download Zscaler Root Certificate. Navigate to the ZscalerRootCerts. zip file and unzip it.
- 问:如何将该证书添加到 CA 包中?
答:见 How to install company proxy certificate:
- You can use
curl --cacert <CA certificate>
to supply your company CA cert.
- Or you can add your company CA cert to
/etc/pki/tls/certs/
and run make
there to make it available system-wide.
两个选项中的第 1 步将提取 Zscaler 证书。
选项 1 直接卷曲
- 下载证书(所有证书都包含在一个文件中)
- 执行
curl
命令并传递您要使用的证书。
# 1
openssl s_client -showcerts \
-connect jsonplaceholder.typicode.com:443 </dev/null 2>/dev/null \
| sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > typicode.crt
# 2
curl --cacert typicode.crt -v \
-d "userId=5&title=Hello World&body=Post body." \
https://jsonplaceholder.typicode.com/posts
选项 2(安装程序脚本)
如果 curl
命令由您无法控制的安装程序执行,则更新您的证书:
- 从服务器提取证书(使用 FQDN 或 IP 和端口,即:
jsonplaceholder.typicode.com:443
)
- 将 XXX.crt 证书移动到您的证书目录
- 更新证书
- 执行安装脚本
# 1
openssl s_client -showcerts \
-connect jsonplaceholder.typicode.com:443 </dev/null 2>/dev/null \
| sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > typicode.crt
# 2
sudo mv typicode.crt /usr/local/share/ca-certificates/
# 3
sudo update-ca-certificates
# 4 execute your installer script
奖金
如果您 need/want 仅获取 Zscaler 证书,请从以下位置获取 IP:https://ip.zscaler.com
openssl s_client -showcerts -servername server -connect 165.225.216.33:443 > </dev/null 2>/dev/null | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' | grep -m1 -B-1 -- '-----END CERTIFICATE-----' > zscaler.crt
更新 (11/19/21):
- 添加选项 1,当是直接
curl
并且不需要安装证书时。
- 优化了提取证书(创建文件)的命令
- 奖励:获得 Zscaler IP
在 Zscaler 代理后面的 Ubuntu 20 和 18 上测试。
无证书
有证书
参考文献:
我需要在公司代理后面进行 curl 上传。根据我尝试的网站,我遇到了以下两类问题,
- curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong 版本号
- curl: (60) SSL 证书问题:无法获取本地颁发者证书
详情如下:
案例一:
. . .
< HTTP/1.1 200 Connection established
< Proxy-agent: CCProxy
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* 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 -vX POST -d "userId=5&title=Hello World&body=Post body." https://jsonplaceholder.typicode.com/posts
Note: Unnecessary use of -X or --request, POST is already inferred.
* Uses proxy env variable https_proxy == 'http://10.xx.xx.xx:808/'
* Trying 10.xx.xx.xx:808...
* TCP_NODELAY set
* Connected to 10.xx.xx.xx port 808 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to jsonplaceholder.typicode.com:443
> CONNECT jsonplaceholder.typicode.com:443 HTTP/1.1
> Host: jsonplaceholder.typicode.com:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
< Proxy-agent: CCProxy
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
不是上述CCProxy的问题,而是我们公司使用的是Zscaler透明代理,它使用自己的证书拦截SSL请求。
请问有什么办法可以解决吗?
$ curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1g zlib/1.2.11 brotli/1.0.7 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.8.0 nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux bullseye/sid
Release: testing
Codename: bullseye
此错误 (SSL certificate problem
) 表示 curl 用于验证服务器对等点的 CA 存储不包含证书,因此无法验证服务器。
如果想要 curl 与终止 TLS 的透明代理一起工作,您必须将该代理的证书添加到 CA 包或完全忽略证书检查(我建议不要这样做)。
TLS 的透明代理当然会使连接完全不可靠并且破坏了安全属性。
答案是 “将该代理的证书添加到 CA 包”,感谢
- 问:获得 Zscaler 证书的最简单方法是什么?
答:来自 here:
Go to Policy > SSL Inspection. In the Intermediate Root Certificate Authority for SSL Interception section, click Download Zscaler Root Certificate. Navigate to the ZscalerRootCerts. zip file and unzip it.
- 问:如何将该证书添加到 CA 包中?
答:见 How to install company proxy certificate:
- You can use
curl --cacert <CA certificate>
to supply your company CA cert.- Or you can add your company CA cert to
/etc/pki/tls/certs/
and runmake
there to make it available system-wide.
两个选项中的第 1 步将提取 Zscaler 证书。
选项 1 直接卷曲
- 下载证书(所有证书都包含在一个文件中)
- 执行
curl
命令并传递您要使用的证书。
# 1
openssl s_client -showcerts \
-connect jsonplaceholder.typicode.com:443 </dev/null 2>/dev/null \
| sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > typicode.crt
# 2
curl --cacert typicode.crt -v \
-d "userId=5&title=Hello World&body=Post body." \
https://jsonplaceholder.typicode.com/posts
选项 2(安装程序脚本)
如果 curl
命令由您无法控制的安装程序执行,则更新您的证书:
- 从服务器提取证书(使用 FQDN 或 IP 和端口,即:
jsonplaceholder.typicode.com:443
) - 将 XXX.crt 证书移动到您的证书目录
- 更新证书
- 执行安装脚本
# 1
openssl s_client -showcerts \
-connect jsonplaceholder.typicode.com:443 </dev/null 2>/dev/null \
| sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > typicode.crt
# 2
sudo mv typicode.crt /usr/local/share/ca-certificates/
# 3
sudo update-ca-certificates
# 4 execute your installer script
奖金
如果您 need/want 仅获取 Zscaler 证书,请从以下位置获取 IP:https://ip.zscaler.com
openssl s_client -showcerts -servername server -connect 165.225.216.33:443 > </dev/null 2>/dev/null | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' | grep -m1 -B-1 -- '-----END CERTIFICATE-----' > zscaler.crt
更新 (11/19/21):
- 添加选项 1,当是直接
curl
并且不需要安装证书时。 - 优化了提取证书(创建文件)的命令
- 奖励:获得 Zscaler IP
在 Zscaler 代理后面的 Ubuntu 20 和 18 上测试。
无证书
有证书
参考文献: