本文最后更新于 264 天前(2025-03-25),部分内容可能已经过时。

我现在在后端项目上 使用自签证书 对域名 172.16.99.32:1043 生成了证书和密钥。并在 nginx 中启动服务使用这个
我使用 curl 加 -K 这个参数 可以成功调用 https 的接口
但是我的前端页面服务直接使用 python http.server 启动访问的时候 无法调用这个接口。报错net::ERR_CERT_AUTHORITY_INVALID

我该怎么解决呢。因为我只是为了 加密通信,且没有域名 。是不是可以在两端互相认证证书之类的呢?


解决方案概述 by-grok3

理解问题

您的问题是前端页面(通过 Python 的 http.server 提供服务)无法调用使用自签名证书的 HTTPS 接口(172.16.99.32:1043),而使用 curl -k 可以成功调用。错误为 net::ERR_CERT_AUTHORITY_INVALID,因为浏览器默认不信任自签名证书。由于您是为了开发环境中的加密通信,且没有域名,我们需要让浏览器信任该证书。

推荐解决方案:使用 mkcert

使用 mkcert 是最方便的方法,它会生成本地信任的证书,浏览器会自动识别。步骤如下:

  • 安装 mkcert(在 macOS/Linux 上用 brew install mkcert,Windows 上从 GitHub 页面 下载)。
  • 运行 mkcert -install 安装本地 CA。
  • 为您的 IP 生成证书:运行 mkcert 172.16.99.32
  • 在 nginx 中使用新生成的证书和密钥,更新配置并重启 nginx。

完成后,浏览器应该会信任该证书,前端可以正常访问 HTTPS 接口。

替代方案:手动信任证书

如果不使用 mkcert,可以手动将现有自签名证书添加到浏览器的信任存储:

  • 导出证书文件(例如 server.crt)。
  • 根据操作系统添加至信任存储:
    • Windows:使用 certmgr.msc 导入到“受信任的根证书颁发机构”。
    • macOS:通过 Keychain Access 导入并设置为“始终信任”。
    • Linux:添加到系统 CA 存储(如 Debian 的 /etc/ssl/certs/)。
  • 重启浏览器后测试。

这个方法适合单机使用,但如果有多台机器或浏览器,操作会比较繁琐。

关于相互认证

您提到是否可以在两端相互认证证书。相互 TLS(mTLS)需要客户端和服务器都提供证书,但在开发环境中,浏览器通常不支持为任意网站提供客户端证书。由于您只需加密通信,信任服务器的证书已足够,mTLS 在此场景下可能不必要。


详细报告

背景与问题分析

您当前在后端项目中使用自签名证书为域名 172.16.99.32:1043 生成证书和密钥,并通过 nginx 提供 HTTPS 服务。使用 curl -k 可以成功调用接口,但前端页面(通过 Python 的 http.server 提供服务)访问时,浏览器报错 net::ERR_CERT_AUTHORITY_INVALID。这是因为自签名证书未由受信任的证书颁发机构(CA)签发,浏览器默认不信任。

curl -k 选项会跳过证书验证,因此能正常工作,但这在生产环境中不安全。对于浏览器,特别是在开发环境中,您希望加密通信且没有域名,解决方案需要让浏览器信任该证书。

解决方案详解

推荐方法:使用 mkcert 生成本地信任证书

mkcert 是一个专门为开发环境设计的工具,可以创建浏览器自动信任的证书。它通过安装一个本地 CA 并为指定主机(包括 IP 地址)生成证书来实现。

实施步骤
  1. 安装 mkcert

    • macOS/Linux:运行 brew install mkcert(需安装 Homebrew),或从 mkcert GitHub 页面 获取安装说明。
    • Windows:从 GitHub 发布页面 下载二进制文件,并添加到系统 PATH。
  2. 安装本地 CA

    • 运行 mkcert -install,这会将 mkcert 的根证书添加到系统信任的 CA 列表中,浏览器会自动识别。
  3. 为 IP 生成证书

    • 运行 mkcert 172.16.99.32,这会生成两个文件,例如 172.16.99.32.pem(证书)和 172.16.99.32-key.pem(密钥)。
  4. 更新 nginx 配置

    • 在 nginx 配置文件中,替换现有的证书和密钥路径为 mkcert 生成的文件。例如:
      1
      2
      
      ssl_certificate /path/to/172.16.99.32.pem;
      ssl_certificate_key /path/to/172.16.99.32-key.pem;
    • 保存配置并重启 nginx(sudo systemctl restart nginx 或相应命令)。
  5. 测试

    • 访问前端页面,通过 JavaScript 或浏览器直接请求 https://172.16.99.32:1043,浏览器应不再报错。
