ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Nginx Proxy Manager 证书管理全攻略:HTTP、DNS 与自定义证书的签发、续期与源码原理

Nginx Proxy Manager 证书管理全攻略:HTTP、DNS 与自定义证书的签发、续期与源码原理 Nginx Proxy Manager 证书管理全攻略HTTP、DNS 与自定义证书的签发、续期与源码原理【免费下载链接】nginx-proxy-managerDocker container for managing Nginx proxy hosts with a simple, powerful interface项目地址: https://gitcode.com/GitHub_Trending/ng/nginx-proxy-manager本文围绕 Nginx Proxy Manager 的证书模块展开系统讲解其提供的三类证书——Lets Encrypt HTTP 验证证书、Lets Encrypt DNS 验证证书与自定义证书——的适用场景、前置条件与完整签发流程并结合仓库源码剖析签发、续期、吊销的底层实现。读完本文你将掌握在 Nginx Proxy Manager 中正确选择证书类型、配置 DNS 服务商插件、规避常见坑点如通配符支持、HTTP 可达性要求的完整实战方案。证书体系概览三种证书怎么选Nginx Proxy Manager 在Certificates证书页面统一管理三类证书其核心区别在于验证方式与适用场景。下表对关联文档 frontend/src/locale/src/HelpDoc/zh/Certificates.md 所述内容进行归纳维度HTTP 证书DNS 证书自定义证书颁发方Lets EncryptLets Encrypt你自己的证书颁发机构CA验证方式HTTPHTTP-01Lets Encrypt 服务器通过 HTTP 访问你的域名DNSDNS-01通过 DNS 服务商插件创建临时 DNS 记录无需验证直接上传前置条件必须先创建可经 HTTP 访问、指向本 Nginx 安装的代理主机无需预先创建代理主机无需配置 HTTP 访问无需任何 Nginx 配置通配符域名*.example.com不支持支持取决于证书本身续期要求代理主机需始终保持 HTTP 访问可用凭据有效即可自动续期到期需自行更新三种证书入口分别对应前端三个弹窗组件HTTP 证书对应 frontend/src/modals/HTTPCertificateModal.tsx、DNS 证书对应 frontend/src/modals/DNSCertificateModal.tsx、自定义证书对应 frontend/src/modals/CustomCertificateModal.tsx证书列表页见 frontend/src/pages/Certificates/Table.tsx。HTTP 证书基于 HTTP-01 挑战的签发流程原理与前置条件HTTP 验证证书的核心机制是Lets Encrypt 服务器将通过 HTTP而非 HTTPS访问你的域名如果访问成功即证明你拥有该域名的控制权随后为你颁发证书。这在 frontend/src/locale/src/HelpDoc/zh/Certificates.md 中已明确强调HTTP 而非 HTTPS。使用此方法必须满足为你的域名创建一个可通过 HTTP 访问、并指向此 Nginx 安装的代理主机Proxy Host签发成功后你可以修改该代理主机使其同时使用此证书处理 HTTPS 连接为了证书能够续期该代理主机仍需保持 HTTP 访问配置——这是新手最容易踩的坑签发后把 HTTP 关闭或强制跳转 HTTPS会导致后续续期失败。此过程不支持通配符域名。签发流程源码解读后端 backend/internal/certificate.js 的create方法完整实现了 HTTP 证书签发其流程注释清晰地分为 6 步见L128-L137查找占用域名的所有主机调用internalHost.getHostsWithDomains(certificate.domain_names)找出所有使用了该证书域名的代理主机、重定向主机、404 主机临时禁用这些主机disableInUseHosts会通过internalNginx.bulkDeleteConfigs批量删除相关 nginx 配置避免与 ACME 挑战路径冲突生成 Lets Encrypt 请求配置调用internalNginx.generateLetsEncryptRequestConfig(certificate)生成临时的letsencrypt-request.conf配置请求证书调用requestLetsEncryptSsl执行 certbot 命令删除临时配置internalNginx.deleteLetsEncryptRequestConfig(certificate)恢复此前禁用的主机enableInUseHosts调用bulkGenerateConfigs重新生成并加载配置。requestLetsEncryptSslL777-L817底层构造的 certbot 命令参数如下certbot certonly -n --config /etc/letsencrypt.ini \ --work-dir /tmp/letsencrypt-lib --logs-dir /data/logs \ --cert-name npm-证书ID --agree-tos \ --authenticator webroot -m 你的邮箱 \ --preferred-challenges http \ --domains 逗号分隔的域名列表 \ [--key-type rsa|ecdsa]要点解析--authenticator webroot使用 webroot 验证方式配合模板 backend/templates/letsencrypt-request.conf 中的 ACME 挑战路径/data/letsencrypt-acme-challenge/.well-known/acme-challenge/完成 HTTP-01 应答--cert-name npm-证书ID证书在/etc/letsencrypt/live/npm-证书ID目录下的命名规则见getLiveCertPathL1262-L1264--key-type可选参数默认前端表单会给出rsa/ecdsa两种密钥类型选项见 frontend/src/modals/HTTPCertificateModal.tsx 的meta.keyType字段请求证书要求用户账户配置有效邮箱L145-L150否则抛出必须设置有效邮箱才能使用 Lets Encrypt的校验错误。HTTP 可达性测试HTTP 证书弹窗提供Test测试按钮用于在真正提交前验证域名是否可从公网经 HTTP 访问。前端调用testHttpCertificateAPI见 frontend/src/api/backend/testHttpCertificate.ts后端路由为POST /api/nginx/certificates/test-httpbackend/routes/nginx/certificates.jsL115-L138实现位于internalCertificate.testHttpsChallengeL1120-L1236在/data/letsencrypt-acme-challenge/.well-known/acme-challenge/写入test-challenge测试文件内容为Success对每个域名发起外部 HTTP 请求http://domain/.well-known/acme-challenge/test-challenge根据响应结果返回状态ok响应 200 且内容正确、no-host域名无法解析、404服务器存在但返回 404、wrong-data返回数据错误、failed/other:code其他错误。前端 HTTPCertificateModal.tsx 的parseTestResults会对这些状态逐条渲染为可读结果便于你在提交前定位 DNS 解析或代理配置问题。DNS 证书基于 DNS-01 挑战与插件体系原理与优势DNS 验证证书要求你使用一个DNS 服务商插件DNS Provider plugin。该插件被用于在域名下创建临时记录随后 Lets Encrypt 查询这些记录以确认你是域名所有者验证成功即颁发证书。相比 HTTP 证书DNS 证书有两个显著优势原文明确强调无需预先创建代理主机也无需将代理主机配置为支持 HTTP 访问——适合证书先于站点上线的场景支持通配符域名如*.example.com这是签发泛域名证书的唯一官方路径。DNS 服务商插件清单支持哪些服务商由配置文件 backend/certbot/dns-plugins.json 定义后端GET /api/nginx/certificates/dns-providers接口backend/routes/nginx/certificates.jsL79-L108会将该清单按名称排序后返回给前端下拉框。插件清单覆盖国内外主流服务商例如Cloudflaredns-cloudflare凭据dns_cloudflare_api_tokenAPI Token阿里云Aliyundns-aliyun凭据dns_aliyun_access_keydns_aliyun_access_key_secret腾讯云Tencent Clouddns-tencentcloud凭据dns_tencentcloud_secret_iddns_tencentcloud_secret_keyDNSPoddns-dnspod凭据dns_dnspod_emaildns_dnspod_api_tokenAWS Route 53dns-route53凭据为 AWS 凭证文件格式aws_access_key_idaws_secret_access_keyGoogle / GoDaddy / OVH / DigitalOcean / Hetzner / Vultr / Namecheap等上百家服务商每个插件条目包含full_plugin_namecertbot 认证器名、package_namepip 包名、version与credentials凭据模板例如 Cloudflare 条目为cloudflare: { credentials: # Cloudflare API token\ndns_cloudflare_api_token0123456789abcdef0123456789abcdef01234567, full_plugin_name: dns-cloudflare, name: Cloudflare, package_name: certbot-dns-cloudflare, version: {{certbot-version}} }凭据模板会展示在前端 DNS 提供商字段组件 frontend/src/components/Form/DNSProviderFields.tsx 中供用户按格式填写。DNS 挑战签发流程requestLetsEncryptSslWithDnsChallengeL824-L889的签发流程与 HTTP 路径不同其关键差异在于按需安装插件调用installPlugin(certificate.meta.dns_provider)实现见 backend/lib/certbot.js根据dns-plugins.json中的package_name与version通过 pip 安装对应 certbot 插件凭据落盘将用户填写的dns_provider_credentials写入/etc/letsencrypt/credentials/credentials-证书ID文件权限为0o600仅属主可读写保护敏感凭据构造 certbot 命令使用--preferred-challenges dns、--authenticator full_plugin_name并通过--plugin-credentials传入凭据文件其中route53 是特例hasConfigArg为 false改为通过环境变量AWS_CONFIG_FILE传递凭据见getAdditionalCertbotArgsL1238-L1260可选传播等待若设置meta.propagation_seconds会追加--plugin-propagation-seconds 秒数参数用于等待 DNS 记录全球生效无临时 nginx 配置由于 DNS-01 不依赖 HTTP 路径create方法中 DNS 挑战分支L153-L166跳过生成 LE 配置/删除配置两步只需临时禁用占域主机后请求、再恢复。另外DNS 证书的密钥类型keyType同样支持rsa/ecdsa选择默认ecdsa见 frontend/src/modals/DNSCertificateModal.tsx 的 initialValues。自定义证书上传自有 SSL 证书适用场景自定义证书用于上传由**你自己的证书颁发机构CA**签发的 SSL 证书典型场景包括企业内网自建 CA、商业证书如从云厂商购买的 SSL 证书、或已有权威证书需要导入统一管理。原文将其定义为使用此选项上传您自己的 SSL 证书该证书由您自己的证书颁发机构提供。上传与验证流程前端 frontend/src/modals/CustomCertificateModal.tsx 的上传流程分为三步见其onSubmit填写名称niceName1~255 字符并选择 provider 为other选择三个可选文件证书certificate、私钥certificate_key、中间证书intermediate_certificate构造FormData后先调用validateCertificate进行预校验依次调用createCertificate创建空证书记录、uploadCertificate(cert.id, formData)上传文件内容。后端对应三个接口backend/routes/nginx/certificates.jsPOST /api/nginx/certificates/validate预校验L145-L172POST /api/nginx/certificates创建证书记录L64-L74POST /api/nginx/certificates/:certificate_id/upload上传文件L244-L272。后端internalCertificate.validateL554-L588只接收三类允许文件allowedSslFiles [certificate, certificate_key, intermediate_certificate]L32并分别处理私钥通过openssl pkey -in file -check -noout校验checkPrivateKeyL632-L653带 10 秒超时保护防止口令保护密钥导致挂起证书与中间证书通过openssl x509 -in file -subject/-issuer/-dates -noout提取 CN、签发者与有效期getCertificateInfo/getCertificateInfoFromFileL662-L748若throwExpired为 true 且证书已过期则抛错。upload成功后证书内容由writeCustomCertL487-L530写入/data/custom_ssl/npm-证书ID/目录fullchain.pem证书 中间证书拼接与privkey.pem供 nginx 配置引用同时从证书中提取的 CN 与到期时间会被写回数据库记录expires_on、domain_names。证书生命周期续期与吊销自动续期机制Nginx Proxy Manager 内置自动续期定时器源码位于internalCertificateL31-L110intervalTimeout 1000 * 60 * 60即每小时检查一次renewBeforeExpirationBy [30, days]即到期前 30 天开始续期initTimer在服务启动时立即执行一次processExpiringHosts此后每小时触发查询条件为provider letsencrypt且expires_on 当前时间 30 天且未删除的证书续期必须串行执行源码注释明确说明原因否则会报错Another instance of Certbot is already runningL74-L76因此代码用 Promise 链逐个续期单个失败只记录错误不中断后续证书L92-L95。续期命令renewLetsEncryptSslL933-L968使用certbot renew --force-renewal --cert-name npm-证书ID --preferred-challenges http|dns并携带--no-random-sleep-on-renew与--disable-hook-validation参数DNS 证书则走renewLetsEncryptSslWithDnsChallenge分支L974-L1014按证书的meta.dns_provider选择对应插件续期。用户也可以在界面上手动续期前端对应 frontend/src/modals/RenewCertificateModal.tsx后端路由POST /api/nginx/certificates/:certificate_id/renewbackend/routes/nginx/certificates.jsL279-L302超时设置为 15 分钟续期成功后会在审计日志中记录renewed动作并更新expires_onL897-L927。吊销与下载删除证书DELETE /api/nginx/certificates/:certificate_idL227-L237调用internalCertificate.deleteL396-L423对 Lets Encrypt 证书软删除is_deleted 1后会执行revokeLetsEncryptSslL1021-L1055发起certbot revoke --cert-path .../fullchain.pem --delete-after-revoke主动吊销并清理凭据文件下载证书GET /api/nginx/certificates/:certificate_id/downloadL309-L331仅对 Lets Encrypt 证书开放自定义证书会收到校验错误将从/etc/letsencrypt/live/npm-证书ID/收集所有.pem文件打包为npm-证书ID-时间戳.zip供下载download/zipFilesL341-L387。证书与主机的关联使用证书创建完成后即可在代理主机Proxy Host、重定向主机Redirection Host、404 主机Dead Host与四层流Stream中引用。数据模型 backend/models/certificate.js 定义了这些关联关系proxy_hostscertificate.id - proxy_host.certificate_iddead_hostscertificate.id - dead_host.certificate_idredirection_hostscertificate.id - redirection_host.certificate_idstreamscertificate.id - stream.certificate_idowner证书归属用户因此GET /api/nginx/certificates支持expand参数一次性带出该证书被哪些主机使用getAll/cleanExpansionsL433-L463前端证书列表用此能力渲染使用中In Use状态见 frontend/src/components/Table/Formatter/CertificateInUseFormatter.tsx。这也解释了为何签发新证书时系统要临时禁用占域主机——正是为了在 nginx 层面保证 ACME 挑战路径不被业务站点配置干扰。常见问题排查要点HTTP 证书签发/续期失败优先检查域名是否已通过 HTTP 公网可达80 端口未被防火墙拦截、代理主机已启用且指向本 Nginx可用弹窗内Test按钮先做可达性验证通配符域名签发失败确认选的是 DNS 证书而非 HTTP 证书HTTP-01 不支持通配符DNS 证书签发失败检查 DNS 服务商 API 凭据是否与 backend/certbot/dns-plugins.json 中该服务商的credentials模板格式一致必要时增大propagation_seconds等待 DNS 记录生效证书到期未自动续期确认证书provider为letsencrypt、账户邮箱有效、且距到期不足 30 天若属于 HTTP 证书还需确认代理主机仍保留 HTTP 访问自定义证书报Certificate is not valid检查私钥是否带口令保护后端会超时拒绝、证书是否已过期、私钥与证书是否匹配。上述界面与接口行为均有对应源码支撑深入实现细节可继续阅读 backend/internal/certificate.js、backend/routes/nginx/certificates.js 与前端三个证书弹窗组件形成从界面操作到 certbot 命令执行的完整闭环认知。【免费下载链接】nginx-proxy-managerDocker container for managing Nginx proxy hosts with a simple, powerful interface项目地址: https://gitcode.com/GitHub_Trending/ng/nginx-proxy-manager创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表