通过 Certbot 申请泛域名 HTTPS 证书及配置自动更新

全网 HTTPS 时代就要到来,Let’s Encrypt 三个月有效期的免费 HTTPS 证书现在支持泛域名了,我们可以通过 Certbot 非常方便的申请和更新证书。网上很多关于 Certbot 的文章,但是关于泛域名证书的自动更新很少提及,或者很多误区,这里简单的讲解一下。

Certbot 安装

安装非常简单,只要进入 Certbot 官网选择对应的系统和 Web 服务软件就会提示如何安装,按照提示操作就可以了。

我的服务器是 Ubuntu 16.04 + Nginx,以下内容以这个为模板。

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

申请证书有两种模式:自动模式和手动模式

自动模式

$ sudo certbot --nginx

一行命令解决所有问题:

  1. 申请证书
  2. 配置 Nginx 站点
  3. 设置证书自动更新

既然自动模式全部搞定了,为什么还要手动模式呢。自动模式只能自动申请和更新普通域名证书,即仅包含类似 dada.fun、www.dada.fun 这种域名的证书,将来每增加一个二级域名如 admin.dada.fun 都要重新扩展证书。而泛域名证书是直接认证给 *.dada.fun,所有二级域名都覆盖了,一劳永逸。如果你仅仅需要普通域名证书,那到此就结束了。

对于喜欢折「zhuang」腾「bi」的人来说,当然还是来个泛域名证书吧!

手动模式

申请泛域名证书

申请泛域名证书的时候要对域名进行认证。认证方式有很多,比如在域名绑定空间下放个文件什么的,都很麻烦,最方便的是 DNS 认证。DNS 认证只需要在域名 DNS 下增加一条指定的记录就可以了。一般来说可以自己登录域名管理后台添加指定记录来配合申请,但是以后更新怎么办?每次都登录服务器运行更新命令,再登录域名管理后台添加记录?好在 Certbot 程序可以在更新证书的时候通过接口来替我们添加 DNS 记录。现在很多 DNS 服务商都提供了 API 接口来管理 DNS 记录,这样就使自动更新成为可能。Certbot 默认支持很多 DNS 服务商,但是国内几家大的服务商都不支持,这样就要用到第三方的插件了。

我用的是网友 虞大胆 开源的一个工具:certbot-letencrypt-wildcardcertificates-alydns-au。工具就不介绍了,点开链接作者写的很详细了,看看怎么用吧:

$ git clone https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au certbot-wildcard
$ cd certbot-wildcard
$ chmod 0777 au.sh autxy.sh augodaddy.sh python-version/au.sh

「这工具名字太长,我改成 certbot-wildcard 了」
下载安装完成修改一下配置文件 alydns.php「我是阿里云注册的域名」:

<?php

date_default_timezone_set("GMT");

//这两个值需要去阿里云申请
define("accessKeyId", "");
define("accessSecrec", "");
.
.
.
    public static function getDomain($domain) {
    
    //https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains  
        //常见根域名
        $arr[]=".co.jp";
        $arr[]=".com.tw";
        $arr[]=".net";
        $arr[]=".com";
        $arr[]=".com.cn";
        $arr[]=".org";
        $arr[]=".cn";
        $arr[]=".gov";
        $arr[]=".net.cn";
        $arr[]=".io";
        $arr[]=".top";
        $arr[]=".me";
        $arr[]=".int";
        $arr[]=".edu";
        $arr[]=".link";
        $arr[]=".uk";
        $arr[]=".hk";
        $arr[]=".fun"; #默认不支持 .fun 域名,增加一条
.
.
.

阿里云的 accessKeyIdaccessSecrec 填进去就可以了,注意一下域名数组里可有你的根域名在里面,没有就加进去。

现在来执行 Certbot 命令申请证书:

$ sudo certbot certonly -d dada.fun -d *.dada.fun --manual --preferred-challenges dns --manual-auth-hook /root/certbot-wildcard/au.sh --pre-hook "systemctl stop nginx.service" --post-hook "systemctl start nginx.service"

命令非常长,带了很多参数:

-d 指定域名,*.dada.fun 必须的,本来就冲着它来的。有的机构会自动带上 dada.fun,但是 Let’s Encrypt 不会,所以要把 dada.fun 带上,不然访问 dada.fun 还是 HTTP 就尴尬了!

--manual 手动操作

--preferred-challenges dns 通过 DNS 来认证

--manual-auth-hook /root/certbot-wildcard/au.sh 手动操作认证时候的钩子,这里调用刚刚下载的工具进入阿里云域名管理后台添加 DNS 记录

--pre-hook "systemctl stop nginx.service" 前置钩子,安装证书之前关闭 nginx 服务

--post-hook "systemctl start nginx.service" 后置钩子,证书安装完成以后打开 nginx 服务

不出意外的话证书就申请好了。默认放在 /etc/letsencrypt/archive/dada.fun/ 文件夹里面。接下来修改一下 Nginx 的站点配置:

server {

    server_name dada.fun www.dada.fun;
    root "/var/www/dada.fun";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log /var/log/nginx/dada.fun.log;
    error_log /var/log/nginx/dada.fun-error.log error;

    sendfile off;

    client_max_body_size 100m;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;

        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
    }

    location ~ /\.ht {
        deny all;
    }

    listen 443 ssl; # 修改地方
    ssl_certificate /etc/letsencrypt/live/dada.fun/fullchain.pem; # 修改地方
    ssl_certificate_key /etc/letsencrypt/live/dada.fun/privkey.pem; # 修改地方

} server {
    
    if ($host = www.dada.fun) {
        return 301 https://$host$request_uri;
    } # 强制跳转 HTTPS

    if ($host = dada.fun) {
        return 301 https://$host$request_uri;
    } # 强制跳转 HTTPS

    listen 80;
    server_name dada.fun www.dada.fun;
    return 404; # 修改地方

}