优势
  • mkcert 跨平台支持(Windows、macOS、Linux),适合团队开发。
  • 支持为 IP 地址生成证书,符合您的需求(mkcert GitHub 页面 明确支持 IP)。
  • 自动处理信任问题,无需手动为每个浏览器配置。
注意事项

确保 nginx 配置正确,且端口(1043)在防火墙中开放。证书适用于主机名,不涉及端口,端口由服务器配置处理。

替代方法:手动添加证书到信任存储

如果不使用 mkcert,可以手动将自签名证书添加到系统的信任证书存储中,但需要根据操作系统和浏览器进行配置。

实施步骤
  1. 导出证书

    • 找到现有自签名证书文件(例如 server.crtserver.pem)。如果没有,可以从 nginx 配置中提取。
  2. 添加至信任存储

    • Windows
      • 打开 certmgr.msc(通过运行输入)。
      • 导航至“受信任的根证书颁发机构” > “证书”。
      • 右键点击“所有任务” > “导入”,选择证书文件,按照向导完成。
    • macOS
      • 打开 Keychain Access(通过启动台搜索)。
      • 转到“文件” > “导入项目”,选择证书文件。
      • 双击导入的证书,进入“信任”选项卡,将“When using this certificate”设置为“Always Trust”。
    • Linux
      • 过程因发行版不同而异。例如,在 Debian/Ubuntu 上,将证书复制到 /etc/ssl/certs/,然后运行 update-ca-certificates
  3. 重启浏览器

    • 关闭并重新打开浏览器,确保新信任的证书生效。
  4. 测试

    • 访问 https://172.16.99.32:1043,确认错误消失。
局限性
  • 需要为每台机器和每个浏览器重复操作,适合单机开发,不适合团队。
  • 配置过程可能因浏览器版本和操作系统不同而复杂。

关于相互认证(mTLS)

您提到是否可以在两端相互认证证书。这涉及到相互 TLS(mTLS),即客户端和服务器都提供证书进行身份验证。在生产环境中,这常用于内部网络以增强安全性。

然而,在您的开发场景中:

  • 浏览器通常不支持为任意网站提供客户端证书,配置复杂。
  • 您只需加密通信,信任服务器的证书已足够。
  • mTLS 在开发环境中可能不必要,且实施成本较高。

因此,建议专注于让浏览器信任服务器证书,而非实现 mTLS。

额外考虑

CORS 问题

由于前端通过 Python 的 http.server 提供服务(通常为 HTTP,例如 http://localhost:8000),而后端为 HTTPS(https://172.16.99.32:1043),它们被视为不同来源(协议不同)。如果前端通过 JavaScript(如 fetch 或 XMLHttpRequest)请求后端,可能遇到 CORS 错误。

解决方法:

  • 将前端也通过 HTTPS 提供服务(例如使用 mkcert 为前端生成证书)。
  • 在后端(nginx)配置 CORS,允许来自前端的请求。例如,在 nginx 中添加:
    1
    2
    3
    
    add_header Access-Control-Allow-Origin http://localhost:8000;
    add_header Access-Control-Allow-Methods GET, POST, OPTIONS;
    add_header Access-Control-Allow-Headers Authorization, Content-Type;
  • 测试后确保请求正常。
IP 地址证书的特殊性

证书通常为域名签发,但也支持 IP 地址。浏览器会接受 IP 地址的证书,只要信任该证书。mkcert 明确支持 IP 地址生成证书(mkcert GitHub 页面),因此不会出现问题。

总结

对于开发环境,推荐使用 mkcert 生成本地信任的证书,步骤简单且适合团队使用。如果不方便安装额外工具,可以手动将证书添加到信任存储,但操作较繁琐。关于相互认证,mTLS 在此场景下不必要,信任服务器证书已满足加密通信需求。


关键引用