自动续签并部署 TLS 证书到多台服务器Nginx EMQX在企业或者个人项目中TLS/SSL 证书是保证 HTTPS 和 MQTT 安全的重要组成部分。为了避免证书过期导致服务中断我们可以结合acme.sh、Cloudflare DNS 和自动化脚本实现证书的自动续签和多服务器分发。本文记录一套可落地的实践方案。目录1. 使用 acme.sh 申请证书1.1 安装 acme.sh1.2 申请证书支持通配符2. 证书安装与自动部署2.1 服务器分布2.2 部署脚本示例deploy-cert.sh2.3 绑定自动部署脚本install-cert reloadcmd3. EMQX TLS 配置3.1 配置 TLS 证书路径3.2 双向认证可选4. 注意事项4.1 Nginx 重载4.2 EMQX TLS 配置4.3 配置 SSH Key 无密码登录免密登录远程服务器4.4 证书管理建议5. 总结1. 使用 acme.sh 申请证书首先确保你的域名已经在Cloudflare上配置好并开通 API Token。1.1 安装 acme.sh# 安装curlhttps://get.acme.sh|sh# 切换默认 CA 到 Lets Encryptacme.sh --set-default-ca--serverletsencrypt1.2 申请证书支持通配符acme.sh--issue\--dnsdns_cf\-dyour_domain.com\-d*.your_domain.com\--keylengthec-256注意事项--dns dns_cf使用 Cloudflare API 自动验证 DNS--keylength ec-256使用 ECC 证书更安全、更小如果使用ZeroSSL需要先注册邮箱acme.sh --register-account-myour_emailexample.com2. 证书安装与自动部署为了让续签后的证书自动分发到三台服务器Nginx EMQX可以编写一个部署脚本。2.1 服务器分布域名服务器 IP部署路径服务your_domain.com47.222.222.22/etc/nginx/ssl/your_domain.com.*Nginxcloud.your_domain.com63.222.222.22/mnt/data/nginx/ssl/cloud.your_domain.com.*Nginx EMQXems.your_domain.com159.222.2.222/usr/local/nginx/cert/ems.your_domain.com.*Nginx2.2 部署脚本示例deploy-cert.sh#!/bin/bashset-e# Nginx HTTPS - your_domain.comscp~/.acme.sh/your_domain.com_ecc/fullchain.cer root47.222.222.22:/etc/nginx/ssl/your_domain.com.pemscp~/.acme.sh/your_domain.com_ecc/your_domain.com.key root47.222.222.22:/etc/nginx/ssl/your_domain.com.keysshroot47.222.222.22nginx -s reload# Nginx HTTPS - cloud.your_domain.com本机Nginx EMQX 共用证书cp~/.acme.sh/your_domain.com_ecc/fullchain.cer /mnt/data/nginx/ssl/cloud.your_domain.com.pemcp~/.acme.sh/your_domain.com_ecc/your_domain.com.key /mnt/data/nginx/ssl/cloud.your_domain.com.key nginx-sreload# EMQX MQTT TLS reloademqx_ctl ssl reload# Nginx HTTPS - ems.your_domain.comscp~/.acme.sh/your_domain.com_ecc/fullchain.cer root159.222.2.222:/usr/local/nginx/cert/ems.your_domain.com.pemscp~/.acme.sh/your_domain.com_ecc/your_domain.com.key root159.222.2.222:/usr/local/nginx/cert/ems.your_domain.com.keysshroot159.222.2.222nginx -s reload说明cloud.your_domain.com因为 EMQX 使用同一证书所以cp直接拷贝到本地路径即可emqx_ctl ssl reload重新加载 EMQX 的 TLS 证书无需完整重启免密登录scp/ssh如果不想每次输入密码可配置 SSH key公钥写入远端~/.ssh/authorized_keys2.3 绑定自动部署脚本install-cert reloadcmd将证书安装动作与自动部署脚本绑定acme.sh --install-cert-dyour_domain.com\--ecc\--reloadcmd/root/deploy-cert.sh说明--reloadcmd证书每次成功更新后会自动执行该命令acme.sh默认每天会检查一次证书是否快到期小于 30 天如果是会自动续签并执行reloadcmd3. EMQX TLS 配置EMQX 支持 MQTT/TLS可通过 Dashboard 或配置文件设置证书。3.1 配置 TLS 证书路径在 EMQX Dashboard 中示例选项路径示例TLS Cert/mnt/data/nginx/ssl/cloud.your_domain.com.pemTLS Key/mnt/data/nginx/ssl/cloud.your_domain.com.keyCA Cert/mnt/data/nginx/ssl/ca.pem说明TLS Cert / TLS Key服务端证书与私钥CA Cert用于双向认证客户端的根证书可选如果不填写CA CertEMQX 默认不开启双向认证3.2 双向认证可选如需客户端证书校验准备/生成 CA 证书例如ca.pem将CA Cert填写到 Dashboard 或配置文件中重启或执行以下命令重新加载 TLSemqx_ctl ssl reload注意Dashboard 支持直接上传证书文件或填写路径使用路径时要保证 EMQX 进程对证书文件有读取权限4. 注意事项4.1 Nginx 重载确保证书路径在 Nginx 配置中正确使用nginx -t检查配置正确性重载命令nginx -s reload4.2 EMQX TLS 配置使用emqx_ctl ssl reload重新加载证书如启用双向认证确保 CA Cert 配置正确4.3 SSH 免密登录在自动化部署证书或脚本时如果每次使用scp或ssh都要输入密码会非常不方便。通过SSH Key 无密码登录可以实现自动化。4.3.1 生成本地 SSH Key在本地服务器例如你的63.222.222.22生成公私钥对# 默认生成 ed25519 算法密钥更安全推荐ssh-keygen-ted25519-Cyour_emailexample.com# 或者使用 RSA# ssh-keygen -t rsa -b 4096 -C your_emailexample.com命令执行后会提示Enter file in which to save the key (/home/user/.ssh/id_ed25519):直接回车使用默认路径或指定自定义路径例如/home/user/.ssh/auto_keyEnter passphrase (empty for no passphrase):可留空直接回车以便完全免密码生成成功后会得到两个文件~/.ssh/id_ed25519私钥绝对不要泄露~/.ssh/id_ed25519.pub公钥4.3.2 将公钥复制到远程服务器使用ssh-copy-id可以快速添加公钥到远程服务器ssh-copy-id-i~/.ssh/id_ed25519.pub rootremote_ip其中remote_ip是目标服务器 IP例如47.222.222.22。首次会提示输入远程服务器密码一次验证成功后公钥会被加入到远程的~/.ssh/authorized_keys。如果提示ssh-copy-id: command not found可以使用手动方式sshrootremote_ipmkdir -p ~/.ssh chmod 700 ~/.sshcat~/.ssh/id_ed25519.pub|sshrootremote_ipcat ~/.ssh/authorized_keyssshrootremote_ipchmod 600 ~/.ssh/authorized_keys4.3.3 配置 SSH 客户端使用指定私钥可选如果你使用了非默认路径的密钥建议在本机~/.ssh/config添加配置Host server1 HostName 47.222.222.22 User root IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes Host server2 HostName 63.222.222.22 User root IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes之后可以直接ssh server1登录无需输入密码scp file.txt server1:/etc/nginx/ssl/通过别名拷贝文件4.3.4 验证 SSH Key 登录执行sshrootremote_ip如果成功登录且不提示密码说明配置成功。如果仍提示密码常见排查点远程~/.ssh/authorized_keys是否包含正确公钥远程权限是否正确目录700文件600本地是否使用了正确的私钥路径尤其是自定义 key 的情况4.3.5 注意事项权限 / 多台服务器 / 安全权限问题本地私钥权限通常应为600否则 SSH 可能拒绝使用远程.ssh目录权限700authorized_keys权限600多台服务器每台服务器都需要将同一公钥加入各自的~/.ssh/authorized_keys安全性私钥不要泄露如果机器多人可访问建议给私钥设置 passphrase自动化部署配置完成后部署脚本中的scp和ssh将无需输入密码可与acme.sh的自动续签脚本配合实现全自动证书分发4.4 证书管理建议优先使用 ECC 证书--keylength ec-256如果多个域名共用同一证书确保证书配置与部署路径一致5. 总结通过acme.sh Cloudflare API 自动部署脚本可以实现证书自动续签自动分发到多台服务器自动重载 Nginx 和 EMQX 服务优点避免证书过期导致服务中断支持多台服务器同步可扩展到更多服务如 MQTT、WebSocket建议直接使用acme.sh的内置自动检测续签机制对远程服务器使用 SSH key记录每次续签与部署日志方便排查问题
自动续签并部署 TLS 证书到多台服务器(Nginx + EMQX)
自动续签并部署 TLS 证书到多台服务器Nginx EMQX在企业或者个人项目中TLS/SSL 证书是保证 HTTPS 和 MQTT 安全的重要组成部分。为了避免证书过期导致服务中断我们可以结合acme.sh、Cloudflare DNS 和自动化脚本实现证书的自动续签和多服务器分发。本文记录一套可落地的实践方案。目录1. 使用 acme.sh 申请证书1.1 安装 acme.sh1.2 申请证书支持通配符2. 证书安装与自动部署2.1 服务器分布2.2 部署脚本示例deploy-cert.sh2.3 绑定自动部署脚本install-cert reloadcmd3. EMQX TLS 配置3.1 配置 TLS 证书路径3.2 双向认证可选4. 注意事项4.1 Nginx 重载4.2 EMQX TLS 配置4.3 配置 SSH Key 无密码登录免密登录远程服务器4.4 证书管理建议5. 总结1. 使用 acme.sh 申请证书首先确保你的域名已经在Cloudflare上配置好并开通 API Token。1.1 安装 acme.sh# 安装curlhttps://get.acme.sh|sh# 切换默认 CA 到 Lets Encryptacme.sh --set-default-ca--serverletsencrypt1.2 申请证书支持通配符acme.sh--issue\--dnsdns_cf\-dyour_domain.com\-d*.your_domain.com\--keylengthec-256注意事项--dns dns_cf使用 Cloudflare API 自动验证 DNS--keylength ec-256使用 ECC 证书更安全、更小如果使用ZeroSSL需要先注册邮箱acme.sh --register-account-myour_emailexample.com2. 证书安装与自动部署为了让续签后的证书自动分发到三台服务器Nginx EMQX可以编写一个部署脚本。2.1 服务器分布域名服务器 IP部署路径服务your_domain.com47.222.222.22/etc/nginx/ssl/your_domain.com.*Nginxcloud.your_domain.com63.222.222.22/mnt/data/nginx/ssl/cloud.your_domain.com.*Nginx EMQXems.your_domain.com159.222.2.222/usr/local/nginx/cert/ems.your_domain.com.*Nginx2.2 部署脚本示例deploy-cert.sh#!/bin/bashset-e# Nginx HTTPS - your_domain.comscp~/.acme.sh/your_domain.com_ecc/fullchain.cer root47.222.222.22:/etc/nginx/ssl/your_domain.com.pemscp~/.acme.sh/your_domain.com_ecc/your_domain.com.key root47.222.222.22:/etc/nginx/ssl/your_domain.com.keysshroot47.222.222.22nginx -s reload# Nginx HTTPS - cloud.your_domain.com本机Nginx EMQX 共用证书cp~/.acme.sh/your_domain.com_ecc/fullchain.cer /mnt/data/nginx/ssl/cloud.your_domain.com.pemcp~/.acme.sh/your_domain.com_ecc/your_domain.com.key /mnt/data/nginx/ssl/cloud.your_domain.com.key nginx-sreload# EMQX MQTT TLS reloademqx_ctl ssl reload# Nginx HTTPS - ems.your_domain.comscp~/.acme.sh/your_domain.com_ecc/fullchain.cer root159.222.2.222:/usr/local/nginx/cert/ems.your_domain.com.pemscp~/.acme.sh/your_domain.com_ecc/your_domain.com.key root159.222.2.222:/usr/local/nginx/cert/ems.your_domain.com.keysshroot159.222.2.222nginx -s reload说明cloud.your_domain.com因为 EMQX 使用同一证书所以cp直接拷贝到本地路径即可emqx_ctl ssl reload重新加载 EMQX 的 TLS 证书无需完整重启免密登录scp/ssh如果不想每次输入密码可配置 SSH key公钥写入远端~/.ssh/authorized_keys2.3 绑定自动部署脚本install-cert reloadcmd将证书安装动作与自动部署脚本绑定acme.sh --install-cert-dyour_domain.com\--ecc\--reloadcmd/root/deploy-cert.sh说明--reloadcmd证书每次成功更新后会自动执行该命令acme.sh默认每天会检查一次证书是否快到期小于 30 天如果是会自动续签并执行reloadcmd3. EMQX TLS 配置EMQX 支持 MQTT/TLS可通过 Dashboard 或配置文件设置证书。3.1 配置 TLS 证书路径在 EMQX Dashboard 中示例选项路径示例TLS Cert/mnt/data/nginx/ssl/cloud.your_domain.com.pemTLS Key/mnt/data/nginx/ssl/cloud.your_domain.com.keyCA Cert/mnt/data/nginx/ssl/ca.pem说明TLS Cert / TLS Key服务端证书与私钥CA Cert用于双向认证客户端的根证书可选如果不填写CA CertEMQX 默认不开启双向认证3.2 双向认证可选如需客户端证书校验准备/生成 CA 证书例如ca.pem将CA Cert填写到 Dashboard 或配置文件中重启或执行以下命令重新加载 TLSemqx_ctl ssl reload注意Dashboard 支持直接上传证书文件或填写路径使用路径时要保证 EMQX 进程对证书文件有读取权限4. 注意事项4.1 Nginx 重载确保证书路径在 Nginx 配置中正确使用nginx -t检查配置正确性重载命令nginx -s reload4.2 EMQX TLS 配置使用emqx_ctl ssl reload重新加载证书如启用双向认证确保 CA Cert 配置正确4.3 SSH 免密登录在自动化部署证书或脚本时如果每次使用scp或ssh都要输入密码会非常不方便。通过SSH Key 无密码登录可以实现自动化。4.3.1 生成本地 SSH Key在本地服务器例如你的63.222.222.22生成公私钥对# 默认生成 ed25519 算法密钥更安全推荐ssh-keygen-ted25519-Cyour_emailexample.com# 或者使用 RSA# ssh-keygen -t rsa -b 4096 -C your_emailexample.com命令执行后会提示Enter file in which to save the key (/home/user/.ssh/id_ed25519):直接回车使用默认路径或指定自定义路径例如/home/user/.ssh/auto_keyEnter passphrase (empty for no passphrase):可留空直接回车以便完全免密码生成成功后会得到两个文件~/.ssh/id_ed25519私钥绝对不要泄露~/.ssh/id_ed25519.pub公钥4.3.2 将公钥复制到远程服务器使用ssh-copy-id可以快速添加公钥到远程服务器ssh-copy-id-i~/.ssh/id_ed25519.pub rootremote_ip其中remote_ip是目标服务器 IP例如47.222.222.22。首次会提示输入远程服务器密码一次验证成功后公钥会被加入到远程的~/.ssh/authorized_keys。如果提示ssh-copy-id: command not found可以使用手动方式sshrootremote_ipmkdir -p ~/.ssh chmod 700 ~/.sshcat~/.ssh/id_ed25519.pub|sshrootremote_ipcat ~/.ssh/authorized_keyssshrootremote_ipchmod 600 ~/.ssh/authorized_keys4.3.3 配置 SSH 客户端使用指定私钥可选如果你使用了非默认路径的密钥建议在本机~/.ssh/config添加配置Host server1 HostName 47.222.222.22 User root IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes Host server2 HostName 63.222.222.22 User root IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes之后可以直接ssh server1登录无需输入密码scp file.txt server1:/etc/nginx/ssl/通过别名拷贝文件4.3.4 验证 SSH Key 登录执行sshrootremote_ip如果成功登录且不提示密码说明配置成功。如果仍提示密码常见排查点远程~/.ssh/authorized_keys是否包含正确公钥远程权限是否正确目录700文件600本地是否使用了正确的私钥路径尤其是自定义 key 的情况4.3.5 注意事项权限 / 多台服务器 / 安全权限问题本地私钥权限通常应为600否则 SSH 可能拒绝使用远程.ssh目录权限700authorized_keys权限600多台服务器每台服务器都需要将同一公钥加入各自的~/.ssh/authorized_keys安全性私钥不要泄露如果机器多人可访问建议给私钥设置 passphrase自动化部署配置完成后部署脚本中的scp和ssh将无需输入密码可与acme.sh的自动续签脚本配合实现全自动证书分发4.4 证书管理建议优先使用 ECC 证书--keylength ec-256如果多个域名共用同一证书确保证书配置与部署路径一致5. 总结通过acme.sh Cloudflare API 自动部署脚本可以实现证书自动续签自动分发到多台服务器自动重载 Nginx 和 EMQX 服务优点避免证书过期导致服务中断支持多台服务器同步可扩展到更多服务如 MQTT、WebSocket建议直接使用acme.sh的内置自动检测续签机制对远程服务器使用 SSH key记录每次续签与部署日志方便排查问题