您现在的位置是:首页 >其他 >CIAA 网络安全模型 — TLS v1.3 和 HTTPS 协议网站首页其他

CIAA 网络安全模型 — TLS v1.3 和 HTTPS 协议

范桂飓 2024-06-14 17:20:17
简介CIAA 网络安全模型 — TLS v1.3 和 HTTPS 协议

目录

SSL/TLS

SSL(Secure Sockets Layer,安全套接层)协议最初由 Netscape(网景公司)在 1994 年设计并开发,为了给 HTTP 提供一个安全的传输层。

到 1999 年,因为 SSL 应用广泛,已经成为 Internet 上的事实标准。所以 IETF(Internet Engineering Task Force,互联网工程任务组)在 SSL 的基础上将其标准化为 TLS(Transport Layer Security,传输层安全协议)协议。

目前,我们最常见的是 TLS v1.2 版本,而最新的 v1.3(2018 年,RFC8446)版本有望成为有史以来最安全,但也最复杂的 TLS 协议。

在这里插入图片描述

TLS 1.2

TLS 协议是 CIAA 网络安全模型的具体实现,基于混合加密方案和 PKI/CA 数字证书技术制定了一套安全通信协议标准,所以理解 TLS 协议之前需要先对 CIAA 安全模型有一定的认识。

TLS 主要由 2 个部分组成:

  1. TLS 记录数据(TLS Record):是一种数据结构,用于将应用层协议的数据分割成多个 TLS Records。数据结构的概览如下图所示:
    在这里插入图片描述

  2. TLS 握手协议(TLS Handshake):是一种协议,用于在 TLS 通信的初始阶段进行身份验证和协商安全参数。协议处理流程如下图所示:
    在这里插入图片描述

协议交互抓包示例如下图所示:
在这里插入图片描述

1. client_hello

当 TCP 连接建立后,TLS 握手的第一步由 Client 发起,发送 ClientHello Msg 到 Server。

Client Hello Msg 包含以下内容

  1. Client 支持的 TLS 版本。
  2. Client 支持的 Cipher Suites(加密套件候选列表)。
  3. Compression Methods(压缩算法候选列表)。
  4. Extensions(扩展字段)。
  5. Client Random(随机数),用于后续的对称密钥协商。
  6. 可选的 Session ID,用于支持 TLS 会话恢复。如果提供了,那么 Server 会复用对应的握手信息,避免短时间内重复握手。

2. server_hello + server_certificate + sever_hello_done

Server 收到了 ClientHello Msg 后,比对 Server 支持的 TLS 版本和 Cipher Suites,然会回复 ServerHello Msg,以此来完成 Cipher Suites 协商阶段。

Server Hello Msg 包含以下内容

  1. Server 所能支持的最高 TLS 版本。
  2. Server 选择使用的 Cipher Suites(加密套件)。例如:Nginx 的 ssl_ciphers HIGH:!aNULL:!MD5; 配置项。
  3. Server 选择使用的 Compression Method(压缩算法)。
  4. Server Random(随机数),用于后续的对称密钥协商。
  5. 可选的 Session ID,用于支持 TLS 会话恢复。如果提供了,则 Client 会复用当前握手的信息,避免短时间内重复握手。

可选的 Session ID 会话恢复,是指在一次完整协商的连接断开时,Client 和 Server 都会将 TLS Session 协商的安全参数保留一段时间,用于后续的会话恢复,起到类似 Cache 的功能。希望恢复会话的 Client 需要将相应的 Session ID 放入 Client Hello Msg 发出。如果 Server 愿意恢复会话,则将相同的 Session ID 放入 Server Hello Msg 返回。

Server Certificate Msg 包含以下内容

  1. Server 的 CA 证书,该证书由 CA 签发,是一个由 CA 背书的 Server “公钥“。
  2. 在双向安全认证场景中,Client 也需要提供它的 CA 证书,还需要包含 Client Certificate Request(客户端证书请求)。

