美文网首页程序员
一文解剖ubuntu,curl,openssl更新根证书的细节

一文解剖ubuntu,curl,openssl更新根证书的细节

作者: 虞大胆的叽叽喳喳 | 来源:发表于2018-07-28 06:50 被阅读27次

    《apt,curl,openssl之间的那点事》《yum,curl,nss之间的那点事》这两篇文章中,介绍了以下几个主题:

    • 在 CentOS、Ubuntu 操作系统中,Curl 分别使用 OpenSSL、NSS 密码学库。
    • 在 CentOS、Ubuntu 操作系统中,Yum 和 APT 给 Curl 安装了那些依赖包。
    • 了解 Curl 发送 HTTPS 请求的一些细节。

    但有一个关键主题一直没说,那就是 Curl 请求 HTTPS 网站的时候,需要使用本地的 CA 根 证书来校验网站的身份,那根证书由谁提供?证书在哪儿?有些同学说,这不废话吗?肯定由 OpenSSL 或 NSS 提供。实际上不同平台、不同密码学库、不同的应用软件,使用的 CA 根证书是有一定区别的。

    所以接下去的两篇文章介绍 Curl(实际上是 OpenSSL 和 NSS)和 CA 根 证书的一些关系。为了更清楚的描述,本文讲解在 Ubuntu 下,Curl(密码库使用的是 OpenSSL)是如何引用根证书的。

    顺藤摸瓜找到 ca-certificates

    《apt,curl,openssl之间的那点事》这篇文章中讲到,在 Ubuntu 下,安装 Curl 包的时候会额外安装一个包 ca-certificates,这个包和证书有关,实际上这个包由 OpenSSL 安装的,如下:

    $ apt-cache depends openssl 
     
    openssl
      依赖: libc6
      依赖: libssl1.0.0
      建议: ca-certificates
      冲突: openssl:i386
    

    因为 Curl 是通过 OpenSSL 实现客户端 HTTPS 协议的,也就是说在 Curl/OpenSSL 平台下,Curl 使用的根证书库都是由 ca-certificates 包处理。

    在介绍 ca-certificates 包之前,让我们了解在 Ubuntu/Curl(包括 openssl s_client 工具)在发送 HTTPS 请求的时候,其引用的根证书地址,见下图:

    curl -v

    根证书库 CAfile: /etc/ssl/certs/ca-certificates.crt,让我们记住这一个文件,该文件是由 ca-certificates 包更新的。

    深究 ca-certificates

    运行如下命令了解 ca-certificates 包的详细信息:

    $ apt-cache show ca-certificates
    

    This package includes PEM files of CA certificates to allow SSL-based applications to check for the authenticity of SSL connections.

    It includes, among others, certificate authorities used by the Debian infrastructure and those shipped with Mozilla's browsers.

    也就是说这个包含了 PEM 格式的 CA 根证书,这些证书可以供基于 SSL 协议的引用程序使用,所有的 CA 根证书实际上是由 Mozilla 维护的。

    接下去运行下列命令,了解下 ca-certificates 包含的文件:

    $ dpkg  -L ca-certificates
    

    主要包含二种类型的文件:

    (1)/usr/share/ca-certificates/mozilla/

    包含很多具体的 CA 根证书文件,每个 CA 机构的根证书对应一个文件。

    (2)/usr/sbin/update-ca-certificates

    这是一个命令行工具,作用是什么?运行如下命令了解官方说明:

    $ man update-ca-certificates 
    

    update-ca-certificates - update /etc/ssl/certs and certificates.crt

    直白的说,运行这个工具,它最终会更新 /etc/ssl/certs/ca-certificates.crt 文件。这下你应该明白了,有了这个文件,不管是 Curl 还是 openssl 在发送 HTTPS 请求的时候,都可以校验 HTTPS 网站的真实身份了。

    具体执行步骤如下:

    • 读取 /etc/ca-certificates.conf 文件,包含的内容就是所有 /usr/share/ca-certificates/mozilla/ 目录下的证书文件名。
    • 将 /etc/ca-certificates.conf 文件对应的所有证书合并到 /etc/ssl/certs/ca-certificates.crt 文件中。

    如何及时更新 CA 根证书

    ca-certificates 包使用的 CA 根证书来自于 Mozilla,但对于一个发行版来说,升级和更新包的频率并不高。

    思考一个情况,Mozilla 新引入了一个 CA,或者不信任一个 CA,也就是说对于 Mozilla 来说,其 CA 根证书列表发生了更新。其他使用 Mozilla CA 根证书的应用程序(包括 ca-certificates)可能无法做到及时更新,有没有办法及时更新本地的 CA 根证书呢?

    可以使用 mk-ca-bundle.pl 工具,它是 Curl 工程发布的,Mozilla 将自己所信任的 CA 根证书全部存入 https://hg.mozilla.org/projects/nss/raw-file/default/lib/ckfw/builtins/certdata.txt 文件中(很少有应用程序直接使用 NSS cert9.db 文件)。

    而 mk-ca-bundle.pl 要做的就是将 certdata.txt 转换为 PEM 格式,然后供 Curl(或者其他应用程序)使用。

    $ wget https://raw.githubusercontent.com/curl/curl/master/lib/mk-ca-bundle.pl  
    
    $ chmod 0777 mk-ca-bundle.pl
    
    $ ./mk-ca-bundle.pl
    
    $cp ca-bundle.crt /etc/ssl/certs/ca-certificates.crt -fr 
    

    运行结束后,/etc/ssl/certs/ca-certificates.crt 就更新了,Curl 就能使用最新的根 CA 证书了。

    细心的同学可能会发现,mk-ca-bundle.pl 工具没有自动在 /usr/share/ca-certificates/mozilla/ 目录下更新证书,自然 update-ca-certificates 工具也不能更新了。

    后续我打算写一个工具解决该问题:

    • 基于 mk-ca-bundle.pl,将证书同步到 /usr/share/ca-certificates/mozilla/ 目录。
    • 然后使用 update-ca-certificates 更新最新的证书。

    在我的新书《深入浅出HTTPS:从原理到实战》 也描述了更新证书的问题,但描述的有点误差(P214 页),所以这篇文章也正好做了修正。

    可能很多同学很奇怪,为什么我最近写了很多 curl、nss 相关方面的文章?原因在于这些主题在我的新书《深入浅出HTTPS:从原理到实战》中描述的不多,也不系统,而这些主题同学们在工作、学习过程中有很大几率会用到,所以系统性的做一些介绍。

    相关系列文章:


    我最近写了一本书《深入浅出HTTPS:从原理到实战》,欢迎去各大电商购买,也欢迎关注我的公众号(yudadanwx,虞大胆的叽叽喳喳),了解我最新的博文和本书。

    公众号二维码

    相关文章

      网友评论

        本文标题:一文解剖ubuntu,curl,openssl更新根证书的细节

        本文链接:https://www.haomeiwen.com/subject/brbnmftx.html