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

如何使用OpenSSL BIO相关函数实现通过Squid代理的TLS连接?

通过OpenSSL BIO实现Squid代理下的TLS连接

完全可以按照你说的思路实现,这也是HTTP代理中转TLS流量的标准流程——先明文和代理完成CONNECT握手,再在同一个套接字上启用TLS加密。下面是具体的实现步骤和注意事项:

具体实现步骤

1. 创建明文TCP BIO连接代理服务器

不要一开始就用BIO_new_ssl_connect,先创建普通的TCP BIO连接Squid代理:

BIO *tcp_bio = BIO_new_connect("proxy_host:proxy_port");
if (!tcp_bio) {
    // 错误处理
}

2. 建立与代理的TCP连接

处理非阻塞场景下的连接重试:

int ret;
while ((ret = BIO_do_connect(tcp_bio)) <= 0) {
    if (!BIO_should_retry(tcp_bio)) {
        // 连接失败,错误处理
        break;
    }
    // 非阻塞模式下,等待套接字可读/可写后重试
}

3. 发送HTTP CONNECT请求并验证响应

构造CONNECT请求(替换目标服务器地址和授权信息),通过BIO_write发送:

const char *connect_req = 
    "CONNECT target_host:443 HTTP/1.1\r\n"
    "Host: target_host:443\r\n"
    "Proxy-Connection: keep-alive\r\n"
    "User-Agent: Your-Client/1.0\r\n"
    "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==\r\n"
    "\r\n";

int bytes_written = 0;
int req_len = strlen(connect_req);
while (bytes_written < req_len) {
    ret = BIO_write(tcp_bio, connect_req + bytes_written, req_len - bytes_written);
    if (ret <= 0) {
        if (!BIO_should_retry(tcp_bio)) {
            // 发送失败,错误处理
            break;
        }
        // 非阻塞等待后重试
        continue;
    }
    bytes_written += ret;
}

然后读取代理的响应,必须确认返回HTTP/1.1 200 Connection Established:

char resp_buf[1024];
int bytes_read = 0;
while ((ret = BIO_read(tcp_bio, resp_buf + bytes_read, sizeof(resp_buf) - bytes_read - 1)) > 0) {
    bytes_read += ret;
    resp_buf[bytes_read] = '\0';
    // 检查是否包含完整的响应头(以\r\n\r\n结尾)
    if (strstr(resp_buf, "\r\n\r\n")) {
        break;
    }
}
// 验证响应状态码
if (!strstr(resp_buf, "HTTP/1.1 200")) {
    // 代理授权失败,错误处理
}

4. 将TCP BIO与SSL绑定,启用TLS加密

用已有的ssl_ctx创建SSL BIO,并挂载到TCP BIO之上,后续通信自动加密:

BIO *ssl_bio = BIO_new_ssl(ssl_ctx, 1); // 第二个参数1表示自动重试
if (!ssl_bio) {
    // 错误处理
}
// 形成SSL -> TCP的BIO链
ssl_bio = BIO_push(ssl_bio, tcp_bio);

// 执行TLS握手
while ((ret = BIO_do_handshake(ssl_bio)) <= 0) {
    if (!BIO_should_retry(ssl_bio)) {
        // TLS握手失败,错误处理
        break;
    }
    // 非阻塞等待后重试
}

关键注意事项

  • 非阻塞重试逻辑:所有BIO_do_connect、BIO_write、BIO_read、BIO_do_handshake操作在非阻塞下可能返回<=0,必须通过BIO_should_retry判断是否重试,同时用select/poll监听套接字状态。
  • 授权编码正确性:Proxy-Authorization: Basic后的字符串是username:password的Base64编码,建议用OpenSSL的EVP_EncodeBlock生成,不要手动硬编码。
  • 响应完整性:读取代理响应时要确保拿到完整的HTTP头(直到\r\n\r\n),避免因部分响应导致后续逻辑出错。
  • BIO链管理:后续所有读写操作都要通过最上层的SSL BIO执行,释放资源时要正确清理整个BIO链。

内容的提问来源于stack exchange,提问作者Tommy Lin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:23:17