修复 SSL certificate problem: unable to get local issuer certificate

在嵌入式 linux 设备上使用 curl 访问 https 站点会报错:

# curl https://www.google.com
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

而 linux 桌面上使用 curl 访问 https 站点则正常:

$ curl https://www.google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="https://www.google.com.hk/?gfe_rd=cr&amp;ei=i2DmVtXLDOzN8geg-afACA">here</A>.
</BODY></HTML>

嵌入式 linux 设备上缺少了 CA 证书。

什么是 CA 证书

Certificate Authority (CA) Certificates

A certificate authority (CA) is a trusted entity that issues electronic documents that verify a digital entity’s identity on the Internet. The electronic documents, which are called digital certificates, are an essential part of secure communication and play an important part in the public key infrastructure (PKI). Certificates typically include the owner's public key, the expiration date of the certificate, the owner's name and other information about the public key owner.

引用自 What is certificate authority (CA)? - Definition from WhatIs.com

获取 CA 证书

比较有名的 CA 证书列表由 mozilla 维护,curl 提供了命令行工具 mk-ca-bundle.pl ,用于下载 mozilla 维护的 CA 证书列表,转换成 SSL 应用程序可直接使用的格式。

linux 系统的 CA 证书由操作系统发行版负责维护,没有统一的标准规定如何维护和管理 CA 证书。

Archlinux 的 CA 证书由 ca-certificates 包维护,CA 证书来自依赖的包 ca-certificates-mozillaca-certificates-cacert

$ pacman -Qi ca-certificates
Name            : ca-certificates
Version         : 20150402-1
Description     : Common CA certificates (default providers)
Architecture    : any
URL             : http://pkgs.fedoraproject.org/cgit/ca-certificates.git
Licenses        : GPL2
Groups          : None
Provides        : None
Depends On      : ca-certificates-mozilla  ca-certificates-cacert
Optional Deps   : None
Required By     : curl  glib-networking  mono  neon  perl-lwp-protocol-https  qt4
Optional For    : lib32-openssl  openssl  wget
Conflicts With  : None
Replaces        : None
Installed Size  : 1024.00 B
Packager        : Jan Alexander Steffens (heftig) <jan.steffens@gmail.com>
Build Date      : 2015年04月03日 星期五 04时36分52秒
Install Date    : 2015年04月13日 星期一 16时04分37秒
Install Reason  : Installed as a dependency for another package
Install Script  : No
Validated By    : Signature
$ pacman -Ql ca-certificates
$ pacman -Ql ca-certificates-cacert
ca-certificates-cacert /usr/
ca-certificates-cacert /usr/share/
ca-certificates-cacert /usr/share/ca-certificates/
ca-certificates-cacert /usr/share/ca-certificates/trust-source/
ca-certificates-cacert /usr/share/ca-certificates/trust-source/anchors/
ca-certificates-cacert /usr/share/ca-certificates/trust-source/anchors/CAcert.org_class3.crt
ca-certificates-cacert /usr/share/ca-certificates/trust-source/anchors/CAcert.org_root.crt
ca-certificates-cacert /usr/share/licenses/
ca-certificates-cacert /usr/share/licenses/ca-certificates-cacert/
ca-certificates-cacert /usr/share/licenses/ca-certificates-cacert/LICENSE
$ pacman -Ql ca-certificates-mozilla
ca-certificates-mozilla /usr/
ca-certificates-mozilla /usr/share/
ca-certificates-mozilla /usr/share/ca-certificates/
ca-certificates-mozilla /usr/share/ca-certificates/trust-source/
ca-certificates-mozilla /usr/share/ca-certificates/trust-source/mozilla.neutral-trust.crt
ca-certificates-mozilla /usr/share/ca-certificates/trust-source/mozilla.supplement.p11-kit
ca-certificates-mozilla /usr/share/ca-certificates/trust-source/mozilla.trust.crt

拷贝 Archlinux 的 CA 证书文件 /etc/ssl/certs/ca-certificates.crt 到嵌入式 linux 设备, curl 编译时需要通过 --with-ca-bundle 指定默认的 CA 证书文件,运行时通过 --cacert 选项指定

# curl https://www.google.com --cacert /etc/ssl/certs/ca-certificates.crt
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="https://www.google.com.hk/?gfe_rd=cr&amp;ei=LoDmVuXlB9TC8gecrZv4DA">here</A>.
</BODY></HTML>

更新 CA 证书

使用 openwrt 的嵌入式设备

可以通过 opkg 进行安装和更新 CA 证书文件

opkg install ca-certificates
opkg upgrade ca-certificates

使用 linux 的嵌入式设备

如果没有软件包管理器,可以从 linux 服务器上定时下载最新的 CA 证书文件。

linux 服务器上的 CA 证书文件可以通过两种方式更新

  • 更新 ca-certificates 软件包

    CentOS 6.4

    yum update ca-certificates
    

    CentOS 6.4 的 CA 证书文件 /etc/pki/tls/certs/ca-bundle.crt

  • mk-ca-bundle.pl 脚本生成最新的 CA 证书文件

    该脚本生成的 CA 证书文件包含 mozilla 维护的证书

    mk-ca-bundle.pl -q ca-bundle.crt