本文使用Let's Encrypt的免费HTTPS证书,并搭配自动续约脚本,达到https一劳永逸的效果。基本上部署一次,之后就再也不需要维护了,异常方便。

方案简介

Let’s Encrypt和CertBot

我们申请和使用Let's Encrypt的免费HTTPS证书, 就需要一个证书申请和管理的工具, 然后certbot是官方推荐的申请工具, 我们使用这个工具申请和管理我们的证书

certbot支持大部分的Linux发行版

上面也提到,现在阿里云不售卖免费证书了,但是如果我们(实际上是公司)想白嫖怎么办呢?就得用到Let's Encrypt了。

下面我就分享下如何一键部署CertBot并开启自动续期。

方案实施

准备

  • Docker以及Docker Compose环境
  • 域名DNS已经指向待部署的服务器,因为脚本校验证书所属权,需要访问域名

废话少说,这就开始!

克隆仓库

💡 提示:这一步必不可少,一定要按照仓库目录结构来执行,完成后,可以自行更改 nginx/conf.d 下的配置文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ mkdir -p /data
$ cd /data
$ git clone https://ghproxy.com/https://github.com/gcdd1993/nginx-certbot
$ cd nginx-certbot
$ ls -l
drwxr-xr-x 4 root root 4096 Jun 8 22:01 ./
drwxr-xr-x 5 root root 4096 Jun 8 21:49 ../
drwxr-xr-x 4 root root 4096 Jun 8 21:53 data/
-rw-r--r-- 1 root root 660 Jun 8 21:49 docker-compose.yml
drwxr-xr-x 8 root root 4096 Jun 8 21:49 .git/
-rw-r--r-- 1 root root 14 Jun 8 21:49 .gitignore
-rwxr-xr-x 1 root root 2286 Jun 8 22:01 init-letsencrypt.sh*
-rw-r--r-- 1 root root 1074 Jun 8 21:49 LICENSE
-rw-r--r-- 1 root root 1376 Jun 8 21:49 README.md

修改邮箱

1
2
3
4
$ vim init-letsencrypt.sh
...
email="gcwm99@gmail.com"
...

修改操作域名

修改your_domain为你的域名(只能是单域名,不能是泛域名)

1
2
$ sed -i 's/example.org/your_domain/g' data/nginx/app.conf \
&& sed -i 's/example.org/your_domain/g' init-letsencrypt.sh

执行脚本

出现以下内容,说明已经成功!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ./init-letsencrypt.sh
...
Requesting a certificate for your_domain

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem
This certificate expires on 2021-09-06.
These files will be updated when the certificate renews.

NEXT STEPS:
- The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

修改配置

将配置更改为你自己网站的配置,下面给一个示例配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ mv app.conf app.conf.bak # 注释默认配置
$ cd /data/nginx-cert/data/nginx
$ vim nginx-example.conf # 编写自己的配置
upstream my.site {
server localhost:8080;
}
server {
server_name your_domain;

proxy_read_timeout 600s;
proxy_send_timeout 600s;

location / {
add_header X-Frame-Options deny;
proxy_pass http://my.site;
}

# 以下内容保持不变即可,只需要修改your_domain为你的域名
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

server_tokens off;
}
# 以下内容保持不变即可,只需要修改your_domain为你的域名
server {
if ($host = your_domain) {
return 301 https://$host$request_uri;
} # managed by Certbot

location /.well-known/acme-challenge/ {
root /var/www/certbot;
}

server_name your_domain;
listen 80;
return 404; # managed by Certbot
}

其中的location /.well-known/acme-challenge/很重要,千万不要漏了,否则在进行证书续期的时候,是无法通过网站所属验证的。

重启Nginx服务

1
2
$ cd /data/nginx-certbot
$ docker-compose restart

附录

多域名操作

步骤同上,先修改域名为待操作域名,然后执行 init-letsencrypt.sh

1
2
3
4
$ sed -i 's/your_domain/your_domain2/g' data/nginx/app.conf \
&& sed -i 's/your_domain/your_domain2/g' init-letsencrypt.sh
$ ./init-letsencrypt.sh
...

更新证书

1
2
3
4
5
6
$ docker exec -it nginx-certbot_certbot_1 certbot renew
# ...
The following certificates are not due for renewal yet:
/etc/letsencrypt/live/my.site/fullchain.pem expires on 2021-09-06 (skipped)
No renewals were attempted. # 还未到更新时间,证明证书还是有效的
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

修改更新间隔

修改docker-compose.yml里面的间隔即可。

1
2
3
4
5
6
$ cd /data/nginx-certbot
$ vim docker-compose.yml
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" # 修改12h为你喜欢的值

# 修改完毕,重启
$ docker-compose restart

好了,还不快试试?