Python-oracledb 3.0.0版本中SAN通配符域名匹配问题解析

Python-oracledb 3.0.0版本中SAN通配符域名匹配问题解析

在Python-oracledb数据库连接库升级到3.0.0版本后,用户报告了一个关于SSL/TLS证书验证的问题。本文将深入分析该问题的技术背景、产生原因以及解决方案。

问题背景

当用户将python-oracledb升级到3.0.0版本后,连接Oracle Autonomous Database(ADB)时出现了证书验证失败的错误。错误信息显示服务器证书中的名称与预期值不匹配,具体表现为无法正确识别Subject Alternative Name(SAN)中的通配符域名。

技术分析

在SSL/TLS连接建立过程中,客户端需要验证服务器证书的有效性,其中重要的一环就是检查证书中的主机名是否与连接的目标主机名匹配。现代证书通常使用两种方式指定有效域名:

  1. 主题中的通用名称(Common Name, CN)
  2. 主题备用名称(Subject Alternative Name, SAN)

在python-oracledb 3.0.0版本中,证书验证逻辑存在以下问题:

  1. 新版本没有正确处理SAN中的通配符(*)
  2. 验证顺序是先检查CN再检查SAN,不符合RFC 6125规范
  3. 通配符匹配逻辑过于简单,仅支持完全匹配

问题重现

用户连接的ADB实例地址格式为<instaceid>.adb.eu-amsterdam-1.oraclecloud.com,而服务器证书中的SAN包含:

  • adb.eu-amsterdam-1.oraclecloud.com
  • *.adb.eu-amsterdam-1.oraclecloud.com
  • *.adb.eu-amsterdam-1.oraclevcn.com

按照RFC标准,*.adb.eu-amsterdam-1.oraclecloud.com应该匹配<instaceid>.adb.eu-amsterdam-1.oraclecloud.com,但3.0.0版本无法识别这种通配符模式。

解决方案

开发团队提出了改进方案,主要包含以下关键点:

  1. 实现了完整的通配符匹配逻辑,支持多种通配符位置:

    • 前缀通配(*.example.com)
    • 后缀通配(example.*)
    • 中间通配(exa*.com)
  2. 调整了验证顺序,优先检查SAN,只有在没有匹配的SAN时才检查CN,符合RFC 6125规范

  3. 实现了多标签验证,确保通配符只匹配最左侧的标签

  4. 匹配过程不区分大小写

技术实现细节

新版本中增加了_name_matches函数,专门处理证书名称匹配逻辑:

def _name_matches(name_to_check, cert_name):
    # 检查完全匹配(不区分大小写)
    cert_name = cert_name.lower()
    name_to_check = name_to_check.lower()
    if name_to_check == cert_name:
        return True
    
    # 确保名称包含多个标签
    check_pos = name_to_check.find(".")
    cert_pos = cert_name.find(".")
    if check_pos <= 0 or cert_pos <= 0:
        return False
    
    # 确保右侧标签匹配
    if name_to_check[check_pos:] != cert_name[cert_pos:]:
        return False
    
    # 处理通配符匹配
    cert_label = cert_name[:cert_pos]
    check_label = name_to_check[:check_pos]
    if cert_label == "*":
        return True
    elif cert_label.startswith("*"):
        return check_label.endswith(cert_label[1:])
    elif cert_label.endswith("*"):
        return check_label.startswith(cert_label[:-1])
    wildcard_pos = cert_name.find("*")
    if wildcard_pos < 0:
        return False
    return check_label.startswith(cert_label[:wildcard_pos]) \
            and check_label.endswith(cert_label[wildcard_pos + 1:])

用户影响

该问题已在python-oracledb 3.1.0版本中修复。对于使用Oracle Cloud ADB服务的用户,特别是那些使用通配符证书的环境,建议升级到最新版本以获得完整的证书验证支持。

对于暂时无法升级的用户,可以通过设置ssl_server_dn_match=False来禁用证书名称验证,但这会降低连接的安全性,不建议长期使用。

总结

SSL/TLS证书验证是数据库安全连接的重要组成部分。python-oracledb 3.1.0版本改进了证书名称验证逻辑,特别是对通配符域名的支持,使其更符合行业标准和实际应用场景。这一改进确保了与Oracle Cloud ADB服务的兼容性,同时保持了高标准的安全验证。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值