Server Hello Done Msg:向 Client 发送 Server Hello Done 表示 Hello 协商阶段完成。

3. Certificate authentication

Client 收到 Server Hello Msg 后,会对收到的 Server CA 证书进行合法性验证。只有通过验证才会进行后续通信,否则根据错误情况不同做出提示和操作,合法性验证的内容包括:

  1. Trusted Certificate Path(证书链的可信性)
  2. Revocation(证书是否已经吊销):有 2 种方式:离线 CRL 验证、在线 OCSP 验证。不同的 Client 会采用不同的方式。
  3. Expiry Date(有效期):证书是否在有效时间范围内。
  4. Domain(域名):核查证书域名是否与当前的访问域名匹配。

4. client_key_exchange + change_cipher_spec + encrypted_handshake_message

Client 完成了 Server CA 证书的合法性验证之后,就可以从 Server CA 证书中得到了 Server Public Key,继而开始非对称加密行为。具体采用的非对称加密算法由 Server 选择的 Cipher Suites 决定,例如:ECDHE。

Client Key Exchange Msg:内含了 Client 本地运算生成的 Pre-Master 随机数,并用 Server Public Key 加密,然后发送给 Server,再由 Server Private Key 解密。

此时,Client 就获得了混合加密方案所需要的全部通信密钥信息,包括:

  1. 在 C/S 协商阶段获得的 2 个明文随机数 random_C 和 random_S。
  2. Client 自己生成的加密 Pre-Master 随机数。
  3. 用于对称加密的 Master Secret 对称密钥,Client 通过 Fuc(random_C, random_S, Pre-Master) 计算得到。使用 3 个随机数来计算,一方面为了防止 “random_C” 被中间人猜出,另一方也增加 Master Secret 的随机性。
  4. 用于非对称加密的 Server Public Key。

Change Cipher Spec Msg:Client 通知 Server 后续的通信都采用协商的通信密钥和加密算法进行加密通信。

Encrypted Handshake Msg / Finished Msg:TLS v1.2 采用了 MAC(Message authentication code,消息认证码)来确保 Handshake 流程未被篡改。具体的行为是:对 Client 之前已经发送过的所有 Msgs,再次使用协商好的 Master Secret 对称密钥进行 HASH 计算得到数字摘要,最后发送给 Server 用于最后的安全握手验证。

5. change_cipher_spec + encrypted_handshake_message

Server 收到 Client Key Exchange Msg 后,使用 Server Private Key 解密得到 Client 的 Pre-Master 随机数,并基于之前交换的两个明文随机数 random_C 和 random_S,同样可以计算出协商 Master Secret 对称密钥。

Server 收到 Encrypted Handshake Msg 后,同样通过协商好的加密算法进行解密,然后再对 Server 收到的所有 Msgs 使用同样的 Master Secret 对称密钥进行一次数字摘要计算。

最后通过对比数据签名,来最终验证数据的完整性。如果失败,则触发致命的 Alert 异常:Bad Record MAC(Message authentication code,消息认证码),表示安全通道建立过程中有恶意篡改行为。

Change Cipher Spec Msg:验证通过之后,Server 同样发送该消息以告知 Client 后续的通信都采用协商的通信密钥与算法进行加密通信。

Encrypted Handshake Msg / Finished Msg:Server 也会以同样的方式计算出数字签名并发送给 Client。

至此,Client 和 Server 双方都拥有了合法的 Master Secret 对成密钥,接下来进入到业务数据的对称加密安全传输阶段。整个过程通常需要几百毫秒。

TLS 1.3

相对于 TLS v1.2 而言,v1.3 是迄今为止最大的一次改动,主要的改进目的如下:

  1. 更强的安全性:进一步加密握手流程、改善跨协议攻击的弹性、删除不安全的加密算法。
  2. 更快的访问速度:减少握手等待时间。

