3

我正在设置一个本地 vpn 环境,我想通过虚拟网络接口在本地捕获流量,然后通过物理网络接口绑定套接字将它们转发到真实目的地。但是,设置 tun 虚拟网络接口后,我什至无法连接真实目的地。

我的测试机:Linux testing-VirtualBox 3.19.0-15-generic #15-Ubuntu SMP Thu Apr 16 23:32:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

首先,我成功创建了一个名为 tun0 的虚拟网络接口,如下所示:

      tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
      inet addr:192.168.2.1  P-t-P:192.168.2.1  Mask:255.0.0.0
      UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:500 
      RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

为简洁起见,我只是将目标服务器的 ip 地址添加到路由表中: route add -host 45.113.192.102 dev tun0 路由表如下: 内核 IP 路由表

     Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
     0.0.0.0         xxx.xx.xxx.xxx   0.0.0.0         UG        0 0          0 eth0
     45.113.192.102  0.0.0.0         255.255.255.255 UH        0 0          0 tun0
     xxx.xx.xxx.xxx   0.0.0.0         255.255.255.128 U         0 0          0 eth0
     192.0.0.0       0.0.0.0         255.0.0.0       U         0 0          0 tun0

xxx.xx.xxx.xxx 是我的内部主机/网关 IP 地址。

最后,我创建了一个套接字并将套接字绑定到物理网络接口。我在这里使用 libuv,应该不管这个问题。

struct sockaddr_in remote_addr;
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = ntohs(443);
inet_pton(AF_INET, "45.113.192.102", &remote_addr.sin_addr);
uv_os_sock_t sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
    std::cout << "ERROR--- create socket failed\n";
    return -1;
}
int32_t r;
r = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, "eth0", strlen("eth0"));
if (r != 0) {
    std::cout << "setsockopt failed: " << errno;
    return -1;
}

uv_tcp_init(g_uv_loop, &socket_handle);
r = uv_tcp_open(&socket_handle, sock);
uv_connect_t connect_req;
r = uv_tcp_connect(&connect_req, &socket_handle,
        (struct sockaddr *) &remote_addr, _tcp_connect_cb);

我运行我的代码,发现我无法连接到“45.113.192.102”。我通过wireshark抓到流量,发现我的程序已经向“45.113.192.102”发送了SYN,“45.113.192.102”也回复了SYN,ACK。但是,在那之后似乎我的程序没有发送 ACK,导致连接失败。接下来,Client不断发送[TCP Spurious Retransmission] SYN,Server回复[TCP Retransmission] SYN,ACK。

4

0 回答 0