文章目录
- acme.sh管理 SSL/TLS 证书
- 操作流程
- 安装 acme.sh
- 签发证书
- 安装证书
- 自动续签
- 其他实用命令
- 常见问题
- 实操演示
- nginx 环境说明
- 步骤一:创建站定目录(与域名解析一致)
- 步骤二:创建站点配置文件
- 步骤三:http验证申请签发证书
- 步骤四:安装证书到秘钥配置目录
- 步骤五:站点配置文件中配置https配置
- 删除acme.sh申请的证书
acme.sh管理 SSL/TLS 证书
acme.sh 是一个基于 ACME 协议的轻量级工具,用于自动化申请、续签和管理 SSL/TLS 证书(如 Let’s Encrypt 证书)。它使用 Shell 脚本编写,依赖简单,支持多种 DNS 服务和 Web 服务器
操作流程
安装 acme.sh
curl https://get.acme.sh | sh -s email=your_email@example.com
自动安装到 ~/.acme.sh/
,并添加定时任务(通过 crontab -l
查看)。
建议使用真实邮箱,用于证书到期提醒。
签发证书
方式一:HTTP 验证(签发前,请确保域名解析已到服务器
)
acme.sh --issue -d example.com -d www.example.com -w /var/www/html
# 或
acme.sh --issue -d example.com -d www.example.com --webroot /var/www/html
-w
: 指定网站根目录,工具会在目录下创建 .well-known/acme-challenge/
临时文件验证所有权。
方式二:DNS 验证(无需服务器,适合通配符证书)
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
需提前配置 DNS API 凭据(如 Cloudflare、阿里云等)。
例如 Cloudflare:
export CF_Key="your_cloudflare_api_key"
export CF_Email="your_cloudflare_email"
未实操,请自行测试
安装证书
acme.sh --install-cert -d example.com \--key-file /path/to/key.pem \--fullchain-file /path/to/fullchain.pem \--reloadcmd "systemctl reload nginx"
证书文件默认保存在 ~/.acme.sh/example.com/。
–reloadcmd 指定证书更新后重启服务的命令。
自动续签
acme.sh 自动创建定时任务,证书到期前会主动续签(Let’s Encrypt 证书有效期为 90 天)。
手动续签:
acme.sh --renew -d example.com --force
其他实用命令
查看已安装证书:
acme.sh --list
升级 acme.sh:
acme.sh --upgrade
切换 CA 机构(如 ZeroSSL):
acme.sh --set-default-ca --server zerossl
或在配置文件在同目录中的account.conf
中配置
DEFAULT_ACME_SERVER='https://acme-v02.api.letsencrypt.org/directory'
常见问题
-
权限问题:确保证书目录可被 Web 服务器读取(如 Nginx 用户需访问 /path/to/key.pem)。
-
DNS API 配置:参考 acme.sh DNS API 文档 设置环境变量。
-
通配符证书:必须使用 DNS 验证方式。
实操演示
以下教程与自行编译nginx,mysql 和php组合的环境部署
nginx 环境说明
- 配置用户组和所属用户未
www www
- 站点目录为
/home/www/wwwroot/
- 秘钥存储目录为
/usr/local/nginx/ssl/
- 虚拟站点拆分配置文件目录
/usr/local/nginx/vhost/
步骤一:创建站定目录(与域名解析一致)
mkdir /home/www/wwwroot/www.example.com
chowm -R www:www /home/www/wwwroot/www.example.com
创建的站点目录,需要设定为对应的所属组、所属主
步骤二:创建站点配置文件
已在 nginx.conf
配置include vhost/*.conf;
引入同目录下的文件夹vhost
中的站点配置文件www.example.com.conf
- 单域名配置
server{listen 80;#listen [::]:80;server_name www.example.com; # example.com换成对应的域名index index.html index.htm;root /home/wwwroot/www.example.com; # example.com换成对应的站点目录#error_page 404 /404.html;# 拒绝访问特定目录下的PHP文件#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; } # 申请SSL 证书后,打开注释重定向到https配置# return 301 https://$host$request_uri; access_log off;}
- 多域名申请配置
server{listen 80;#listen [::]:80;server_name www.example.com example.com; # example.com换成对应的域名index index.html index.htm;root /home/wwwroot/example.com; # example.com换成对应的站点目录#error_page 404 /404.html;# 拒绝访问特定目录下的PHP文件#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; } # 申请SSL 证书后,打开注释重定向到https配置# return 301 https://$host$request_uri; access_log off;}
return 301 https://$host$request_uri;
申请ssl正式前,先注释掉,用于申请证书访问
- 站点配置文件配置好后,重启
nginx
服务 ,通过http://www.example.com
检查是否能访问成功
systemctl restart nginx.service
步骤三:http验证申请签发证书
cd
进入acme.sh
的安装目录~/.acme.sh
,执行以下命令
- 单域名申请证书
./acme.sh --issue -d example.com -d www.example.com --webroot /home/www/wwwroot/www.example.com
- 多域名申请证书
./acme.sh --issue -d www.example.com -d example.com --webroot /home/www/wwwroot/www.example.com
执行上述命令成功后,默认在~/.acme.sh
目录中产生一个域名对应的文件夹
步骤四:安装证书到秘钥配置目录
执行安装命令前,请确保已创建对应的ssl
配置目录
在acme.sh
的安装目录~/.acme.sh
,执行以下命令
- 单域名申请证书安装
./acme.sh --install-cert -d www.example.com --key-file /usr/local/nginx/ssl/www.example.com/key.pem --fullchain-file /usr/local/nginx/ssl/www.example.com/cert.pem
- 多域名证书安装
./acme.sh --install-cert -d www.example.com -d example.com --key-file /usr/local/nginx/ssl/www.example.com/key.pem --fullchain-file /usr/local/nginx/ssl/www.example.com/cert.pem
执行成功后,会在对应的目录下生成key.pem
和 cert.pem
步骤五:站点配置文件中配置https配置
修改站点配置文件www.example.com.conf
- 单域名站点配置
server{listen 80;#listen [::]:80;server_name www.example.com; # example.com换成对应的域名index index.html index.htm;root /home/wwwroot/www.example.com; # example.com换成对应的站点目录#error_page 404 /404.html;# 拒绝访问特定目录下的PHP文件#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; } return 301 https://$host$request_uri; access_log off;}
server{listen 443 ssl;http2 on;#listen [::]:443 ssl http2;server_name www.example.com;index index.html index.php;root /home/wwwroot/www.example.com;ssl_certificate /usr/local/nginx/ssl/www.example.com/cert.pem;ssl_certificate_key /usr/local/nginx/ssl/www.example.com/key.pem;ssl_session_timeout 5m;ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;ssl_prefer_server_ciphers on;ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";ssl_session_cache builtin:1000 shared:SSL:10m;# openssl dhparam -out /usr/local/nginx/ssl/dhparam.pem 2048ssl_dhparam /usr/local/nginx/ssl/dhparam.pem;#error_page 404 /404.html;# Deny access to PHP files in specific directory#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }access_log /home/wwwlogs/example.log;}
- 多域名站点配置
server{listen 80;#listen [::]:80;server_name www.example.com example.com; # example.com换成对应的域名index index.html index.htm;root /home/wwwroot/example.com; # example.com换成对应的站点目录#error_page 404 /404.html;# 拒绝访问特定目录下的PHP文件#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; } return 301 https://$host$request_uri; access_log off;}
server{listen 443 ssl;http2 on;#listen [::]:443 ssl http2;server_name www.example.com example.com;index index.html index.php;root /home/wwwroot/www.example.com;ssl_certificate /usr/local/nginx/ssl/www.example.com/cert.pem;ssl_certificate_key /usr/local/nginx/ssl/www.example.com/key.pem;ssl_session_timeout 5m;ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;ssl_prefer_server_ciphers on;ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";ssl_session_cache builtin:1000 shared:SSL:10m;# openssl dhparam -out /usr/local/nginx/ssl/dhparam.pem 2048ssl_dhparam /usr/local/nginx/ssl/dhparam.pem;#error_page 404 /404.html;# Deny access to PHP files in specific directory#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }access_log /home/wwwlogs/example.log;}
- 站点配置文件配置好后,重启
nginx
服务 ,通过http://www.example.com
检查是否能访问成功
访问的时候,会自动跳转到https://www.example.com
systemctl restart nginx.service
配置文件中ssl_dhparam /usr/local/nginx/ssl/dhparam.pem;
可以通过一下命令生成
openssl dhparam -out /usr/local/nginx/ssl/dhparam.pem 2048
删除acme.sh申请的证书
- 查看已安装的正式列表
./acme.sh --list
- 通过
./acme.sh --remove -d 域名
删除 - 改操作只会删除申请记录,需要手动删除相关文件目录,如
~/.acme.sh/站点_ecc目录
root@rufeike:~/.acme.sh# ./acme.sh --list
Main_Domain KeyLength SAN_Domains CA Created Renew
www.example.com "ec-256" example.com LetsEncrypt.org 2025-04-01T06:24:54Z 2025-05-30T06:24:54Z
test.example.com "ec-256" no LetsEncrypt.org 2025-03-20T13:09:12Z 2025-05-18T13:09:12Z
root@rufeike:~/.acme.sh# ./acme.sh --remove -d test.example.com
[Tue Apr 1 16:39:59 CST 2025] The domain 'test.example.com' seems to already have an ECC cert, let's use it.
[Tue Apr 1 16:39:59 CST 2025] test.example.com has been removed. The key and cert files are in /root/.acme.sh/test.example.com_ecc
[Tue Apr 1 16:39:59 CST 2025] You can remove them by yourself.