引入的新特性如下:

  1. 引入了新的 PSK 密钥协商机制。
  2. 支持 0-RTT 数据传输,在建立连接时节省了往返时间。
  3. 废弃了过时的 3DES、RC4、AES-CBC 等加密组件,以及 SHA1、MD5 等哈希算法。
  4. 对 Server Hello Msg 之后的所有握手消息采取了加密操作,可见明文大大减少。
  5. 不再允许对加密报文进行压缩、不再允许双方发起重协商。
  6. DSA 证书不再允许使用。

目前最新的 Chrome 和 Firefox 都已支持 TLS 1.3,但需要手动开启。下面是各大浏览器的 TLS 1.3 支持情况:

在这里插入图片描述

测试网站是否开启了 TLS 1.3:

$ git clone --depth 1 https://github.com/drwetter/testssl.sh.git
$ cd testssl.sh
$ ./testssl.sh -p <domainName>

Testing protocols via sockets except NPN+ALPN

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      offered
 TLS 1.1    offered
 TLS 1.2    offered (OK)
 TLS 1.3    offered (OK): draft 28, draft 27, draft 26
 NPN/SPDY   h2, spdy/3.1, http/1.1 (advertised)
 ALPN/HTTP2 h2, spdy/3.1, http/1.1 (offered)

更强的安全性

加密了整个 TLS Handshake 握手流程

TLS v1.2 中的 Handshake 流程并没有实现完全加密,协商加密算法类型和随机数阶段、以及握手结束(Encrypted Handshake Msg / Finished Msg)都是明文的,通过对称 MAC(Message authentication code,消息认证码)来确保握手未被篡改。

这种疏忽导致了许多备受瞩目的安全漏洞(e.g. FREAK、LogJam etc.),所以在 TLS v1.3 中,会对整个握手进行非对称加密。

在这里插入图片描述

以最简单的 FREAK 攻击为例,它利用了以下 2 个漏洞:

  1. 许多浏览器和服务器仍然支持 20 世纪 90 年代的弱密码(称为 Export 密码)。
  2. TLS v1.2 用于协商使用哪种加密算法的握手部分没有加密。

使得 FREAK 中间人可以篡改 Client 和 Server 最终选用的 Supported ciphers(加密套件),让双方都降级了加密强度(HIGH => LOW => EXPORT)。然后中间人就可以暴力破解 Encrypted Handshake Message 得到 3 个随机数,并计算出 Master Secret 对称密钥信息 ,最终就可以伪造了彼此的 Finished Message,即 MAC 值。如下图所示。

在这里插入图片描述

在 TLS v1.3 中,这种类型的安全降级攻击是不可能的,因为整个握手流程都进行了加密,同时 v1.3 还删除了那些不安全的加密算法,包括:

  • RSA 密钥传输:不支持前向安全性。
  • CBC 模式密码:易受 BEAST 和 Lucky 13 攻击。
  • RC4 流密码:在 HTTPS 中使用并不安全。
  • SHA-1 哈希函数:建议以 SHA-2 取而代之。
  • 任意 Diffie-Hellman 组:CVE-2016-0701 漏洞。
  • 输出密码:易受 FREAK 和 LogJam 攻击。
  • 等等。

使用支持向前保密的临时 Diffie-Hellman 替代 RSA 加密算法

RSA 非对称加密算法是由 Rivest,Shamir 和 Adelman 在 1977 年发现的,一直都被视为是密码学领域的重大成就之一。但现在看来,RSA 存在不满足前向保密(Forward Secret)的严重缺陷。即:如果中间人记录存储了加密对话数据,后面假如某一天中间人通过 Heartbleed(心脏出血)之类的技术窃取了 Server 的 RSA Private Key,那么中间人依然可以将对话解密。

在这里插入图片描述

因此,TLS 1.3 移除了 RSA,而仅采用了临时 Diffie-Hellman 作为唯一的秘钥交换机制。

