前言

    最近在github上发现一个项目”acme.sh“,相当强大,它实现了 acme 协议, 可以从 letsencrypt 生成免费证书,并自动更新证书,解决了证书申请和更换的痛点。

    就这一点,就已经体现了这个项目的价值了,给作者赞一个。而我也是https证书申请替换的深度受害者,看到这个项目后,立刻着手实践了一把,别说,这效果还真不错。

github地址:链接地址

acme.sh安装

安装很容易,只需要一个简单的命令:

1
curl  https://get.acme.sh | sh

设置别名,方便后面直接调用:

1
alias acme.sh=~/.acme.sh/acme.sh

安装完成后,会自动创建一个cronjob,每天 0:00 点自动检测所有的证书,如果快过期了,就会自动更新证书。我们可以通过下面的命令查看:

1
crontab -l

nginx配置静态网页

1,创建nginx证书,指定需要生成证书的域名

1
acme.sh --issue  -d u.32e.co   --nginx

注:上面这个命令执行之前,需要先将nginx的域名配置好,否则会提示错误:“Can not find conf file for domain u.32e.co”,示例可参考文末“申请配置示例”

2,设置证书存放路径

1
mkdir -p /home/cert/u.32e.co

3,将生成的证书安装到指定路径,并设置自动更新

1
2
3
4
acme.sh --install-cert -d u.32e.co \
--key-file /home/cert/u.32e.co/key.pem \
--fullchain-file /home/cert/u.32e.co/cert.pem \
--reloadcmd "nginx -s reload"

注:这里文档倒是说要使用:“force-reload”,才能正常更新加载。不过貌似直接reload也能重新加载,实在不行甚至可以直接拼接命令:“nginx -s stop;nginx”

4,证书和自动更新已经设置好后,我们就开始配置ngix,开放443端口、设置证书路径和其他参数

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
server {
listen 80;
listen 443 ssl http2;
server_name u.32e.co;

#如果打开,则默认全部走https
#ssl on;
ssl_certificate /home/cert/u.32e.co/cert.pem;
ssl_certificate_key /home/cert/u.32e.co/key.pem;

#ssl性能调优
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;

# 开启gzip压缩
gzip on;
# 设置中文编码
charset utf-8,gbk;

location / {
root /home/www_utils;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

nginx配置动态服务

1,我这里使用是java的springboot项目,端口:8080。创建证书的方法都是一样的,我们直接看nginx要如何配置的:

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
41
42
43
44
45
46
47
48
upstream server_pool{
server 127.0.0.1:8080;
}
server {
listen 80;
listen 443 ssl http2;
server_name k.32e.co;

#如果打开,则默认全部走https
#ssl on;
ssl_certificate /home/cert/k.32e.co/cert.pem;
ssl_certificate_key /home/cert/k.32e.co/key.pem;

#ssl性能调优
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;

# 开启gzip压缩
gzip on;
# 设置中文编码
charset utf-8,gbk;

#缓冲区设置
client_max_body_size 100m;
client_body_buffer_size 2M;

location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;

proxy_max_temp_file_size 2048M;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;

proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 1M;
proxy_busy_buffers_size 2M;

proxy_pass http://server_pool;
}
}

2,如此,就结束了,确实很简单,等到证书快过期的时候,脚本设置的定时任务会自动去更新证书,我们也就不用去关注了。

申请配置示例

1
2
3
4
5
6
7
8
server {
listen 80;
server_name u.32e.co;
location / {
root /;
index index.html index.htm;
}
}