美文网首页Web开发程序员
apt,curl,openssl之间的那点事

apt,curl,openssl之间的那点事

作者: 虞大胆的叽叽喳喳 | 来源:发表于2018-07-20 20:53 被阅读126次

    Curl 可以说是非常流行的一个客户端网络请求工具,充分理解了 Curl,相当于熟练掌握了 HTTP/HTTPS 协议(也包括其他的应用层协议,比如 FTP、IMAP 等等)。

    一旦将 Curl 和 HTTPS 协议联系在一起,对于初学者来说,必然会思考以下几个问题:

    • Curl 是如何完成 HTTPS 协议交互的?
    • Curl 是基于 OpenSSL、Nss,还是其他密码学库实现的 HTTPS 功能?
    • 和浏览器一样,Curl 为校验证书,其依赖的根证书库位置在哪儿?
    • 使用包安装(apt或yum)和源代码安装 Curl 有什么区别?

    在我写的书《深入浅出HTTPS:从原理到实战》也描述了 Curl 和 HTTPS 的交互,但由于各方面原因,讲解的不是特别深入,所以打算写几篇相关的文章解释这些问题,这篇文章主要基于 Ubuntu(14.4 版本) 的 apt 包安装工具讲解 Curl 和 HTTPS 相关知识,如何你对 apt 包安装工具不熟悉,也可以借此篇文章学习。

    在 Ubuntu 下,为支持 HTTPS 协议,Curl 安装的时候默认使用的是 OpenSSL 密码库;在 CentOS 下,Curl 安装的时候默认使用的是 NSS 密码库。

    首先看看 curl 依赖于哪些包,执行如下命令:

    $ apt-cache depends  curl
    

    输出如下:

    curl
      依赖: libc6
      依赖: libcurl3
      依赖: zlib1g
      冲突: curl:i386
    

    依赖最重要的包就是 libcurl3,执行如下命令,看看 libcurl3 依赖什么包:

    $ apt-cache depends  libcurl3
    

    输出如下:

    libcurl3
      依赖: libc6
      依赖: libgssapi-krb5-2
      依赖: libidn11
      依赖: libldap-2.4-2
      依赖: librtmp0
    

    并没有看到 OpenSSL 的影子,难道 libcurl3 没有包含 OpenSSL 相关库?

    再仔细阅读 libcurl3 包的说明,执行下列命令:

    $ apt-cache show libcurl3
    

    结果见下图:

    libcurl3

    其中有两点重点关注:

    • Recommends: ca-certificates,推荐安装 ca-certificates 包,非常有用,后续我会专门描述。
    • SSL support is provided by OpenSSL,说明 libcurl3 的 SSL 功能确实由 OpenSSL 提供。

    那么为什么从 libcurl3 包中看不到 OpenSSL 的影子呢?让我们拿出 ldd 大法,执行下列命令:

    ldd /usr/bin/curl | grep ssl  
    

    关键输出如下:

    libssl.so.1.1 => /usr/lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007fd25e60a000)
    

    原来是 libcurl3 静态绑定了 libssl.so.1.1,这个包是 OpenSSL 提供的吗?通过两种方法验证。

    (1)查看包依赖关系

    $ apt-cache depends openssl 
    

    输出:

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

    可以看出 openssl 也依赖 libssl1.0.0。

    同时 libssl1.0.0 也提供给 libcurl3,可以执行下列命令进行确认:

    $ apt-cache rdepends  libssl1.0.0 | grep curl 
      libcurl3
    

    (2)通过 curl-config

    这个工具非常有用,官方介绍如下:

    curl-config - Get information about a libcurl installation

    也就是说,通过 apt 包安装 curl 虽然简单,但失去了解细节的乐趣(比如无法知晓编译了那些具体参数),而 curl-config 工具可以让你了解内幕。

    如果机器没有该工具,可以使用下列命令安装:

    $ apt-get install libcurl4-openssl-dev  
    $ dpkg -L libcurl4-openssl-dev 
    

    然后重点观察 apt 安装采用的 configure,执行如下命令:

    $ curl-config --configure
    

    输出如下:

     '--build=x86_64-linux-gnu' '--prefix=/usr' '--includedir=/usr/include' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc' '--localstatedir=/var' '--libdir=/usr/lib/x86_64-linux-gnu' '--libexecdir=/usr/lib/x86_64-linux-gnu' '--disable-maintainer-mode' '--disable-dependency-tracking' '--disable-symbol-hiding' '--enable-versioned-symbols' '--enable-threaded-resolver' '--with-lber-lib=lber' '--with-gssapi=/usr' '--with-ca-path=/etc/ssl/certs' 'build_alias=x86_64-linux-gnu' 'CFLAGS=-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security' 'LDFLAGS=-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed' 'CPPFLAGS=-D_FORTIFY_SOURCE=2'
    

    --with-ca-path 这个参数可以重点关注,curl 在校验服务器证书的时候,会使用该目录下的根证书库文件,在 Ubuntu 中,/etc/ssl/certs 是 OpenSSL 库配置的根证书库(是不是很想改为 NSS 可信任根证书库?后续文章我会描述)。

    上述命令并没有 ssl 包相关信息,可以执行下列命令查看静态编译的库:

    $ curl-config  --static-libs
    

    输出如下:

    /usr/lib/x86_64-linux-gnu/libcurl.a -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed -lidn -lrtmp -lssl -lcrypto -lssl -lcrypto -Wl,-Bsymbolic-functions -Wl,-z,relro -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -llber -llber -lldap -lz
    

    如果你没有安装 Curl,执行一条命令就能完成(前提你安装了 OpenSSL,Ubuntu 默认会安装):

    $ apt-get install curl
    

    看看 Curl 安装后的信息,执行如下命令:

    $ curl -V
    

    输出信息如下:

    curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.0g zlib/1.2.8 nghttp2/1.31.0-DEV
    Release-Date: 2018-01-24
    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 HTTP2 UnixSockets HTTPS-proxy 
    

    可见 curl 基于 libcurl/7.58.0 和 OpenSSL/1.1.0g。

    然后再执行下 curl https 请求命令:

    $ curl -v "https://www.baidu.com"
    

    输出信息如下图:

    curl -v

    重点关注的细节是 curl 使用的可信任根证书库 CAfile: /etc/ssl/certs/ca-certificates.crt。后续会重点讲解 Curl 使用的根证书库。


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

    公众号二维码

    相关文章

      网友评论

        本文标题:apt,curl,openssl之间的那点事

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