临时 Diffie-Hellman 由 Diffie 和 Hellman 在 1976 年发明,要求 Client 和 Server 都创建一对非对称密钥,并且都交换彼此的 Public Key,一旦收到了对方的 Public Key,那么就会与自己的 Private Key 进行组合,最后以相同的 Pre-Master Secret 值作为结尾。

所谓 “临时”,指的是在每个 TLS 会话中,协商密钥所使用的 Pre-Master Secret 参数都是临时生成的,可以实现每个会话的密钥唯一。因此,即使在以后的时间里,攻击者获得了以前的临时密钥,也无法利用这些密钥来破解之前或之后的会话。即使一个密钥被泄漏,也不会影响其他会话的安全性。

在这里插入图片描述

更快的访问速度

在 Web 领域,传输延迟(Transmission Latency)是重要的性能指标之一,低延迟意味着更流畅的页面加载以及更快的 API 响应速度。而一个完整的 HTTPS 连接的建立大概需要以下 4 步:

  1. DNS 查询
  2. TCP 握手(1 RTT)
  3. TLS v1.2 握手 (2 RTT)
  4. 建立 HTTP 连接(1 RTT)

可见在 TLS v1.2 中,新建一个完整的 HTTPS 连接最少需要 4 个 RTT(Round-Trip Time 往返时延),而重连则可以通过 TLS 的会话恢复机制节省 1 个 RTT。

  • TLS v1.2 新建连接握手流程:
    在这里插入图片描述
  • TLS v1.2 会话恢复流程(指定了 Hello Msg 的 Session ID):
    在这里插入图片描述

在 TLS v1.3 中,由于仅支持向前保密的临时 Diffie-Hellman 对称加密算法,所以 Client 可以在一条 Msg 中就完成 Diffie-Hellman 密钥共享,即:只需要一次往返( 1-RTT )就可以完成握手。

  • TLS v1.3 新建连接握手流程:
    在这里插入图片描述

另外,TLS v1.3 在会话恢复时,Client 会将 Server 发送过来的 Session Ticket 进行计算,组成一个新的 PSK (PreSharedKey,预共享密钥)。Client 将 PSK 缓存在本地。会话恢复时,在 Client Hello Msg 带上 PSK 扩展,同时通过之前 Client 发送的 Finished Msg 计算出 Resumption Secret(恢复密钥)。通过该密钥加密数据发送给 Server,然后 Server 就会从 Session Ticket 中算出 PSK,使用它来解密刚才发过来的加密数据。至此完成了该 0-RTT 会话恢复的过程。

  • TLS v1.3 0-RTT 会话恢复流程:
    在这里插入图片描述

升级 OpenSSL 1.1.1 支持 TLS 1.3

并非所有的 Client 和 Server 都支持相同版本的 TLS,因此大多数 Server 都会同时支持多个版本,并且进行协商。TLS 的版本协商非常简单。Client 会通知 Server 它支持的协议的最新版本,Server 则会回复支持的协议版本,如果存在交集则协商成功。否则,连接失败。虽然版本协商的过程很简单,但事实证明,很多连接场景并未能正确地实现这一功能,从而导致安全事故。

OpenSSL 最新的 1.1.1 版本提供了 TLS 1.3 的支持,而且和 1.1.0 版本完全兼容。在特定的 Linux 发行版中,可能需要手动安装。

以 CentOS7 为例,检查是否开启了 TLS 1.3:

$ openssl s_client --help | grep tls1_3

如果没有,则需要手动安装:

  1. 下载 OpenSSL 1.1.1 版本
$ cd /opt
$ wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1-stable.zip
$ unzip OpenSSL_1_1_1-stable.zip
  1. 编译安装
$ ./config enable-tls1_3 --prefix=/usr/local/openssl
$ make && make install
  1. 配置
$ mv /usr/bin/openssl /usr/bin/openssl.old
$ mv /usr/lib64/openssl /usr/lib64/openssl.old
$ mv /usr/lib64/libssl.so /usr/lib64/libssl.so.old
$ ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
$ ln -s /usr/local/openssl/include/openssl /usr/include/openssl
$ ln -s /usr/local/openssl/lib/libssl.so /usr/lib64/libssl.so
$ echo "/usr/local/openssl/lib" >> /etc/ld.so.conf
$ ldconfig -v 
  1. 查看版本并验证