改完以后重启 Nginx 服务生效,网站就能访问了。

更新泛域名证书

证书有效期只有三个月,所以更新域名非常关键。更新操作其实和初次申请差不多,只是命令不同,参数都一样。所以智能的 Certbot 在初次申请完成以后就把所有参数都保存下来,方便更新的时候使用。更新的参数保存在 /etc/letsencrypt/renewal/dada.fun.conf。我们打开看看:

# renew_before_expiry = 30 days
version = 0.28.0
archive_dir = /etc/letsencrypt/archive/dada.fun
cert = /etc/letsencrypt/live/dada.fun/cert.pem
privkey = /etc/letsencrypt/live/dada.fun/privkey.pem
chain = /etc/letsencrypt/live/dada.fun/chain.pem
fullchain = /etc/letsencrypt/live/dada.fun/fullchain.pem

# Options used in the renewal process
[renewalparams]
manual_public_ip_logging_ok = True
manual_auth_hook = /root/certbot-wildcard/au.sh
server = https://acme-v02.api.letsencrypt.org/directory
pref_challs = dns-01,
authenticator = manual
account = 6656c0feac6c44e53d8b89e9afb6712b
pre_hook = systemctl stop nginx.service
post_hook = systemctl start nginx.service

通过第一行看到 Certbot 只有在离证书过期 30 天内才会更新证书,超过 30 天的证书更新会被忽略。

既然参数都还在,那更新证书只需要一条简单的命令就可以了:

$ sudo certbot renew

定时任务自动更新

光能更新证书还不够,谁吃饱没事每三个月登录一次服务器更新证书呀。在服务器上设置定时任务自动更新才是完美的方案。Linux 的定时任务有两种方法:cron 和 systemd/timers,任何一种都能实现定时的更新任务,可爱的 Certbot 两种都设置了,我们分别看看。

Cron

$ vim /etc/cron.d/certbot

打开文件可以看到 Certbot 设定的任务记录:

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

每天运行两次 certbot -q renew,-q 是安静模式,只把 error 写入日志。我们选择 timers 来自动更新,所以把 cron 任务注释掉:

#0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

Timers

Certbot 在 /lib/systemd/system/ 下生成了两个文件:certbot.servicecertbot.timer,一个是服务,一个是定时器。

certbot.service:

[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true

可以看到也是运行 certbot -q renew 命令。

certbot.timer:

[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target

每天 0 点和 12 点激活 certbot.service。其实不需要这么频繁的更新证书,而且在更新证书的时候我们加了钩子来关闭和开启 Nginx 服务,所以最好是在凌晨没人访问网站的时候更新证书,我们稍微修改一下:

[Unit]
Description=Run certbot every 05:00

[Timer]
OnCalendar=*-*-* 05:00:00
Persistent=true

[Install]
WantedBy=timers.target

每天凌晨 5 点更新一次证书。因为只有过期前 30 天才会申请更新,所以前 60 天这个任务什么都没干。

保存修改以后需要重启定时器:

$ systemctl daemon-reload
$ systemctl restart certbot.timer

至此就算大功告成了!写起来一大篇,其实真正操作起来也就是半小时。最后祝大家都用上安全的 HTTPS!

看一下安全检测:https://www.ssllabs.com/ssltest/analyze.html?d=dada.fun

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容