基于 Let’s Encrypt 开启 HTTPS

HTTPS 目前已经是大多数成熟网站的标配,它通过在浏览器与网站之间建立加密信道来保证数据交换的隐私与完整性。

证书入门

HTTPS 建立过程不在这里展开讲,在网上能搜到大量相关论文,后面有机会再作分享。核心的逻辑是,通过 非对称加密算法 交换密钥,然后通过 对称加密 完成数据加密传输。为什么是这样?原因很简单,对称加密的计算效率远远高于非对称加密,是出于性能的考虑。

我们知道非对称加密有一对公钥/私钥,私钥只能自己掌握,公钥对外公开。

  • 私钥加密的内容只有公钥能解开,这个特性可用于 数字签名,做数据完整性验证。例如我用我的私钥对一份文件进行签名,张三用我的公钥可以对签名进行验证,如果验证成功则表示该文件没有被篡改。
  • 公钥加密的内容只有私钥能解开,这个特性可用于数据加密传输。例如我要向张三传输一份绝密文件,就可以使用张三的公钥加密后进行传输,除了张三之外任何人都无法解密这份文件,即使中间窃取了内容也无可奈何。

既然公钥是公开的,那这里就存在一个难题:如何确保公钥真的就是张三的?会不会是攻击者李四欺骗大家,宣称自己是张三?

大家看过《三体》,知道猜疑链,两个参与者之间不可能达成直接的信任!这时候就引入了大家都信任的第三方,由第三方来证明公钥就是张三的。这个第三方机构就是 数字证书认证机构(Certificate Authority,缩写为CA),她所颁发的证明文件就是 CA 证书。

CA 中心必须是公信力足够强的机构,不会造假,这是大家相互信任的基石。所以浏览器里面内置了很多公信力被认可的机构,只有这些机构签发的证书才可用于建立受信任的安全通道,否则浏览器会发出安全警告。同时,我们也会看到,经常有一些 CA 机构因违反了规定被浏览器移出信任列表,例如国内某知名证书认证机构就因未经认证为域名颁发证书而被吊销信任。

SSL 证书类型

根据不同的验证级别,分为

  • DV (Domain validated) Certificates,只验证域名的所有权,一般用于个人网站、小型网站。
  • OV (Organization validated) Certificates,除了验证 DV 所需要的信息外,还需要验证组织相关的信息,详见 The information required for OV certificates。这类证书会包含组织名称,一般用于公司、政府、其他想要提升信任级别的实体。
  • EV (Extended validation) Certificates,比 OV 更高的验证级别,需要更严苛的认证信息,详见 EV SSL Requirements。这类证书认证的域名,浏览器会在地址栏用绿色显示其公司名,以表达强力的信任程度,如下所示。
    EV Domain

更多信息,可参考:DV OV and EV Certificates

Let’s Encrypt

Let’s Encrypt 是国际上著名的免费 CA 认证中心,提供开放的、自动化的认证服务。

部署

如果有服务器 Shell 访问权限,可使用 Certbot 完成自动化部署。
如果没有服务器 Shell 访问权限,请参考 官方指南

Certbot

Certbot 是由 电子前沿基金会,The Electronic Frontier Foundation - EFFACME 协议 为基础开发的 SSL/TLS 证书自动获取和部署工具。

通过 Certbot 官网选择操作系统和 Web Server 软件,获取对应的部署指南。以 CentOS 7 + Nginx 为例,见 https://certbot.eff.org/lets-encrypt/centosrhel7-nginx.

安装 Certbot

1
2
3
yum -y install yum-utils
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
sudo yum install python2-certbot-nginx

部署证书

1
sudo certbot --nginx

这个命令会自动获取证书,并修改 Nginx 配置文件。
Certbot-Nginx

如果你只想获取证书,然后手动配置 Nginx,可以加上 certonly 参数。

1
sudo certbot --nginx certonly

如果想使用通配符证书,需要用到 Certbot’s DNS plugins,详细用法参考 官方指南

更新证书

CA 证书是有有效期的,Let’s Encrypt 的证书有效期为 3 个月,到期后需要更新,否则浏览器会对 HTTPS 进行安全警告。
通过执行以下命令,完成证书的更新。

1
sudo certbot renew

如果怕忘记,可以配置一个 crontab 定时任务,自动完成检查和更新。

1
0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew