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

Swift下借助LibXray绕过VPN对服务器列表执行TCP Ping检测

问题分析与解决方案

核心问题定位

在LibXray连接状态下,即便添加了直连路由规则,TCP Ping流量仍可能被VPN劫持,常见原因包括:

  1. 路由规则优先级被全局代理策略覆盖,比如domainStrategy设为AsIs或IPIfNonMatch时,直连规则未触发
  2. 默认Socket复用了LibXray的全局代理套接字,而非系统原生直连套接字
  3. TCP Ping实现逻辑错误:TCP本身无PING协议,仅发送"PING"字符串不符合TCP握手规范,所谓TCP Ping实际是TCP三次握手时间测量

分步解决方案

1. 修正LibXray路由规则

确保直连规则优先级高于全局代理规则,示例配置片段:

"routing": {
  "domainStrategy": "IPOnDemand",
  "rules": [
    // 优先匹配需要直连的代理服务器域名/IP
    {
      "type": "field",
      "domain": ["proxy-server-1.example.com", "proxy-server-2.example.com"],
      "outboundTag": "direct"
    },
    {
      "type": "field",
      "ip": ["192.168.1.100", "203.0.113.5"],
      "outboundTag": "direct"
    },
    // 后续全局代理规则
    {
      "type": "field",
      "network": "tcp,udp",
      "outboundTag": "proxy"
    }
  ]
}

注意:outboundTag必须对应配置中已定义的direct出站(通常默认存在)

2. 强制使用系统原生Socket直连

不依赖LibXray套接字,直接创建绕过全局代理的Socket(以Java为例):

public class TCPDirectPing {
    public static long ping(String host, int port, int timeoutMs) {
        long start = System.currentTimeMillis();
        try (Socket socket = new Socket()) {
            // 禁用代理,强制走系统直连
            socket.setProxy(Proxy.NO_PROXY);
            socket.connect(new InetSocketAddress(host, port), timeoutMs);
            return System.currentTimeMillis() - start;
        } catch (IOException e) {
            return -1; // 连接失败标记
        }
    }
}

其他语言实现逻辑一致:Python用socket.setblocking(True)+connect_ex,Go用net.DialTimeout且不设置代理参数

3. 正确实现TCP Ping逻辑

TCP Ping核心是测量三次握手耗时,无需发送额外数据,完成握手后立即关闭即可。若要验证代理服务可用性,可发送对应协议的测试包(以SOCKS5为例):

public static boolean testSocks5(String host, int port, int timeoutMs) {
    try (Socket socket = new Socket()) {
        socket.setProxy(Proxy.NO_PROXY);
        socket.connect(new InetSocketAddress(host, port), timeoutMs);
        OutputStream out = socket.getOutputStream();
        // SOCKS5握手帧:版本5 + 1种认证方式(无认证)
        out.write(new byte[]{0x05, 0x01, 0x00});
        out.flush();
        byte[] resp = new byte[2];
        socket.getInputStream().read(resp);
        // 验证响应:版本5 + 无认证通过
        return resp[0] == 0x05 && resp[1] == 0x00;
    } catch (IOException e) {
        return false;
    }
}

4. 排查系统层面代理劫持

  • 检查系统全局代理设置:Windows的Internet选项、Linux的http_proxy环境变量,这类设置会覆盖应用层Socket配置
  • 移动端需确保APP拥有ACCESS_NETWORK_STATE权限,且未被系统强制路由所有流量至VPN

验证方法

  • 用tcpdump或Wireshark抓包,确认Ping流量从原生网卡发出,而非VPN虚拟网卡
  • 对比VPN连接前后的Ping结果,差值在10ms以内则说明直连生效

内容的提问来源于stack exchange,提问作者максим мартынов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:10:04