$ openssl version
$ openssl s_client --help | grep tls1_3

HTTPS

HTTPS 就是 HTTP 与 TLS 的组合,本质为 HTTP over SSL/TLS。在以往的文章中,我们已经分别介绍了 HTTP 和 TLS 协议,所以在这里主要关注 HTTPS 的 2 种安全认证方式,并梳理 HTTPS 连接建立流程。

在这里插入图片描述

HTTPS 单向认证

在这里插入图片描述

  1. Client 向 Server 发送 TLS 协议版本号、加密算法种类、随机数等信息。
  2. Server 给 Client 返回 TLS 协议版本号、加密算法种类、随机数等信息,同时也返回 Server 的 CA 证书。
  3. Client 使用 Server 返回的信息验证 CA 证书的合法性,包括:
    • 证书是否过期。
    • 签发证书的 CA 机构是否可靠。
    • 安装的 CA 公钥证书是否能正确解开 CA 证书并返回数字签名。
    • CA 证书上的 DN(域名)是否和 Server 的实际域名相匹配。
    • 验证通过后,将继续进行通信,否则,终止通信。
  4. Client 向 Server 发送自己所能支持的对称加密算法,供 Server 进行选择。
  5. Server 端在 Client 提供的加密方案中选择加密程度最高的方式。
  6. Server 将选择好的加密方案通过明文方式返回给 Client。
  7. Client 接收到 Server 返回的加密方式后,使用该加密方式生成产生 Pre-Master 随机码,使用 Server Public Key 进行加密,并发送至 Server。
  8. Server 收到 Client 发来的加密信息后,使用自己的 Private Key 进行解密,获取 Pre-Master 随机码,并计算出 Master 对称密钥。
  9. 在接下来的会话中,Server 和 Client 将会使用 Master 对称密钥进行对称加密,保证通信过程中信息的安全。

HTTPS 双向认证

双向认证和单向认证类似,主要是额外增加了 Server 对 Client 的认证。如下图红色部分。

在这里插入图片描述

TLS 的 SNI 扩展

SNI

早期的 SSLv2 根据经典的 PKI 标准进行设计,它默认认为一台 HTTP Server(或者说一个 IP 地址)只会提供一个服务(只有一个 Domain Name),所以在 SSL 握手时,Client 无需指明具体的 Domain Name,Server 就会把默认的 CA 证书返回。

然而在 Apache 等 HTTP Server 中应用了 VirtualHosts 之后,就出现了一个 IP 会对应多个 Domain Name 的情况。为了支持 VirtualHosts,HTTP/1.1 Header 协议增加了 Host 字段,相应的 TLS 也需要类似的手段,否则会出现 “公共名称不匹配错误(Unable to communicate securely with peer: requested domain name does not match the server’s certificate.)”。即:虽然 Client 到达了 HTTP Server 的正确 IP 地址,但由于 CA 证书上的 Domain Name 与 Web 的 Domain Name 不匹配导致无法建立安全连接。

为了解决这个问题,TLS 在 v1.0 版本中增加了 SNI(Server Name Indication,服务器名称指示,RFC 4366)扩展,它包含在 TLS Hello 握手流程中,以确保 Client 能够指定要访问的 Domain Name。举例来说,假设:网站 https://www.example.com、https://www.something.com、https://www.another-website.com、https://www.example.io 被托管在相同的 HTTP Server 中,通过基于 Hostname 的 VirtualHosts 对外提供服务。此时。,如果 TLS 的 SNI 扩展指定为 https://www.example.com,那么 HTTP Server 就会返回 https://www.example.com 的 CA 证书,继而建立正确的安全连接。

  • 发出 SNI:
