Я устанавливаю локальную среду 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.