跳到主要内容
  1. Skills/
  2. 建站/

为你的网站申请 ssl 证书

··字数 3489·7 分钟
howto ssl证书

ssl 证书,是网站提前 https 服务的一项前提。与 ssh 远程连接类似,需要一对密钥,用于通讯双方消息传输过程的信息加密,在有悟文章《如何实现ssh免密码登录linux服务器》有介绍如何创建证书与部署。因为证书可以伪造,所以用于网站 https 服务的 ssl 证书 要稍微复杂一些,需要由一个可信任的机构来签发证书。

本文主要内容:

  • ssl 证书申请
  • ssl 证书部署
  • 泛域名

有悟文章《如何实现ssh免密码登录linux服务器》:

ssl 证书 是由另外一份 ssl 证书 生成的,这些信息包含在已签发的证书中,所以就有了『鸡生蛋、蛋生鸡』的问题。在实际应用中解决哲学问题,就是定义几个源头,由它们来生成证书,然后再由这些证书来生成新的证书,把一个死循环变成上下级的结构。所以就有了根证书、证书链等待概念。

作为使用者的我们,无须知道太多,只要知道如何申请、验证、申请后又如何部署就可以。证书是有一定有效期的,因而也就有了更新(重颁发)、删除(吊销)等待操作。其中接触最多的是申请、重颁发、部署等操作。

在申请证书之前,先简单介绍这个背后的流程。先向证书的颁发机构申请签发证书,他们通过验证申请域名有效性(域名所有权、域名未过期)后,向申请者签发证书文件,并提供相关的机制让申请者可以吊销、重申请颁发。

如果你的域名服务商提供了商业服务,在规划与申请 ssl 证书时需要注意 证书与域名的关系 之外,简单在控制台上对应的域名记录操作『ssl 申请申请』,等待半小时左右就可以下载到刚刚签发的证书文件,拿到这个文件之后就可以为网站部署 https 服务。

证书与域名的关系 #

  • 单域名
  • 泛域名

https://www.youwu.today ” 是有悟网站的一级域名,也可以缩写成 “ https://youwu.today ”,对于搜索引擎来说,这不是统一的。有些搜索引擎会认为 “ www.example.com ” 格式的才是主域名,对我们这种一般用户来说,无需关心。

而根域名之前的非『www』的域名,是二级域名,比如 『hub.youwu.today』,是有悟网站划分出来的另一个子站,它可以指向与 “ https://youwu.today ” 完成不同的服务器站点,不管对于浏览器、还是搜索引擎,它们被认为是两个不同的站点。

ssl证书 是根据域名来签发的,并且一个ssl 证书可以被用于站点的一级域名或者二级域名,也可以用于一个站点的所有二级域名,申请这种通指所有二级域名的 ssl证书,就需要使用到泛域名来表示。

“*.youwu.today”,这个格式就是泛域名,可以用来表示域名后缀为"youwu.today"的所用二级域名,使用泛域名申请的 ssl证书,可以用于该域名后缀的所有二级域名子站。

需要提醒的是,一般这种泛域名ssl证书是域名商业服务的一部分。申请 ssl证书时,要验证域名,域名服务商通常可以免费解析『"*" A 记录』,但证书签发时,并不一定可以申请到免费的泛域名 ssl 证书。比如在腾讯云的域名服务中,泛域名 ssl证书 是一项收费服务。

可以申请 Let’s Crypt 免费的泛域名 ssl证书,不过 Let’s Crypt 的证书有效期为3个月,站长需要定期更新,不过证书的定期更新都有一些现成的维护脚本或工具,所增加的维护工作量也是可以接受的(可以自动),毕竟是免费证书。这种免费证书同样受到认可。不过如果你是企业,还是花点钱买商业ssl 证书吧,虽然技术上看都是一样的(用文本编辑器打开来看都是一段加密后的密文),但从客户角度看心理上还是不一样的。

Let’s Crypt, 为1.8亿个网站提供TLS证书的非盈利性证书颁发机构。

如果不想花钱又不想用 Let’s Crypt 签发的证书,那就在支持申请 ssl证书的域名服务商的域名管理控制台上,添加对应的一条二级子站域名解析记录,再为这个二级域名申请专用的ssl 证书。腾讯云的域名服务,一个主域要以申请20个免费ssl证书,即不花钱你可以得到1个主域+19个二级域名的 ssl 证书,绝对够一般站点使用了。

申请证书时遇到的 dns 验证问题 #

如果你使用的是阿里云、腾讯云的域名服务,那没必要再往下看了。

能坚持到这里的同志,基本都是喜欢折腾的,放着好好的阿里云、腾讯云的免费域名服务不用,非得自己动手折腾脚本。其实,有一些站点运行在国外服务器,使用的域名服务也是国外的,这些站点与相关域名没办法正常使用国内域名服务商的服务,而国外的域名服务商除了免费解析之外,其它都收费的。这时 Let’s Crypt 的免费 ssl 证书就显得非常有价值了。