SSLKEYLOGFILE=ssl_log.txt curl 
--cacert ~/ca_01.pem 
--resolve www.app1.com:443:172.18.22.68 
-X GET "https://www.app1.com:443/" 
-H 'Content-type: application/json' 
-H 'Accept: application/json' 
-H 'host: www.app1.com'
  • 抓包示例:
    在这里插入图片描述

  • Client Hello 的 SNI Extensions:
    在这里插入图片描述

ESNI(加密的 SNI)

SNI 作为 TLS Client Hello Msg 的 扩展字段,这意味着在 TLS v1.2 中,SNI 是明文的。也就是说,任何监视 Client 和 Server 之间连接的攻击者都可以读取到 SNI 信息,并以此了解到 Client 正在与哪个 Domain Name 建立 HTTPS 连接,即便攻击者无法解密进一步的通信内容,但攻击者仍然可以利用 SNI 信息,例如:建立一个钓鱼网站来欺骗用户。

由此,就提出了 ESNI(加密的 SNI),通过加密 client_hello 消息的 SNI 部分(仅此部分),来保护 SNI 的私密性,确保攻击者无法监视到 SNI 明文信息。另外,ESNI 的加密密钥必须以其他方式进行传输。

具体而言,HTTP Server 会在其 DNS 记录中添加一个用于 ESNI 的 Public Key。这样,当 Client 查找到正确的 HTTP Server IP 地址时,同时也能得到对应的 Public Key。

例如:当用户在浏览器中输入 URL:https://www.bobisawesome.example.com 时,浏览器将通过以下流程加载网站:

  1. 浏览器向 DNS Server 发送 Domain Name 查询,以查询 HTTP Server 的 IP 地址。
  2. DNS 响应 HTTP Server IP 地址以及 ESNI Public Key。
  3. 浏览器向指定的 IP 地址发送 TLS client_hello 消息,并使用 ESNI Public Key 对 SNI 部分进行加密。
  4. HTTP Server 根据 SNI 指示返回指定的 CA 证书。
  5. TLS 握手继续进行。

但需要注意的是,即表如此 ESNI 也并非是绝对安全的,因为常规的 DNS 通信未加密,存在 “地址簿伪装“ 攻击风险。即使安装了 ESNI,攻击者仍然可以查看用户正在查询的 DNS 记录,并确定他们正在访问哪些网站。

所以更进一步的,还可能需要安全的 DNS 方案,常见的有:

  • 基于 TLS 的 DNS;
  • 基于 HTTPS 的 DNS;
  • DNSSEC;
  • 等等

升级 curl 支持 HTTP2 与 TLS 1.3

编译安装

安装编译环境:

$ yum -y groupinstall "Development Tools"
$ yum -y install libev libev-devel zlib zlib-devel openssl openssl-devel git

安装 OpenSSL:

$ mkdir /var/tmp
$ cd /var/tmp
$ wget https://openssl.org/source/openssl-1.0.2.tar.gz
$ tar -zxf openssl-1.0.2.tar.gz
$ cd openssl-1.0.2
$ mkdir /opt/openssl
$ ./config --prefix=/opt/openssl
$ make
$ make test
$ make install

安装 nghttp2:

$ git clone https://github.com/tatsuhiro-t/nghttp2.git
$ cd nghttp2
$ autoreconf -i
$ automake
$ autoconf
$ ./configure
$ make
$ make install
$ echo '/usr/local/lib' > /etc/ld.so.conf.d/custom-libs.conf
$ ldconfig
$ ldconfig -p| grep libnghttp2

安装 curl:

$ cd /var/tmp
$ git clone https://github.com/bagder/curl.git
$ cd curl
$ ./buildconf
$ ./configure --with-ssl=/opt/openssl --with-nghttp2=/usr/local --disable-file --without-pic --disable-shared
$ make

验证:

