全網 HTTPS 時代就要到來撮躁,Let’s Encrypt 三個月有效期的免費 HTTPS 證書現在支持泛域名了,我們可以通過 Certbot 非常方便的申請和更新證書买雾。網上很多關于 Certbot 的文章把曼,但是關于泛域名證書的自動更新很少提及,或者很多誤區(qū)漓穿,這里簡單的講解一下嗤军。
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
一行命令解決所有問題:
- 申請證書
- 配置 Nginx 站點
- 設置證書自動更新
既然自動模式全部搞定了震叮,為什么還要手動模式呢胧砰。自動模式只能自動申請和更新普通域名證書,即僅包含類似 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 域名鲤拿,增加一條
.
.
.
阿里云的 accessKeyId
和 accessSecrec
填進去就可以了假褪,注意一下域名數組里可有你的根域名在里面,沒有就加進去皆愉。
現在來執(zhí)行 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.service
和 certbot.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