返回

解决mitmproxy TLS握手失败:实用指南与方案

Linux

mitmproxy TLS 握手失败的解决之道

使用 mitmproxy 这类中间人代理工具时,在 Linux 系统上安装证书后,如果遇到 TLS 握手失败,会让人很困扰。浏览器可能会报告证书不受信任或无法建立安全连接,即便已将证书添加到系统信任存储区。 理解问题根源是有效解决问题的关键。

理解 TLS 握手失败的原因

通常,TLS 握手失败是由于以下几种原因造成的:

  • 证书未被浏览器或操作系统信任 : 即使证书安装到了信任存储区,浏览器也可能由于其他策略(例如,证书扩展不兼容或浏览器内置的证书颁发机构列表未更新)而拒绝信任该证书。
  • 证书的 CN(Common Name)或 SAN(Subject Alternative Name)与访问域名不匹配 :如果证书上声明的域名和浏览器实际请求的域名不符,会触发证书验证失败。
  • 代理服务器的配置问题 :mitmproxy 可能配置不当,或者使用了不支持的协议或加密套件。
  • 系统或应用程序层面的缓存问题 :之前失败的连接可能导致缓存了不好的结果,即便配置已修复,仍可能持续失败。

解决步骤和示例

以下步骤了针对这些常见问题采取的解决方案,并且提供了对应的代码和操作说明。

方案一:重新生成自签名证书

当遇到浏览器持续拒绝接受证书的情况时,可能需要重新生成自签名证书。 这个过程中,需要重点关注以下几个方面,例如,包含有效的SAN (Subject Alternative Name), 使用 SHA-256 或更高级别的散列算法:

操作步骤:

  1. 创建新的证书配置文件:
    创建一个名为 openssl.cnf 的文件,并使用以下内容替换默认内容,这将包含 SAN 配置:

    [req]
    distinguished_name = req_distinguished_name
    x509_extensions = v3_req
    prompt = no
    [req_distinguished_name]
    CN = localhost
    [v3_req]
    keyUsage = digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = localhost
    IP.1 = 127.0.0.1
    

    确保在 [alt_names] 部分加入 DNS.1 = localhostIP.1 = 127.0.0.1。 这里可以按需增加更多的 SAN 记录。

  2. 生成新的证书密钥对:

    使用 openssl 工具生成新的密钥对(mitmproxy.pem 为私钥,mitmproxy.crt 为证书文件)。 运行下面命令:

 openssl req -x509 -newkey rsa:4096 -keyout mitmproxy.pem -out mitmproxy.crt -days 365 -nodes -config openssl.cnf -sha256
`days 365` 指定证书有效期为一年,`-nodes` 指示生成不加密的私钥(虽然并不建议生产环境这样做),`-sha256` 使用 SHA256 算法保证安全,同时必须包含前面创建好的 `openssl.cnf` 配置文件,以此增加 SAN 记录。
  1. 替换 mitmproxy 证书

将生成的 mitmproxy.crtmitmproxy.pem 放到 mitmproxy 预期的证书目录(通常位于 $HOME/.mitmproxy)下,并且确保其文件权限正确,mitmproxy 服务可以访问和读取这些文件。 同时记得覆盖已有的 mitmproxy-ca.pem 证书。

  1. 更新系统信任存储

mitmproxy.crt 文件添加到操作系统和浏览器的受信任根证书列表中,不同操作系统的操作步骤不一样。 在 Debian/Ubuntu 等 Linux 发行版上, 可以使用 sudo cp mitmproxy.crt /usr/local/share/ca-certificates/ 将其复制到 ca-certificates 目录,然后运行 sudo update-ca-certificates更新信任列表。 具体操作方式需要查询你当前系统对应添加证书的方式。
5. 重启 mitmproxy
完成证书更新后,重启 mitmproxy 服务以应用更改。

方案二:检查浏览器缓存和设置

浏览器可能会缓存 TLS 连接信息,即使证书已正确更新,也可能导致握手失败。 可以通过以下操作来排除缓存干扰:

操作步骤:

  1. 清除浏览器缓存和 Cookie

清除浏览器缓存、Cookie和站点数据,或直接使用无痕/隐私模式测试连接。 这些选项通常位于浏览器设置或历史记录中,各浏览器界面略有不同。
2. 检查浏览器安全设置

确保浏览器的安全设置没有过度严格,阻止自签名证书或混合内容(HTTPS 页面中包含 HTTP 内容)。在高级安全设置里查找并检查相关的策略是否配置妥当。

方案三:mitmproxy 配置检查

确保 mitmproxy 配置文件 (config.yaml 或类似) 使用正确的 TLS 协议版本和加密套件。 一些旧的或不安全的配置可能会导致握手失败,可以通过更新配置进行解决。

操作步骤:

  1. 编辑配置文件:
    找到 mitmproxy 的配置文件,通常在 $HOME/.mitmproxy 目录下。 查找与 TLS/SSL 协议配置相关的参数,确保使用的是当前版本的TLS,而不是过时的 SSL v3 或 TLS v1.0,优先使用 TLS v1.2 及更高版本。 例如, ssl_version 或者 ciphers 参数。 可以设置 ssl_version: tls1.2. tls1.3 等等。

  2. 应用配置更改
    重启 mitmproxy 使配置生效。

 mitmproxy
如果使用不同的启动方式,按对应的规则进行重启。

其他建议

  • 保持软件更新: 定期更新操作系统和 mitmproxy 到最新版本,这有助于避免兼容性问题,并修复潜在的安全漏洞。
  • 使用强密码: 在使用证书或进行任何身份验证时,使用高强度的密码。
  • 注意端口冲突: 检查其他应用程序是否使用了 mitmproxy 使用的端口。
  • 逐步排查: 先简化 mitmproxy 配置,如使用简单的代理模式测试证书是否生效。排除故障后,逐渐增加复杂的功能,进行更全面的测试。

遇到 mitmproxy TLS 握手失败并非无法解决的问题。按照上述步骤,一步步排除故障,理解问题产生的根源,往往能高效地定位问题并有效解决。