$ /var/tmp/curl/src/curl --version
curl 7.70.0-DEV (x86_64-unknown-linux-gnu) libcurl/7.70.0-DEV OpenSSL/1.0.2o nghttp2/1.41.0-DEV
Release-Date: [unreleased]
Protocols: dict ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS HTTP2 HTTPS-proxy IPv6 Largefile NTLM NTLM_WB SSL TLS-SRP UnixSockets

curl 从 7.52.0 版本开始也已经支持 TLS 1.3 了,curl 7.61.0 及以上在 TLS 握手过程中协商 TLS 版本时,curl 默认使用 TLS 1.3,但也取决于 curl 正在使用的 TLS 库及其版本,例如:要求 OpenSSL 1.1.1 版本以上。

YUM 升级

安装新版 libcurl 的 yum 源:

$ rpm -ivh http://mirror.city-fan.org/ftp/contrib/yum-repo/city-fan.org-release-1-13.rhel6.noarch.rpm

升级:

$ yum upgrade libcurl

升级完成后可以卸载此 yum 源:

$ rpm -e city-fan.org-release

curl 常用选项

curl [options] [URL...]
  • -A/–user-agent <string>:设置用户代理发送给服务器。
  • -e/–referer <URL>:来源网址。
  • –cacert <file>:CA 证书(SSL)。
  • -k/–insecure:允许忽略证书进行 SSL 连接。
  • –compressed:要求返回是压缩的格式。
  • -H/–header <line>:自定义首部信息传递给服务器。
  • -i:显示页面内容,包括报文首部信息。
  • -I/–head:只显示响应报文首部信息。
  • -D/–dump-header <file>:将 URL 的 header 信息存放在指定文件中。
  • –basic:使用 HTTP 基本认证。
  • -u/–user <user[:password]>:设置服务器的用户和密码。
  • -L:如果有 3xx 响应码,重新发请求到新位置。
  • -O:使用 URL 中默认的文件名保存文件到本地。
  • -o <file>:将网络文件保存为指定的文件中。
  • –limit-rate <rate>:设置传输速度。
  • -0/–http1.0:数字 0,使用 HTTP 1.0。
  • -v/–verbose:更详细。
  • -C:选项可对文件使用断点续传功能。
  • -c/–cookie-jar <file name>:将 URL 中 Cookie 存放在指定文件中。
  • -x/–proxy <proxyhost[:port]>:指定代理服务器地址。
  • -X/–request <command>:向服务器发送指定请求方法。
  • -U/–proxy-user <user:password>:代理服务器用户和密码。
  • -T:选项可将指定的本地文件上传到 FTP 服务器上。
  • –data/-d:方式指定使用 POST 方式传递数据。
  • -b name=data:从服务器响应 set-cookie 得到值,返回给服务器。

curl 指令使用 SNI

由以上过程可以知道,没有 SNI 的情况下,服务器无法预知客户端到底请求的是哪一个域名的服务。SNI 的 TLS 扩展通过发送虚拟域名做为 TLS 协商的一部分修正了这个问题,在 Client Hello 阶段,通过 SNI 扩展,将域名信息提前告诉服务器,服务器根据域名取得对应的证书返回给客户端已完成校验过程。

curl 7.18.1+ & openssl 0.9.8j+ 的组合就可以支持 SNI 了:

curl 
--cacert /root/CA/nginx1.com/cacert.pem 
-X GET "https://webserver.com:8443/" 
-H 'Content-type: application/json' 
-H 'Accept: application/json' 
-H 'host: nginx1.com'

如果没有配置 DNS 解析的话可以使用 curl 7.21.3 支持的 --resolve 参数:

curl 
--cacert /root/CA/nginx1.com/cacert.pem 
--resolve webserver.com:8443:127.0.0.1 
-X GET "https://webserver.com:8443/" 
-H 'Content-type: application/json' 
-H 'Accept: application/json' 
-H 'host: nginx1.com'

–resolve 主要用于直接定位到 IP 地址进行访问,对于一个 Domain Name 有多个服务器(多个不同的 IP)的服务来说,这个参数可以指定的访问某个设备。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。