0x00 Web服务与SSL证书
如果你搭建网站、开发web服务或API,一定会接触到SSL证书。SSL证书是为网站方位启用HTTPS(SSL/TLS)所需的数字证书,其内容包含用来身份认证的和信息加密的公私密钥;部署了SSL证书的服务器,可在浏览器访问时建立基于TLS(目前是TLSv1.3)和HTTPS协议的加密可信的安全连接,从而让我们的Web环境更加安全且注重隐私。
信息的隐私性和安全性是可信赖Web服务的基础,未来的Web服务也将全部构建与TLS之上。如果你的网站没有SSL证书,所有的主流浏览器都会在URL处标记为不安全(Not Secure)网站,iOS和Andorid平台上的应用开发也必须通过HTTPS协议与应用后台通信。
那么,怎样才能获得SSL证书并用于提升网站安全性呢?本教程将提供一个基于Let's Encrypt证书的思路,并实践讲解一次真实的申请流程,跟随我一起,先从基础的背景了解开始吧~
0x01 ACME协议与DNS-01验证
Let's Encrypt与ACME协议
Let’s Encrypt是个免费、开放、自动化的证书颁发机构(CA),为公众的利益而运行。它是一项由 Internet Security Research Group(ISRG)提供的服务。这个机构致力于尽可能对用户友好的方式免费提供为网站启用 HTTPS(SSL/TLS)所需的数字证书。
Let's Encrypt免费给任何拥有域名的主体颁发安全的SSL证书;它颁发的证书还是普遍受信的,即被各浏览器厂商(Google Chome、Mozila Firefox、Apple Safari)、平台(Facebook、AWS等)和组织(如EFF)等所公认;最关键的Let's Encrypt颁发证书还快,因为流程是(几乎)完全自动化的。
ACME,(Automatic Certificate Management Environment ),即自动化证书管理环境。它Let's Encrypt设计的用于自动化管理(申请、续期、吊销)Web服务器证书的协议,通过与运行在客户端Agent程序(也称证书管理软件,以下简称certbot)来完成。
证书申请时,certbot按照ACME协议实现与Let's Encrypt的CA服务器端的数据交互,发送指定格式及内容的一组或都组验证请求,从而证明申请者对域名的控制权。验证请求中会用到不同的证明控制权的方式,即验证方式(Challenge Type)。比如,可以在已知的URI下放置指定的HTTP资源(HTTP-01)或配置DNS指定的记录(DNS-01)等验证方式。
ACME v2 协议的生产环境版本已经在2018年5月发布,其中,ACME客户端(Let'sEncrypt的Certbot)也已在最新版本中实现,完全支持了DNS-01验证方式及通配符证书的颁发。
ACME验证方式
ACME最常用的验证方式(Challenge Type)有以下两种:
HTTP-01 验证方式
这是最常见也是默认的验证方式。Let’s Encrypt 向我们服务器上的 ACME 客户端提供一个token,然后 ACME 客户端将对服务其上的 Web 服务目录 http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN>
(用提供的token替换 <TOKEN>
)路径上放置指定文件。该文件包含令牌以及帐户密钥的指纹。当ACME 客户端告诉 Let’s Encrypt 文件已准备就绪,Let’s Encrypt会尝试(从多个地点并多次)访问它这个文件。Let's Encrypt验证我们的Web服务器上确实正确路径保存了正确的文件,则该验证被视为成功,并颁发证书。
HTTP-01验证方式的优点是:不需要关于域名配置的额外知识;向通过CNAME指向的域名颁发证书也可以;和已有的 Web 服务器结合使用方便。不过缺点也显而易见:由于只能使用80端口,一旦80端口被ISP封锁了就无法验证;不能用此验证方式来颁发通配符证书;对于多个 Web 服务器,须确保该文件在所有服务器上都可访问。
DNS-01 验证方式
作文本文的主角,DNS-01验证方式要求我们在该域名下的TXT记录中放置特定值来证明对域名的实际拥有和控制——DomainName Ownership Verification。虽然这种验证方式的配置过程比HTTP-01验证略复杂一些,但可以在某些 HTTP-01不可用的情况下工作。另外DNS-01验证方式允许颁发通配符证书。
具体流程是:Let’s Encrypt向ACME客户端提供token后,客户端会创建从该token和密钥派生的TXT记录,再将该记录放在 _acme-challenge.<YOUR_DOMAIN>
下。然后Let’s Encrypt 向DNS解析服务商查询该记录。如果查询到匹配的记录项,就可以颁发证书了。注意最好验证完最好第一时间清理旧的 TXT 记录。
优点非常明显:第一,支持通配符域名的证书;第二,验证流程完全与Web服务器解耦,Nginx还是Apache,占哪个端口,有多少个Web服务器,这些问题全都不存在了。
Let's Encrypt官方认为的缺点有三个:在 Web服务器上保留API凭据存在风险,DNS提供商可能不提供API,即便提供了,也可能无法提供有关更新时间的信息。其实这都说的一个事,DNS厂商目前还没跟Let'sEncrypt配合好,导致现阶段不能完全自动化证书申请流程(这个原因复杂,本文不做任何讨论)。
不过别担心,我们可以通过结合--manual
参数的半手工操作方式,完全解决这个问题。跟着我,继续走下去吧~
0x02 申请通配型SSL证书实践
本节我们来实践下真实场景的ACME流程,通过letsencrypt客户端程序自动申请免费的通配型SSL证书,准备好了嘛~
0、为域名添加通配解析记录
首先,需要在云服务商添加通配符的域名解析记录。
所谓通配解析就是的主机记录为*
的A记录,对应解析的域名为*.your-domain.com
,通常放在最后。记录值填写要指向云服务器的IP,而这台云服务器将是我们后续发起ACME验证流程的机器。
下图是腾讯云的dnspod解析服务配置通配解析记录的示例:
1、安装Let's Encrypt客户端
登录云服务器,安装letsencrypt软件,它包含了ACME的客户端程序certbot。在Ubuntu 20.04 下可以方便地用apt命令安装:
代码语言:javascript复制sudo apt install letsencrypt
2、通过手动方式完成DNS-01验证
通过certbot命令来向Let's Encrypt申请完成验证并完成证书颁发。这里需要用certonly
子命令表示仅申请并下载证书,因为certbot还提供针对特定web服务器安装(install)证书的功能(这与其他参数并不完全兼容,而且我们此时并不需要,见后)。
后续的参数简要说明:
--manual
:表示交互式操作地获取证书--preferred-challenges=dns
:指定通过dns(DNS-01)方式验证,这是获取通配证书的目前唯一方式--server https://acme-v02.api.letsencrypt.org/directory
:指定验证的服务端API Endpoint(对于当前版本的certbot这个url已经是默认值)。
sudo certbot certonly
--manual
--preferred-challenges=dns
--server https://acme-v02.api.letsencrypt.org/directory
--agree-tos
-m your-email@example.com
-d *.your-domain-name.com
另外,可以加--dry-run
参数来测试申请(certonly)或续期(renew)的验证过程,而不会真正存储证书到本地硬盘。如图所示:
输入两个Yes后,即可开始DNS-01的验证过程了。
certbot交互程序会指示我们所需添加的DNS TXT记录,其中包括记录名(_acme-challenge)和记录值(一个随机生成的字符串)。
这时回到腾讯云的域名解析页面,为域名添加上对应的TXT记录,如图:
尽管腾讯云dnspod的域名解析第一次生效非常快,还是建议最好先用验证刚加的TXT记录是否已生效。还记得我们常说的嘛:Verify, don't trust。方法很简单,用以下这行dig
命令即可:
出现红色部分的记录值意味着TXT记录生效,此时就可以在和certbot的交互中按下回车键确认啦!待Let's Encrypt服务端验证成功后,会颁发新证书并下载到本地,命令结果如图所示:
可以看到,新的证书默认存在/etc/letsencrypt/live/your-domain.com/
目录下,证书文件名为fullchain.pem
,私钥文件名为privkey.pem
。
完成!是不是很简单?
3、Nginx服务器相关配置
证书的使用不是本文重点,这里之作简单说明,对于Nginx服务器,在server
配置段参考以下的配置即可:
证书部署成功后,浏览器就会显示安全的加锁标记并可以查看证书详情。注意,SSL证书结合HTTP2一起使用,效果更加哦!
看起来不错。不过证书期限只有3个月,到期前需要续期renew,通常certbot会创建定时任务帮我们自动完成。也可以自己手动续期。
0x03 小结
通过这篇小教程,相信你可以了解了SSL证书的背景知识、ACME协议的基本原理以及letsencrypt工具的基本使用方法。最重要的,你可以通过certbot工具申请通配SSL证书并部署在自己的网站上了,快去试试吧~
0x04 参考资料
- Let's Encrypt
- ACME protocol
- Challenge Type
- DNS-01 Challenge