用acme.sh实现ssl证书部署及自动续签
wandoubaba / 2024-11-04
介绍
acme.sh是一个实现了 acme 协议的客户端工作,使用它可以申请Let's Encrpypt、TrustAsia等机构的免费SSL证书并可以实现自动部署与自动续签。
项目地址:https://github.com/acmesh-official/acme.sh
本文主要介绍如何使用 acme.sh 为域名申请免费的90天证书,并实现Nginx自动部署和自动续签。
本文的操作环境是 Debian 11/12 系统,域名从腾讯云注册(DNSPod提供解析)。
安装acme.sh客户端
使用发下命令安装,email可以换成自己的:
curl https://get.acme.sh | sh -s email=my@example.com如果上面的命令安装失败,可以换下面这种方式:
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m my@example.com
. ~/.bashrc整个安装过程只会把工具安装到~/.acme.sh/目录下,只是在~/.bashrc中添加了一句. "/root/.acme.sh/acme.sh.env",看一眼acme.sh.env内容,是这样的:
cat /root/.acme.sh/acme.sh.env
# 结果
export LE_WORKING_DIR="/root/.acme.sh"
alias acme.sh="/root/.acme.sh/acme.sh"建议再安装个socat(它本身功能也十分强大,是linux网络运维的瑞士军刀),可以用于以standalone mode申请证书时临时“伪装”一个服务器出来。
apt-get install socat确认证书申请方式
在acme.sh的官方文档中可以看到分发证书的方式有很多种,比如文件验证、独立模式、手动DNS、自动DNS等等,我们为了实现全自动化和未来的自动续签,所以我们选择“自动DNS解析方式”。
我的域名注册商是腾讯云,解析服务由DNSPod提供,幸运的是acme.sh支持DNSPod平台的API密钥,所以我先到DNSPod平台上去创建一组密钥:
- 登录网址:https://www.dnspod.cn/
- 登录控制台
- 我的账号 - API密钥
- 切换到
DNSPod Token(不要用腾讯云API密钥) - 记录
ID和Token(页面关闭后就再也看不见了)
执行下面命令:
export DP_Id=<Id>
export DP_Key=<Token>申请证书
acme.sh --issue --dns dns_dp -d example.com如果执行成功,最后可以看到类似下面的结果,说明已经将证书文件安装到了本地:
[Mon Nov 4 01:12:52 PM CST 2024] Your cert is in: /root/.acme.sh/example.com/example.com.cer
[Mon Nov 4 01:12:52 PM CST 2024] Your cert key is in: /root/.acme.sh/example.com/example.com.key
[Mon Nov 4 01:12:52 PM CST 2024] The intermediate CA cert is in: /root/.acme.sh/example.com/ca.cer
[Mon Nov 4 01:12:52 PM CST 2024] And the full chain certs is there: /root/.acme.sh/example.com/fullchain.cer
[Mon Nov 4 01:12:52 PM CST 2024] _on_issue_success部署证书
下面分别是在apache上和在nginx上部署证书的示例,需要替换的内容是example.com和相关文件的绝对路径,以及服务重新加载配置的命令。
Apache示例:
acme.sh --install-cert -d example.com \
--cert-file /path/to/certfile/in/apache/cert.pem \
--key-file /path/to/keyfile/in/apache/key.pem \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd "service apache2 force-reload"Nginx示例:
acme.sh --install-cert -d example.com \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx force-reload"修改配置文件
acme.sh只会重新部署证书文件,不会去更改任何其他配置文件(为了安全考虑),所以,要让web服务器应用证书,还需要手动去修改相关的配置文件。
我们以nginx为例,提供一个web站点加载ssl证书并提供https服务(开443端口)的示例:
server {
listen 80;
listen [::]:80;
server_name localhost;
# ssl
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/certs/cert.pem; # 证书文件路径
ssl_certificate_key /etc/nginx/certs/key.pem; # 私钥文件路径
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}如果我们希望所有的http请求(80)都可以自动转到https(443)上,可以对上面的配置文件做一些修改:
server {
listen 80;
listen [::]:80;
server_name localhost;
# 重定向所有 HTTP 请求到 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/certs/cert.pem; # 证书文件路径
ssl_certificate_key /etc/nginx/certs/key.pem; # 私钥文件路径
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}修改完配置文件后,再要重新启动服务或者重新加载一下配置,才会生效。
验证自动续签机制
crontab -l如果看到有下面这样的定时任务,说明acme.sh的自动续签机制是生效的
43 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null