十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

免费SSL证书申请与自动化部署指南:从Let‘s Encrypt到Nginx配置

免费SSL证书申请与自动化部署指南:从Let‘s Encrypt到Nginx配置 1. 先搞清楚免费SSL证书到底能解决什么问题以及它的边界在哪如果你在给自己的网站、博客或者内部系统配置HTTPS时被付费证书的价格、复杂的申请流程或者公司繁琐的审批流程劝退那么免费SSL证书就是你最应该优先了解的工具。它解决的核心问题就是零成本、自动化地为你的域名启用HTTPS加密让浏览器地址栏显示那个代表安全的“小锁”。但很多人对免费证书有误解以为它功能弱、不稳定或者不安全。实际上像 Let‘s Encrypt 这样的免费证书颁发机构CA签发的证书其加密强度、浏览器兼容性与付费的商业证书几乎没有区别。它真正的边界在于有效期短通常90天和签发速率限制。这意味着你不能“一劳永逸”必须建立自动续期的机制。另一个关键点是通配符证书它允许你用一张证书保护一个主域名及其所有子域名例如*.example.com保护a.example.com,b.example.com这对于管理多个子站点的场景非常方便而 Let‘s Encrypt 也提供免费的DV域名验证型通配符证书。所以这篇文章的核心是如何为你的域名包括通配符申请、部署并自动化续期免费的SSL证书并避开那些新手最容易踩的坑。我会以最通用的acme.sh客户端和 Nginx 服务器为例把从零开始的完整流程拆解清楚。2. 申请前的准备域名、服务器和验证方式的选择在动手敲命令之前先确认好三件事域名控制权、服务器环境、以及验证方式。这决定了你后续操作的路径。2.1 确认你对域名的控制权这是申请免费DV证书的前提。CA机构如 Let‘s Encrypt需要通过某种方式验证你确实拥有这个域名。验证方式主要有两种HTTP-01验证在你的网站根目录下放置一个特定的验证文件CA会通过HTTP访问这个文件。这要求你的服务器80端口能从公网访问。DNS-01验证在你的域名DNS解析记录里添加一条特定的TXT记录。这不需要开放服务器端口更适合服务器在防火墙后、没有公网IP或80/443端口被封禁的场景例如某些家庭宽带、企业内部服务器。对于通配符证书Let‘s Encrypt 强制要求使用DNS-01验证。我建议如果你的服务器能开80端口优先用HTTP-01最简单。如果需要申请通配符证书或者80端口不可用那就必须用DNS-01。2.2 服务器环境与工具选择你需要一台能运行Shell命令的Linux服务器如CentOS, Ubuntu。工具方面acme.sh是目前最流行、最易用的Let‘s Encrypt客户端它纯Shell脚本编写依赖少自动续期做得好。在服务器上你需要确保有curl或wget命令。有cron或systemd timer服务用于自动续期任务。如果使用HTTP-01验证确保Web服务器如Nginx/Apache已安装并运行且你知道网站根目录如/usr/share/nginx/html。如果使用DNS-01验证你需要知道你的域名托管在哪家服务商如阿里云、Cloudflare并准备好API密钥用于自动添加DNS记录。2.3 避开第一个大坑ACME协议版本与临时目录Let‘s Encrypt 使用的ACME协议有v1和v2两个版本。v1已废弃现在必须使用v2。acme.sh默认使用v2这点不用担心。但很多新手在申请时遇到的第一个报错是关于临时目录权限的例如Can‘t create directory /home/user/.acme.sh/.http-challenges。这通常是因为脚本运行用户对家目录没有写权限。一个稳妥的做法是直接用root用户安装和运行acme.sh它会自动将证书安装到系统级位置如/root/.acme.sh并为www-data或nginx用户设置好读取权限。3. 实战使用 acme.sh 申请并安装证书HTTP与DNS验证下面我们进入实操环节。我会分HTTP-01单域名和DNS-01通配符两种场景把每一步命令和背后的逻辑讲清楚。3.1 场景一通过HTTP-01验证申请单域名证书假设你的域名是www.yourdomain.com服务器IP可公网访问80端口开放。第一步安装 acme.sh以root用户登录服务器执行一键安装脚本。它会安装到~/.acme.sh/目录并自动创建一个每日检查续期的cronjob。curl https://get.acme.sh | sh -s emailmyexample.com这里的myexample.com是你的邮箱用于接收证书过期提醒和CA通知务必填写真实有效的。安装后需要重载一下shell环境或者新开一个终端让acme.sh命令生效。source ~/.bashrc # 或者 exec $SHELL第二步签发证书HTTP验证使用--webroot模式指定你的网站根目录。acme.sh会自动在该目录下创建验证文件。acme.sh --issue -d www.yourdomain.com --webroot /usr/share/nginx/html/-d: 指定要申请证书的域名。--webroot: 指定Web服务器的根目录路径。执行后你会看到脚本自动完成域名验证、向CA申请、下载证书的全过程。成功后证书和密钥文件会存放在~/.acme.sh/www.yourdomain.com/目录下。第三步安装证书到Nginx证书文件不能直接使用~/.acme.sh/目录下的因为续期时这个目录的内容会被覆盖。我们需要将证书复制或链接到另一个固定位置比如/etc/nginx/ssl/。 首先创建目录mkdir -p /etc/nginx/ssl/www.yourdomain.com然后使用acme.sh的--install-cert命令进行安装。这个命令的好处是它会在续期证书后自动重新加载Nginx配置。acme.sh --install-cert -d www.yourdomain.com \ --key-file /etc/nginx/ssl/www.yourdomain.com/key.pem \ --fullchain-file /etc/nginx/ssl/www.yourdomain.com/fullchain.pem \ --reloadcmd systemctl reload nginx--key-file: 私钥文件存放路径。--fullchain-file: 证书链文件存放路径包含你的证书和中间CA证书Nginx配置ssl_certificate时需要用这个。--reloadcmd: 证书续期成功后要执行的命令这里是重载Nginx使新证书生效。第四步配置Nginx编辑你的Nginx站点配置文件如/etc/nginx/conf.d/yourdomain.confserver { listen 443 ssl http2; server_name www.yourdomain.com; ssl_certificate /etc/nginx/ssl/www.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/www.yourdomain.com/key.pem; # 其他SSL优化配置可选但推荐 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # 你的网站根目录配置 root /usr/share/nginx/html; index index.html; } # 可选将HTTP请求重定向到HTTPS server { listen 80; server_name www.yourdomain.com; return 301 https://$server_name$request_uri; }检查配置并重载Nginxnginx -t systemctl reload nginx现在用浏览器访问https://www.yourdomain.com应该就能看到安全锁了。3.2 场景二通过DNS-01验证申请通配符证书假设你的域名是yourdomain.com你想申请*.yourdomain.com的通配符证书。域名DNS托管在阿里云。第一步获取DNS服务商的API密钥以阿里云为例登录控制台进入“AccessKey管理”创建一个具有DNS管理权限的子用户AccessKey记下AccessKey ID和AccessKey Secret。第二步在服务器上设置API密钥环境变量acme.sh支持几十种DNS服务商的API。我们需要将密钥导出为环境变量。阿里云的变量名是Ali_Key和Ali_Secret。export Ali_Key你的AccessKey ID export Ali_Secret你的AccessKey Secret重要为了在续期时也能使用最好将这两行添加到你的shell配置文件中如~/.bashrc或~/.profile然后source一下。第三步签发通配符证书使用--dns参数并指定dns_ali阿里云DNS。acme.sh --issue -d yourdomain.com -d *.yourdomain.com --dns dns_ali第一个-d申请根域名证书有些场景需要。第二个-d *.yourdomain.com申请通配符证书。--dns dns_ali: 告诉acme.sh使用阿里云的DNS API进行验证。执行后脚本会自动调用阿里云API在你的域名下添加一条用于验证的TXT记录等待CA验证通过后再自动删除该记录。整个过程无需手动干预。第四步安装证书安装步骤与HTTP验证类似只是域名变成了yourdomain.com。mkdir -p /etc/nginx/ssl/yourdomain.com acme.sh --install-cert -d yourdomain.com \ --key-file /etc/nginx/ssl/yourdomain.com/key.pem \ --fullchain-file /etc/nginx/ssl/yourdomain.com/fullchain.pem \ --reloadcmd systemctl reload nginx注意通配符证书安装时-d参数填写主域名yourdomain.com即可它会匹配所有子域名。第五步配置Nginx通配符示例你可以用一个server块来匹配所有子域名或者为每个子域名单独配置。这里展示一个通用配置server { listen 443 ssl http2; server_name ~^(?subdomain.)\.yourdomain\.com$; # 正则匹配所有子域名 ssl_certificate /etc/nginx/ssl/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/yourdomain.com/key.pem; # ... 其他SSL配置同上 # 根据子域名动态设置根目录可选 root /var/www/$subdomain; index index.html; }4. 自动化续期与日常维护让90天有效期不再是问题免费证书90天有效期的设计初衷就是推动自动化。acme.sh在安装时已经为你创建了每日执行的cronjob可以通过crontab -l查看。它会自动检查所有已签发证书如果剩余有效期小于30天就会自动续期并执行你之前用--reloadcmd指定的命令如systemctl reload nginx。你几乎不需要手动干预。但为了确保万无一失我建议做以下几件事4.1 验证自动续期任务是否生效查看root用户的cron任务列表crontab -l你应该能看到类似这样的一行0 0 * * * “/root/.acme.sh”/acme.sh --cron --home “/root/.acme.sh” /dev/null这表示每天零点检查一次续期。4.2 手动测试续期你可以手动模拟续期过程检查是否会出错acme.sh --renew -d yourdomain.com --force--force参数强制更新即使证书没到期。测试完成后记得检查Nginx是否正常加载了新证书可以通过查看证书的过期日期确认。4.3 管理已签发的证书列出所有证书acme.sh --list查看证书信息证书文件在~/.acme.sh/yourdomain.com/目录下。fullchain.cer是证书链yourdomain.com.cer是你的证书yourdomain.com.key是私钥。撤销证书如果你不再需要某个证书可以撤销它避免占用CA的签发限额。acme.sh --revoke -d yourdomain.com4.4 关于“阿里云SSL证书免费续期”热搜词这个热搜通常指阿里云平台提供的免费单域名DV证书它也是基于类似Let‘s Encrypt的服务但通过阿里云控制台界面操作。其本质和用acme.sh申请是一样的都是自动化的DV证书。区别在于优点有中文界面对不熟悉命令行的用户更友好与阿里云其他产品如CDN、SLB集成可能更方便。需要注意的点同样需要配置自动续期阿里云可能会提供自动续期选项但务必确认是否开启通配符证书通常不免费如果你有多台非阿里云服务器证书的部署和同步需要额外步骤。我个人的建议是如果你已经在使用acme.sh这类命令行工具并且管理着多个域名或跨云服务商的服务器坚持使用它会更加统一和高效。如果只是管理一两个放在阿里云ECS上的简单网站用阿里云控制台申请也可以。5. 常见错误排查从“证书验证失败”到“SSL连接错误”在实际部署中你可能会遇到各种报错。下面我梳理一个从申请到部署的完整排查链路。5.1 申请阶段错误错误Create new order error. Le_OrderFinalize not found.或协议错误这通常表示ACME服务器端点问题。确保你的acme.sh是最新版并且使用的是ACME v2端点默认就是。可以尝试更新脚本acme.sh --upgrade。错误Verify error:Invalid response from http://yourdomain.com/.well-known/acme-challenge/xxxHTTP-01验证失败。按顺序检查域名解析是否正确指向了当前服务器IP用ping yourdomain.com或dig yourdomain.com检查。服务器80端口是否开放且未被防火墙拦截telnet yourdomain.com 80或curl -I http://yourdomain.com。Nginx/Apache配置是否正确确保对.well-known/acme-challenge路径的请求能被正确路由到本地文件系统而不是被重定向到HTTPS或反向代理到别处。一个常见的Nginx配置错误是在80端口的server块里做了全站301跳转到443这会导致验证失败。应该在验证通过后再配置重定向。错误DNS manual mode.或等待DNS验证超时DNS-01验证失败。检查环境变量Ali_Key和Ali_Secret或其他服务商变量是否设置正确且有效。该API密钥是否具有为你的域名添加/删除TXT记录的权限。DNS记录传播需要时间脚本默认等待120秒。如果超时可以尝试增加等待时间acme.sh --issue ... --dnssleep 300。5.2 部署与访问阶段错误这些错误常出现在配置Nginx或其他客户端如Postman, curl, 编程语言HTTP客户端时。Nginx报错SSL_CTX_use_PrivateKey_file或SSL_CTX_use_certificate_chain_file failed证书或私钥文件路径错误、格式错误或权限不足。检查路径ssl_certificate和ssl_certificate_key指令的路径必须绝对正确。检查文件使用cat命令查看文件内容确认是有效的PEM格式以-----BEGIN CERTIFICATE-----或-----BEGIN PRIVATE KEY-----开头。检查权限确保Nginx进程用户通常是nginx或www-data有读取这些文件的权限。建议设置证书文件权限为644私钥文件权限为600。chmod 644 /etc/nginx/ssl/yourdomain.com/fullchain.pem chmod 600 /etc/nginx/ssl/yourdomain.com/key.pem chown root:root /etc/nginx/ssl/yourdomain.com/*.pem # 所有权给root浏览器/客户端报错SSL_ERROR_BAD_CERT_DOMAIN或SSL: certificate_verify_failed证书域名与访问的域名不匹配。检查证书包含的域名SAN列表openssl x509 -in /etc/nginx/ssl/yourdomain.com/fullchain.pem -text -noout | grep -A1 “Subject Alternative Name”。确认你访问的URL中的域名完全在证书的SAN列表中。通配符证书只匹配一级子域名*.example.com不匹配foo.bar.example.com。客户端报错unable to get local issuer certificate或unable to establish SSL connection这通常是证书链不完整导致的。CA证书中间证书没有正确发送给客户端。确保Nginx配置中ssl_certificate指向的是fullchain.pem文件而不是单独的yourdomain.com.cer。fullchain.pem包含了你的证书和所有必要的中间证书。可以使用在线SSL检查工具如 SSL Labs Server Test来诊断证书链问题。关于“关闭SSL验证”的误区如Postman, curl在开发调试时你可能会搜索到curl -k或 Postman 中关闭 “SSL certificate verification” 的选项来绕过证书错误。这只是一个临时调试手段绝不能用于生产环境或正式代码。它使你的连接面临中间人攻击风险。正确的做法是解决证书本身的问题如上所述或者在客户端信任你的自签名证书对于内网环境。5.3 续期阶段错误续期失败但手动执行--renew成功通常是cron任务执行环境的问题。cron执行时环境变量如PATH,Ali_Key等可能与你的shell环境不同。确保在安装acme.sh时使用的API密钥环境变量已经通过acme.sh --install-cert命令被记录或者已经写入到了acme.sh的配置文件中~/.acme.sh/account.conf或域名目录下的domain.conf。acme.sh会自动保存这些信息供cron任务使用。续期成功但Nginx没有重载检查--reloadcmd命令是否正确以及执行cron任务的用户是否有权限执行systemctl reload nginx命令。通常root用户是有权限的。可以在cron任务中把输出重定向到一个日志文件以便排查# 编辑crontab -e修改任务为 0 0 * * * “/root/.acme.sh”/acme.sh --cron --home “/root/.acme.sh” /var/log/acme.sh.log 216. 进阶考量与安全最佳实践当你能够顺利申请和部署免费证书后为了更稳定、安全地用于生产环境还需要考虑以下几点。6.1 多服务器/多节点证书同步如果你有负载均衡或多台应用服务器证书需要部署在每一台机器上。方案有集中存储分发同步在一台“证书管理机”上运行acme.sh续期然后将续期后的证书文件通过scp、rsync或配置管理工具Ansible, SaltStack同步到所有服务器并在每台服务器上执行重载命令。使用--reloadcmd调用同步脚本在--reloadcmd中编写一个脚本该脚本首先同步证书到其他服务器然后在本地重载服务。6.2 使用备用CA或双证书策略Let‘s Encrypt 有速率限制每周每个注册域名50张证书每个域名每小时5次验证失败限制。对于超高频的签发需求或者作为灾备可以考虑配置acme.sh使用其他免费的备用CA如 Buypass、ZeroSSL。# 切换到ZeroSSL默认是Let‘s Encrypt acme.sh --set-default-ca --server zerossl # 然后照常签发证书更稳健的策略是同时维护两张来自不同CA的证书在Nginx中配置双证书以应对某一CA临时故障的情况Nginx 1.11.0 支持ssl_certificate和ssl_certificate_key指令指定多个证书。6.3 安全加固配置除了安装证书Nginx的SSL配置也至关重要可以关闭不安全的协议和加密套件提升安全性。前面已经给出了一个较安全的配置模板你还可以参考 Mozilla SSL Configuration Generator 生成更与时俱进的配置。6.4 监控与告警虽然acme.sh的自动续期很可靠但仍需监控证书过期时间使用 Zabbix、Prometheus 等监控工具监控证书文件的过期日期提前告警如小于15天。续期日志定期检查acme.sh的cron执行日志如果配置了输出确认没有静默失败。服务可用性监控网站的HTTPS端口可访问性。最后也是最重要的经验免费SSL证书的核心价值在于自动化和零成本但它要求运维人员理解其工作原理和生命周期管理。第一次部署时不要只满足于“能用”一定要走通申请 - 安装 - 配置 - 验证 - 模拟续期的完整闭环。把环境变量、文件路径、重载命令这些关键点理清楚后续的维护成本会非常低。对于绝大多数个人网站、博客、测试环境和中小型项目Let‘s Encrypt 加acme.sh的方案已经完全足够提供专业级的HTTPS安全保障。
返回列表