提醒:本页面将不再更新、维护或者支持,文章、评论所叙述内容存在时效性,涉及技术细节或者软件使用方面不保证能够完全有效可操作,请谨慎参考!

不得不说Letsencrypt的免费SSL数字证书确实大力促进了加密HTTP(HTTPS)的普及,使用HTTPS的好处自然有很多,比如防止登录凭据等敏感信息被第三方窃取、防止电信运营商的ISP劫持等,Google Chrome和Mozilla Firefox也在逐步将明文HTTP标识为不安全,这也在一定程度上加快了HTTPS的推广。

但是由于一些条件限制,国内的HTTPS推广普及一直不温不火,虽然大部分主流网站已经采用了HTTPS,但是大量的中小型网站、政府门户依然使用的是明文HTTP,给个人信息带来安全隐患,不使用HTTPS的理由总是有千百种,比如虚拟主机限制、CDN限制、老旧浏览器兼容、服务器资源消耗等,但是我们不能因为这些缘故而放弃HTTPS带来的优势,从长远来看HTTPS的全面普及是势不可挡的。

今天我要介绍的就是使用Letsencrypt免费证书的服务为网站提供HTTPS连接,当然这类文章网上也有很多,尤其是各种便捷自动化部署工具的出现使得专门写一篇文章介绍显得没有必要,但是我今天介绍的是今年Letsencrypt刚推出的通配符(Wildcard)证书的申请。什么是通配符证书,通配符证书也称为泛域名证书,一般情况下我们申请的证书可能只包含两个域名比如主域名wangye.org和子域名www.wangye.org,这对于大部分网站用户来说已经足够,但是需要注意的是这种证书的缺点就是需要把所有可能的子域名加入证书域名别名列表中,否则一旦你开展新业务,比如启用域名mail.wangye.org,这时候使用不包含该域名的证书将会导致浏览器提醒安全风险,甚至拒绝访问。难不成重新申请证书再把mail.wangye.org加入?又或者单独为mail.wangye.org配置证书?这些都是解决方案,不过这可能带来的是管理上麻烦和配置问题,如果一开始我们申请的证书能够包含任意的子域名那就一劳永逸了,是的,通配符证书正是为了解决这个问题而诞生的,我看了一些收费SSL证书,对于DV型证书,支持通配符的证书价格甚至比普通证书要高,这一点可以看出Letsencrypt开放通配符证书的申请还是很有良心的。

本文仅作备忘笔记,内容为事后回忆,可能会有所出入,仅供参考,配置通配符证书的第一步需要确定你的域名权威DNS的动态更新权限,对于一些第三方服务这个是通过API提供的,因为各家配置不同本文不作叙述,关于域名权威DNS可以通过WHOIS查询到,本文介绍的是使用BIND9自建服务器的配置,操作具体涉及到三台服务器分别是域名DNS服务器、网站主机服务器、Letsencrypt证书签发服务器,其中DNS服务器安装的是最新版BIND9软件。

1. 配置DNS服务器

首先使用apt更新系统环境:

sudo apt-get update
sudo apt-get upgrade

使用下面的命令生成SHA512 TSIG密钥,此操作可以在home目录下,不需要root权限:

dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST keyname.

(注意keyname.可以任意定义,但是我查阅资料发现名字基本上都有最后那个点)

上面的命令将创建两个形如 Kkeyname.+165+XXXXX.key Kkeyname.+165+XXXXX.private 文件,这两个文件都是可以直接用cat命令显示出来的,我们需要的是保存于 Kkeyname.+165+XXXXX.private 的key字段数据,使用grep命令抓取:

grep -e Key Kkeyname.+165+XXXXX.private | cut -d' ' -f2-

这里将生成形如以下的key字符串(每次命令生成的字符串是不同的,这里仅举例说明):

i/KJzuKiYGbWlZ7x3qR6OxXjEX3L8XdeOy90F3aFYtRaGJp/8Ig4HmP/WfG6WsFqoe+a31emvJWeapxmNbnDmA==

由于接下来会多次用到这个key,请记住并复制这个key留作备用。

将key加入我们的BIND9配置,编辑配置文件 /etc/bind/named.conf 文件,并写入key的配置如下:

key "keyname." {
  algorithm hmac-sha512;
  secret "i/KJzuKiYGbWlZ7x3qR6OxXjEX3L8XdeOy90F3aFYtRaGJp/8Ig4HmP/WfG6WsFqoe+a31emvJWeapxmNbnDmA==";
};

编辑配置文件 /etc/bind/named.conf.local ,配置DNS区域(zone)如下以启用DNS的动态更新权限(这里以wangye.org为例):

zone "wangye.org" {
  type master;
  file "/etc/bind/zones/master/db.wangye.org";

  update-policy {
    grant keyname. name _acme-challenge.wangye.org. txt;
  };
};

增加BIND9对于配置文件的修改权限,因为动态更新是需要BIND9自主更新,如果BIND9没有修改权限,那么动态更新必然会失败,失败消息可以通过日志看到。

chown -R root:bind /etc/bind/zones/master
chmod -R 775 /etc/bind/zones/master

完成上述操作后使用 service bind9 restart 重启BIND9服务使得DNS生效,至此域名DNS服务器配置结束,接下来需要完成的是网站主机的配置。

2. 托管网站主机配置

这里是网站主机是指运行Ubuntu或者类似Linux系统的主机或者VPS,其中Web服务器软件使用的是nginx,不包括虚拟主机。使用SSH登入网站主机,安装certbot对Letsencrypt证书进行管理:

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx

安装插件 dns_rfc2136 ,此插件通过 dns-01 challenge 实现对DNS服务器上TXT的动态更新(刚才我们BIND9配置过):

sudo apt-get install pip3

如果上面的命令失败的话请尝试下面的命令替代:

sudo apt-get install python3-pip
pip3 install certbot-dns-rfc2136

/etc/letsencrypt 路径下新建配置文件rfc2136.ini,内容如下:

dns_rfc2136_server = 203.119.25.5
dns_rfc2136_name = keyname.
dns_rfc2136_secret = i/KJzuKiYGbWlZ7x3qR6OxXjEX3L8XdeOy90F3aFYtRaGJp/8Ig4HmP/WfG6WsFqoe+a31emvJWeapxmNbnDmA==
dns_rfc2136_algorithm = HMAC-SHA512

值得注意的是上述配置中 dns_rfc2136_server 配置节所指示的IP地址请替换成你自己的DNS服务器IP地址(之前配置BIND9的那台), dns_rfc2136_name dns_rfc2136_secret 请替换成和刚才BIND9 DNS服务器相同的配置。

假设你的nginx已经配置有可以正常运行的网站且防火墙已经放行TCP 443的端口流量,下面可以申请新的证书了:

sudo certbot certonly --dns-rfc2136 \
  --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --agree-tos --no-eff-email \
  --domain 'wangye.org' --domain '*.wangye.org'

最后采用此自动Challenge方式申请证书必然每次续期会修改DNS记录,这个与DNSSEC功能有冲突,如果使用该方式,则需要放弃DNSSEC特性。

参考资料