用Certbot申请免费Let’s Encrypt泛域名证书+自动续期

Let’s Encrypt是一个免费的CA证书颁发机构,从v2版本协议开始支持泛域名证书申请。

什么是通配符证书

在没有出现通配符证书之前,Let’s Encrypt 支持两种证书。

  1. 单域名证书:证书仅仅包含一个主机。
  2. SAN 证书:一张证书可以包括多个主机(Let’s Encrypt 限制是 20),也就是证书可以包含下列的主机:www.example.com、www.example.cn、blog.example.com等等。

证书包含的主机可以不是同一个注册域,不要问我注册域是什么?注册域就是向域名注册商购买的域名。

对于个人用户来说,由于主机并不是太多,所以使用 SAN 证书完全没有问题,但是对于大公司来说有一些问题:

  • 子域名非常多,而且过一段时间可能就要使用一个新的主机。
  • 注册域也非常多。

读者可以思考下,对于大企业来说,SAN 证书可能并不能满足需求,类似于 sina 这样的网站,所有的主机全部包含在一张证书中,而使用 Let’s Encrypt 证书是无法满足的。

Let’s Encrypt 通配符证书

通配符证书就是证书中可以包含一个通配符,比如 .example.com、.example.cn,读者很快明白,大型企业也可以使用通配符证书了,一张证书可以防止更多的主机了。

下载

我们通过 certbot-auto 自动生成工具来操作。

wget https://dl.eff.org/certbot-auto
chmod +x certbot-auto wget https://dl.eff.org/certbot-auto

生成证书

./certbot-auto certonly --email 邮箱 -d 域名 -d 域名2 --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory  

`certonly` 表示安装模式,Certbot 有安装模式和验证模式两种类型的插件。

–manual 表示手动交互模式,Certbot 有很多插件,不同的插件都可以申请证书,用户可以根据需要自行选择

-d 为那些主机申请证书,如果是通配符,输入 *.xxxx.com (可以替换为你自己的域名)

–preferred-challenges 使用 DNS 方式校验域名所有权

–server Let’s Encrypt ACME v2 版本使用的服务器不同于 v1 版本,需要显示指定。

操作交互流程

  1. 是否同意 Let’s Encrypt 协议要求,按y同意确认
  2. 询问是否对域名和机器(IP)进行绑定按y绑定
  3. 域名验证 dns 解析增加 TXT 配置,对申请域名添加TXT解析,名称为_achme-challenge,值为交互模式所给出的值。
  4. 创建成功 /etc/letsencrypt/live/xxxx.com/ 下会生成 4 个文件,请勿更改 ssl 文件位置,这样可以减少自动续期时的操作
    cert.pem – Apache服务器端证书
    chain.pem – Apache根证书和中继证书
    fullchain.pem – Nginx所需要ssl_certificate文件
    privkey.pem – 安全证书KEY文件
    Nginx环境,就只需要用到fullchain.pem和privkey.pem两个证书文件

nginx 配置

增加 443 端口监听

listen 443 ssl; 

增加 ssl 配置

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_session_cache builtin:1000 shared:SSL:10m;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/xxxx.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxx.com/privkey.pem;
ssl_session_timeout 5m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on; `ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_session_cache builtin:1000 shared:SSL:10m;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/xxxx.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxx.com/privkey.pem;
ssl_session_timeout 5m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;` 

#### http 强制跳转 https

server
    {
        listen 80 ;
        server_name www.xxxx.com;
        rewrite ^(.*)$  https://$host$1 permanent; 
    } 

nginx 重新加载配置

service nginx reload

使用脚本生成及续期

以阿里云为例,我们需要建立一个api来进行域名解析等操作,进入阿里云控制台,访问控制,创建用于控制dns的用户,限制变成访问即可,创建自定义权限,下方贴出进具备解析,查询等权限的自定义权限

下面策略是对当前账户下所有的dns具备增删改查dns的权限

{
    "Version": "1",
    "Statement": [
        {
            "Action": [
                "alidns:DescribeSiteMonitorIspInfos",
                "alidns:DescribeSiteMonitorIspCityInfos",
                "alidns:DescribeSupportLines",
                "alidns:DescribeDomains",
                "alidns:DescribeDomainNs",
                "alidns:GetTxtRecordForVerify",
                "alidns:AddDomainRecord",
                "alidns:UpdateDomainRecord",
                "alidns:DescribeDomainRecordInfo",
                "alidns:UpdateDomainRecordRemark",
                "alidns:DeleteSubDomainRecords",
                "alidns:SetDomainRecordStatus",
                "alidns:DescribeDomainGroups"
            ],
            "Resource": "acs:alidns:*:*:domain/xingensheng.com",
            "Effect": "Allow"
        }
    ]
}

执行生成命令

./certbot-auto certonly –no-self-upgrade -d *.willh.cn -d willh.cn –manual –preferred-challenges dns –manual-auth-hook “/home/certbot-sh/au.sh python aly add” –manual-cleanup-hook “/home/certbot-sh/au.sh python aly clean” –dry-run

因为有效期只有 3 个月我们需要自动续期来延长有效期。

通配证书只能通过 dns 的方式验证域名归属,我们需要通过脚本自动完成验证 –manual-auth-hook 设定验证脚本,否则无法自动更新

./certbot-auto renew --no-self-upgrade --cert-name willh.cn --manual-auth-hook /home/certbot-sh/au.sh --dry-run

重要提示:为避免遇到操作次数的限制,加入 dry-run 参数,可以避免操作限制,等执行无误后,再进行真实的 renew 操作。

au.sh脚本具体参考https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au

有了这两个脚本,我们就可以通过 crontab 每月定时执行一次续期,并重新加载 nginx 配置。

crontab -e

添加定时任务

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && 脚本路径/certbot-auto renew --manual --preferred-challenges dns --manual-auth-hook 脚本路径/au.sh --renew-hook "/usr/local/nginx/sbin/nginx -s reload"

openssl 查看证书详情命令

打印证书的过期时间
openssl x509 -in signed.crt -noout -dates

打印出证书的内容:
openssl x509 -in cert.pem -noout -text

打印出证书的系列号
openssl x509 -in cert.pem -noout -serial

打印出证书的拥有者名字
openssl x509 -in cert.pem -noout -subject
以RFC2253规定的格式打印出证书的拥有者名字
openssl x509 -in cert.pem -noout -subject -nameopt RFC2253

在支持UTF8的终端一行过打印出证书的拥有者名字
openssl x509 -in cert.pem -noout -subject -nameopt oneline -nameopt -escmsb

打印出证书的MD5特征参数
openssl x509 -in cert.pem -noout -fingerprint

打印出证书的SHA特征参数
openssl x509 -sha1 -in cert.pem -noout -fingerprint

把PEM格式的证书转化成DER格式
openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER

把一个证书转化成CSR
openssl x509 -x509toreq -in cert.pem -out req.pem -signkey key.pem

给一个CSR进行处理,颁发字签名证书,增加CA扩展项
openssl x509 -req -in careq.pem -extfile openssl.cnf -extensions v3_ca -signkey key.pem -out cacert.pem

给一个CSR签名,增加用户证书扩展项
openssl x509 -req -in req.pem -extfile openssl.cnf -extensions v3_usr -CA cacert.pem -CAkey key.pem -CAcreateserial

查看csr文件细节:
openssl req -in my.csr -noout -text
此条目发表在nginx分类目录。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注