Клиент не может ответить ACK после получения SYN / ACK Сервера в среде виртуального сетевого интерфейса - PullRequest
3 голосов
/ 11 июня 2019

Я устанавливаю локальную среду vpn и хочу захватывать трафик локально через интерфейс виртуальной сети, а затем перенаправлять их в реальные пункты назначения через сокет привязки физического сетевого интерфейса.Однако после настройки интерфейса виртуальной сети tun я даже не могу подключиться к реальному месту назначения.

Моя тестирующая машина: Linux testing-VirtualBox 3.19.0-15-generic # 15-Ubuntu SMP Четверг 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-адрес целевого сервера в маршрутtable: 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 и обнаружил, что моя программа отправила SYN на «45.113.192.102», а «45.113.192.102» также ответил SYN, ACK.Однако после этого кажется, что моя программа не отправила ACK, что вызывает сбой подключения.Далее клиент непрерывно отправляет SYN [ложная повторная передача TCP], а сервер отвечает [повторная передача TCP] SYN, ACK.

...