HTTPS免费证书安装文档(CentOS 8.2,acme.sh方案)
一、文档说明
- 适用系统:CentOS Linux release 8.2.2004 (Core)
- 适用域名:gqliu.cn、www.gqliu.cn(两个域名共用一张证书)
- 证书方案:acme.sh + ZeroSSL(免费、自动续期、无额度限制)
- 替代目标:阿里云免费证书(额度用尽,无需依赖阿里云)
- 证书文件名:保持原有格式(gqliu.cn.key、gqliu.cn.pem),无需修改Nginx配置
- 核心优势:一次安装,永久自动续期,无需手动操作,全程命令行完成
二、前期准备
- 服务器已安装Nginx(确保能正常启动、停止)
- 服务器80端口未被其他程序占用(申请证书时需临时使用)
- 域名gqliu.cn、www.gqliu.cn已解析至当前服务器IP
- 登录服务器(root用户,确保有最高权限)
三、完整安装步骤(按顺序执行,可直接复制命令)
步骤1:安装acme.sh工具(无需系统源,直接安装)
执行命令:
curl https://get.acme.sh | sh
# curl https://get.acme.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1032 0 1032 0 0 560 0 --:--:-- 0:00:01 --:--:-- 559
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 243k 100 243k 0 0 91889 0 0:00:02 0:00:02 --:--:-- 91889
[Fri May 8 14:36:13 CST 2026] Installing from online archive.
[Fri May 8 14:36:13 CST 2026] Downloading https://github.com/acmesh-official/acme.sh/archive/master.tar.gz
[Fri May 8 14:36:15 CST 2026] Extracting master.tar.gz
[Fri May 8 14:36:15 CST 2026] Installing to /root/.acme.sh
[Fri May 8 14:36:15 CST 2026] Installed to /root/.acme.sh/acme.sh
[Fri May 8 14:36:15 CST 2026] Installing alias to '/root/.bashrc'
[Fri May 8 14:36:15 CST 2026] Close and reopen your terminal to start using acme.sh
[Fri May 8 14:36:15 CST 2026] Installing alias to '/root/.cshrc'
[Fri May 8 14:36:15 CST 2026] Installing alias to '/root/.tcshrc'
[Fri May 8 14:36:15 CST 2026] Installing cron job
[Fri May 8 14:36:15 CST 2026] bash has been found. Changing the shebang to use bash as preferred.
[Fri May 8 14:36:16 CST 2026] OK
[Fri May 8 14:36:16 CST 2026] Install success!
说明:安装完成后,执行以下命令让acme.sh命令生效
source ~/.bashrc
步骤2:注册ZeroSSL账号(acme.sh默认CA,必须步骤)
执行命令(替换为自己的邮箱,随便填写即可,用于接收续期提醒,可选):
acme.sh --register-account -m tersup@163.com
示例邮箱:test@163.com(可替换为个人邮箱,不影响使用)
步骤3:停止Nginx(避免80端口占用,申请证书必需)
systemctl stop nginx
步骤4:申请证书(同时包含两个域名,standalone模式)
执行命令(无需修改,直接复制):
acme.sh --issue -d gqliu.cn -d www.gqliu.cn --standalone -k ec-256
[Fri May 8 14:43:41 CST 2026] Domains have changed.
[Fri May 8 14:43:42 CST 2026] Using CA: https://acme.zerossl.com/v2/DV90
[Fri May 8 14:43:42 CST 2026] Standalone mode.
[Fri May 8 14:43:42 CST 2026] Standalone mode.
[Fri May 8 14:43:42 CST 2026] Multi domain='DNS:gqliu.cn,DNS:www.gqliu.cn'
[Fri May 8 14:43:53 CST 2026] Getting webroot for domain='gqliu.cn'
[Fri May 8 14:43:53 CST 2026] Getting webroot for domain='www.gqliu.cn'
[Fri May 8 14:43:53 CST 2026] Verifying: gqliu.cn
[Fri May 8 14:43:53 CST 2026] Standalone mode server
[Fri May 8 14:43:56 CST 2026] Processing. The CA is processing your order, please wait. (1/30)
[Fri May 8 14:44:07 CST 2026] Pending. The CA is processing your order, please wait. (2/30)
[Fri May 8 14:44:11 CST 2026] Success
/root/.acme.sh/acme.sh: line 2693: 2175794 Terminated $_PYTHON -c "import socket,sys;s=socket.socket($_AF,socket.SOCK_STREAM);s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1);s.bind((sys.argv[2],int(sys.argv[1])));s.listen(5);res='HTTP/1.0 200 OK\r\nContent-Length: '+str(len(sys.argv[3]))+'\r\n\r\n'+sys.argv[3];
while True:
c,a=s.accept()
c.sendall(res.encode() if hasattr(res, 'encode') else res)
c.close()" "$Le_HTTPPort" "$_BIND_ADDR" "$content" 2> "$_SOCAT_ERR"
[Fri May 8 14:44:11 CST 2026] Verifying: www.gqliu.cn
[Fri May 8 14:44:11 CST 2026] Standalone mode server
[Fri May 8 14:44:14 CST 2026] Processing. The CA is processing your order, please wait. (1/30)
[Fri May 8 14:44:24 CST 2026] Pending. The CA is processing your order, please wait. (2/30)
[Fri May 8 14:44:28 CST 2026] Success
/root/.acme.sh/acme.sh: line 2693: 2176259 Terminated $_PYTHON -c "import socket,sys;s=socket.socket($_AF,socket.SOCK_STREAM);s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1);s.bind((sys.argv[2],int(sys.argv[1])));s.listen(5);res='HTTP/1.0 200 OK\r\nContent-Length: '+str(len(sys.argv[3]))+'\r\n\r\n'+sys.argv[3];
while True:
c,a=s.accept()
c.sendall(res.encode() if hasattr(res, 'encode') else res)
c.close()" "$Le_HTTPPort" "$_BIND_ADDR" "$content" 2> "$_SOCAT_ERR"
[Fri May 8 14:44:28 CST 2026] Verification finished, beginning signing.
[Fri May 8 14:44:28 CST 2026] Let's finalize the order.
[Fri May 8 14:44:28 CST 2026] Le_OrderFinalize='https://acme.zerossl.com/v2/DV90/order/WHmSxaRiAG-OT2nMB0Xg4g/finalize'
[Fri May 8 14:44:30 CST 2026] Order status is 'processing', let's sleep and retry.
[Fri May 8 14:44:30 CST 2026] Sleeping for 15 seconds then retrying
[Fri May 8 14:44:47 CST 2026] Polling order status: https://acme.zerossl.com/v2/DV90/order/WHmSxaRiAG-OT2nMB0Xg4g
[Fri May 8 14:44:48 CST 2026] Downloading cert.
[Fri May 8 14:44:48 CST 2026] Le_LinkCert='https://acme.zerossl.com/v2/DV90/cert/WPzAgOc6avtsiBwLXThMng'
[Fri May 8 14:44:53 CST 2026] Cert success.
-----BEGIN CERTIFICATE-----
MIIDfzCCAyagAwIBAgIQdtrt74lEsl9+BoPMyeYqgzAKBggqhkjOPQQDAjBGMQsw
CQYDVQQGEwJBVDEVMBMGA1UEChMMWmVyb1NTTCBHbWJIMSAwHgYDVQQDExdaZXJv
U1NMIEVDQyBEViBTU0wgQ0EgMjAeFw0yNjA1MDgwMDAwMDBaFw0yNjA4MDYyMzU5
NTlaMBMxETAPBgNVBAMTCGdxbGl1LmNuMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
QgAEV21e/93s/jvmHdVC6vaGiHjDgVS/7s5vJOImnhchQ3OUbNBhonm5nnzPimtf
4HB0vIKGb8p/G2+3WJD0S06bzaOCAicwggIjMB8GA1UdIwQYMBaAFJRFn9pRR3HV
c66sHasIchJtrXxiMB0GA1UdDgQWBBTLyhANFKXao1JHI+KsUFj5dSP/iDAOBgNV
HQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDATAT
BgNVHSAEDDAKMAgGBmeBDAECATBuBggrBgEFBQcBAQRiMGAwOQYIKwYBBQUHMAKG
LWh0dHA6Ly9jcnQuc2VjdGlnby5jb20vWmVyb1NTTEVDQ0RWU1NMQ0EyLmNydDAj
BggrBgEFBQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wggEEBgorBgEEAdZ5
AgQCBIH1BIHyAPAAdgDXbX0Q0af1d8LH6V/XAL/5gskzWmXh0LMBcxfAyMVpdwAA
AZ4GVLFKAAAEAwBHMEUCIQDjSX64+AVF+mMGvdg9RVRGrE3dXXT+hxkQqbEIjRCt
UQIga9d7SdK232mD26c41ip9NTWhxx/iyyaGLivhlvs4lwMAdgDIo8R/x7OtuTVr
AT9qehJt4zpOQ6XGRvmXrTl1mR3PmgAAAZ4GVLGVAAAEAwBHMEUCIQCQ2IvoXojH
iI7J80a6HFMNICWFioUFP9pFEhn0qfuAOwIgCcqSukjHX2Hv6Id8NpYordlQBUnF
JeT7Sf014WJBebcwIQYDVR0RBBowGIIIZ3FsaXUuY26CDHd3dy5ncWxpdS5jbjAK
BggqhkjOPQQDAgNHADBEAiAgDNbUcRAZqfN+vWbJ7DSIxd61V2jkmibhZWIhvFlN
GgIgOCqbC45CDMwdXZLSQjopJvXpcOHq9dYCdDUTDHbMl1A=
-----END CERTIFICATE-----
[Fri May 8 14:44:53 CST 2026] Your cert is in: /root/.acme.sh/gqliu.cn_ecc/gqliu.cn.cer
[Fri May 8 14:44:53 CST 2026] Your cert key is in: /root/.acme.sh/gqliu.cn_ecc/gqliu.cn.key
[Fri May 8 14:44:53 CST 2026] The intermediate CA cert is in: /root/.acme.sh/gqliu.cn_ecc/ca.cer
[Fri May 8 14:44:53 CST 2026] And the full-chain cert is in: /root/.acme.sh/gqliu.cn_ecc/fullchain.cer
[Fri May 8 14:44:55 CST 2026] ARI suggestedWindow: 2026-07-22T23:59:59Z to 2026-07-24T23:59:59Z
[Fri May 8 14:44:55 CST 2026] Next renewal time picked from ARI window: 2026-07-24T06:44:54Z
说明:
- -d 后面跟需要申请证书的域名,两个域名用空格分隔
- –standalone:临时启动内置web服务,用于CA机构验证域名所有权
- -k ec-256:使用EC算法,证书体积小、安全性高
- 执行成功提示:出现“SUCCESS”字样,代表证书申请成功
步骤5:安装证书(按原有文件名、路径部署,无缝替换旧证书)
第一步:创建证书存放目录(若已存在,执行命令无影响)
mkdir -p /etc/nginx/ssl
第二步:安装证书(生成原有文件名gqliu.cn.key、gqliu.cn.pem)
acme.sh --install-cert -d gqliu.cn \
--key-file /etc/nginx/ssl/gqliu.cn.key \
--fullchain-file /etc/nginx/ssl/gqliu.cn.pem \
--reloadcmd "systemctl restart nginx"
acme.sh --install-cert -d gqliu.cn \
> --key-file /etc/nginx/ssl/gqliu.cn.key \
> --fullchain-file /etc/nginx/ssl/gqliu.cn.pem \
> --reloadcmd "systemctl restart nginx"
[Fri May 8 14:46:42 CST 2026] The domain 'gqliu.cn' seems to already have an ECC cert, let's use it.
[Fri May 8 14:46:42 CST 2026] Installing key to: /etc/nginx/ssl/gqliu.cn.key
[Fri May 8 14:46:42 CST 2026] Installing full chain to: /etc/nginx/ssl/gqliu.cn.pem
[Fri May 8 14:46:42 CST 2026] Running reload cmd: systemctl restart nginx
[Fri May 8 14:46:42 CST 2026] Reload successful
说明:
- –key-file:私钥文件路径(保持原有文件名)
- –fullchain-file:证书文件路径(保持原有文件名)
- –reloadcmd:续期成功后自动重启Nginx,确保证书生效
步骤6:启动Nginx,完成证书部署
systemctl start nginx
验证Nginx运行状态(可选):
systemctl status nginx
提示“active (running)”,代表Nginx正常运行,证书已生效
步骤7:验证证书是否生效(可选)
- 浏览器访问:https://gqliu.cn、https://www.gqliu.cn
- 浏览器地址栏出现“小锁头”图标,代表HTTPS生效
四、自动续期相关(核心重点,存档必看)
1. 自动续期说明
- 证书有效期:90天
- 续期机制:acme.sh安装时自动添加crontab定时任务,每天凌晨自动检测证书有效期
- 续期逻辑:当证书剩余有效期小于30天时,自动申请新证书、覆盖旧文件、重启Nginx,全程无人工干预
2. 查看定时任务(确认自动续期已开启)
crontab -l
crontab -l
15 12 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
正常会显示类似内容(无需修改):
0 0 * * * “/root/.acme.sh”/acme.sh –cron –home “/root/.acme.sh” > /dev/null
3. 手动测试续期(可选,确认续期功能正常)
acme.sh --cron
无报错即代表续期功能正常,无需额外操作
五、常见问题及解决方法(存档备用)
问题1:申请证书时提示“Please update your account with an email address first”
- 原因:未注册ZeroSSL账号
- 解决:执行步骤2的注册命令,填写任意邮箱即可
问题2:申请证书失败,提示“80端口被占用”
- 原因:Nginx未停止,占用80端口
- 解决:执行命令 systemctl stop nginx,再重新执行步骤4
问题3:安装证书后,Nginx无法启动
- 原因:证书路径或文件名错误,与Nginx配置不一致
- 解决:确认证书路径为 /etc/nginx/ssl/gqliu.cn.key 和 /etc/nginx/ssl/gqliu.cn.pem,与Nginx配置文件中的证书路径一致
问题4:acme.sh命令无法识别
- 原因:未执行source ~/.bashrc,命令未生效
- 解决:执行 source ~/.bashrc 后,重新使用acme.sh命令
六、注意事项(存档重点)
- 无需再依赖阿里云证书,彻底摆脱额度限制,后续无需手动申请、替换证书
- 证书文件名、存放路径与原有阿里云证书一致,无需修改Nginx任何配置
- 禁止删除 /root/.acme.sh 目录,该目录是acme.sh工具和证书备份目录,删除会导致自动续期失效
- 若服务器重启,crontab定时任务会自动恢复,无需重新配置
- 若域名解析变更,需重新执行步骤4-6,重新申请证书
七、总结
本方案通过acme.sh工具对接ZeroSSL免费CA,实现gqliu.cn和www.gqliu.cn两个域名的HTTPS证书部署,全程命令行操作,一次安装,永久自动续期,无需手动干预,完美替代阿里云免费证书,解决额度用尽、手动续期麻烦的问题,适合长期存档、后续维护参考。