You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过SOCKS5代理实现Socket连接并隐藏IP?

用SOCKS5代理通过原生Socket隐藏IP:可行,但要手动实现代理握手

嘿,答案是完全可行的,但有个关键前提:你不能直接用socket_connect($this->sock, $address, $port)连目标地址——因为这个函数会直接建立到目标的连接,完全绕开代理,自然没法隐藏你的真实IP。

要实现通过SOCKS5代理隐藏IP,你得手动完成SOCKS5的代理握手流程,让代理服务器帮你转发所有数据。下面给你拆解步骤和代码示例:

核心思路

  1. 先建立到SOCKS5代理服务器的Socket连接,而不是直接连目标地址;
  2. 完成SOCKS5的握手认证(如果代理不需要认证,这一步会更简单);
  3. 向代理发送“要连接的目标地址+端口”的请求;
  4. 等待代理返回连接成功的响应后,就可以通过这个Socket和目标通信了——此时目标看到的IP是代理的IP,不是你的真实IP。

简单的PHP实现示例

下面是一个不需要认证的SOCKS5代理连接示例,完成后可以发送HTTP请求到目标地址:

<?php
// 配置SOCKS5代理信息
$proxyHost = 'your-socks5-proxy.com';
$proxyPort = 1080;
// 目标地址和端口
$targetHost = 'example.com';
$targetPort = 80;

// 1. 连接SOCKS5代理
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_connect($sock, $proxyHost, $proxyPort)) {
    die("Failed to connect to proxy: " . socket_strerror(socket_last_error()));
}

// 2. 发送SOCKS5握手请求(无认证)
$handshake = pack('C3', 0x05, 0x01, 0x00);
socket_write($sock, $handshake, strlen($handshake));
// 接收握手响应
$response = socket_read($sock, 2);
if ($response !== pack('C2', 0x05, 0x00)) {
    die("SOCKS5 handshake failed");
}

// 3. 发送目标地址请求(域名格式)
$targetLen = strlen($targetHost);
$connectRequest = pack('C5', 0x05, 0x01, 0x00, 0x03, $targetLen) . $targetHost . pack('n', $targetPort);
socket_write($sock, $connectRequest, strlen($connectRequest));
// 接收连接响应
$response = socket_read($sock, 10);
$responseCode = ord($response[1]);
if ($responseCode !== 0x00) {
    die("Failed to connect to target via proxy: Code $responseCode");
}

// 4. 现在可以通过代理发送数据到目标了,比如发送HTTP请求
$httpRequest = "GET / HTTP/1.1\r\nHost: $targetHost\r\nConnection: close\r\n\r\n";
socket_write($sock, $httpRequest, strlen($httpRequest));
// 读取响应
$response = '';
while ($chunk = socket_read($sock, 1024)) {
    $response .= $chunk;
}

echo $response;

// 关闭连接
socket_close($sock);
?>

额外提醒:其实cURL也支持SOCKS5!

你之前提到cURL仅支持HTTP(S),但其实它可以通过配置参数支持SOCKS5代理,比手动写Socket简单太多了,示例:

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://example.com');
curl_setopt($ch, CURLOPT_PROXY, 'your-socks5-proxy.com:1080');
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
// 如果代理需要账号密码认证
// curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'username:password');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
?>

注意事项

  • 如果你的SOCKS5代理需要账号密码认证,握手流程会多一步:在握手响应返回需要认证后,发送包含用户名和密码的包,具体可以参考SOCKS5协议规范;
  • 手动Socket实现需要自己处理协议细节和错误场景,适合非HTTP(S)的协议需求;如果只是HTTP(S)请求,优先用cURL的SOCKS5配置更省心。

内容的提问来源于stack exchange,提问作者Родион Ларин

火山引擎 最新活动