在介绍证书申请工具或者脚本之前,有悟先简单介绍原理,这样动手申请证书时才知道输入的那些参数是干什么用的。

通常站长都是申请 Let’s Crypt 的免费证书。申请者(就是你)通过工具或者脚本在操作界面(或者命令行)向证书颁发机构(就是 let’s Crypt)发起一个申请(通过命令发起一个网络请求,调用它的接口),然后颁发机构验证所申请的域名有效性、所有权并通过后,你就可以通过命令把证书下载回来,这个过程已经有专门的小工具实现,你只管操作。在操作之前,需要知道 DNS 验证的相关知识,不难很容易申请失败。

  1. 因为Let’s Crypt是免费的,所以有限制,不然服务资源会被击垮
  2. 这也是难点,DNS 验证,通过何种方式来确认申请者对域名的所有权或操作权。它定义了称为 ACME 标准来规范域名验证。

Let’s Encrypt 支持三种验证方式:HTTP-01,TLS-ALPN-01,DNS-01。我们需要了解的是 HTTP-01、DNS-01。

  • http: 在服务器部署web服务来验证,这个验证只能证明域名将被应用的服务器是真实存在的(这跟域名所有权一点关系都没有)
  • dns: 使用域名服务商的名称服务器来验证(就是负责管理 DNS 解析记录的)。通过在名称服务添加一条txt记录,然后查询这条记录是否已被添加,若存在,则表明申请者可以通过服务商来管理这个用来申请证书的域名,从而证明这个域名是申请者所有或者是可操作的。不同域名服务商提供的服务方式不同,部分服务商提供了可操作的API,通常需要在该服务商用户控制台上获取相应操作权限的API KEY或令牌。

有聪明的开发者或者站长,他们分享了证书申请、更新维护脚本,把 let's crypt 接收申请、在DNS服务上添加 TXT 验证文本,再向 Let’s crypt 发起验证请求、下载证书的整个过程串连起来,其中最为人熟知的是 acme.sh ,这套脚本已经支持了大多数常见的域名服务商(首先这些服务商得要有可通过网络访问的开放接口才行)。

签书申请、域名验证至证书颁发的过程,与从阿里云、腾讯云的域名服务上直接申请的过程是一样的,只不过是用脚本涉及多方服务调用的操作过程用脚本包装起来。

如果你的域名服务商有接口,建议你使用 DNS-01验证方式,因为 acme.sh 脚本对DNS 验证的支持比 http验证方式的支持更好。http方式,要假冒个80端口 http 服务,不懂弄的,单单 socat 的端口权限就搞晕你,或者需要搭配 nginx、apache 来完成这个验证环节,牵涉的工具太多,这些不一定是你熟悉的领域。而 DNS-01方式,只要到服务商控制台上找到 api 操作权限的 key,在 acme 申请命令中输入即可。

有悟以前使用过 cloudflare 的域名服务,cf 提供了几种权限级别的 api 接口放开给用户远程调用。如你也使用了 cloudflare 域名解析服务,配置一个操作权限级别最低的区域令牌即可,把 API KEY 记录下来,这样 acme.sh 申请 let’s crypt 证书时会使用到。

acme.sh 的脚本调用大概是这样的:

安装说明

# 假使你已经安装了 acme.sh
# 使用 dns-01 验证方式申请证书,其中 dns_cf 是 cloudflare 的别名
# 可以在 acme 的安装目录下 acem/config/account.conf 中添加 cf 的 api key,示例后面有
> acme.sh --issue --dns dns_cf -d domain.cyou -d '*.domain.cyou'
# let's encrypt 证书有效期为60天,若没有使用acme 设置的crontab定时更新任务,则按下面手动更新
> acme.sh --renew-all
# 更新后需要将证书复制到使用的位置,并重启web服务

上面的例子是同时申请域名、二级泛域名的 ssl 证书,如果申请成功,那么这些证书会被下载到 acme 的证书安装目录下

dns cloudflare acme/config/account.conf

# acme/config/account.conf
# cloudflare 里提供远程操作api的授权信息,这些信息来自 cf 的管理控制台
...
SAVED_CF_Token='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
SAVED_CF_Account_ID='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
SAVED_CF_Zone_ID='xxxxxxxxxxxxxxxxxxxxxxxxxx'
...

acme.sh 脚本支持自更新、证书更新,这些更新操作都在 acme 安装时就注册到系统 crontab 中做为日常运维的一部分。

本文关于 acme.sh 操作的说明并不完整,平时并不会频繁操作 ssl证书 申请,就没有太多的过程材料。具体的还是参数官方开源库的说明,有中文的。而写这一篇文章的目的,仅是回忆以前申请 ssl证书 时的操作,留作后用。同时近期有悟准备编写关于 nginx 中启用 https 的文章,涉及到 ssl 证书,这篇文章算是其中的一部分吧。