You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python复现openssl s_client -connect ip_addr:port -servername url命令

用Python复现openssl s_client -connect ip_addr:port -servername url的实现

这条OpenSSL命令的核心行为是:与指定的ip_addr:port建立TCP连接,在TLS握手阶段通过SNI(Server Name Indication)指定目标域名url,验证服务器证书合法性,并完成握手获取相关TLS信息。以下是匹配该行为的Python实现:

import socket
from OpenSSL import SSL

def openssl_s_client(ip_addr, port, servername):
    # 初始化兼容TLSv1.2/TLSv1.3的SSL上下文,匹配OpenSSL默认配置
    context = SSL.Context(SSL.TLS_METHOD)
    
    # 加载系统默认CA证书,覆盖常见系统路径
    ca_paths = [
        '/etc/ssl/certs/ca-certificates.crt',
        '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem',
        '/usr/local/etc/openssl/cert.pem'
    ]
    for ca_path in ca_paths:
        try:
            context.load_verify_locations(cafile=ca_path)
            break
        except Exception:
            continue
    
    # 开启严格证书验证,对应OpenSSL默认验证规则
    context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, lambda *args: None)
    
    # 建立TCP连接
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(10)
    sock.connect((ip_addr, port))
    
    # 包装为SSL连接并设置SNI
    ssl_conn = SSL.Connection(context, sock)
    ssl_conn.set_tlsext_host_name(servername.encode('utf-8'))
    
    # 执行TLS握手并处理结果
    try:
        ssl_conn.do_handshake()
        print("TLS握手成功")
        
        # 输出服务器证书核心信息,贴近OpenSSL输出格式
        peer_cert = ssl_conn.get_peer_certificate()
        print("\n服务器证书信息:")
        print(f"主题: {peer_cert.get_subject()}")
        print(f"颁发者: {peer_cert.get_issuer()}")
        print(f"有效期起始: {peer_cert.get_notBefore().decode('utf-8')}")
        print(f"有效期结束: {peer_cert.get_notAfter().decode('utf-8')}")
        
        # 验证证书链完整性
        verify_result = ssl_conn.verify_certificate()
        print("\n证书验证通过" if verify_result is None else f"\n证书验证失败: {verify_result}")
            
    except SSL.Error as e:
        print(f"TLS握手或证书验证失败: {str(e)}")
    finally:
        ssl_conn.shutdown()
        sock.close()

# 使用示例
if __name__ == "__main__":
    openssl_s_client(ip_addr="1.1.1.1", port=443, servername="cloudflare.com")

关键匹配点说明:

  • 区分IP与SNI:连接目标为ip_addr,SNI字段单独设置为servername,完全对应原命令的参数逻辑
  • 证书验证:开启SSL.VERIFY_PEER强制验证服务器证书,对齐OpenSSL默认的严格验证行为
  • 系统CA加载:遍历常见系统CA路径,确保使用与OpenSSL一致的信任根证书
  • 信息输出:补充握手状态、证书核心信息和验证结果,贴近原命令的输出内容

内容的提问来源于stack exchange,提问作者Arindam Choudhury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 18:03:11