Настроить туннельный адаптер для VPN-клиента в Ubuntu 16.04 Desktop?

Настроить туннельный адаптер для VPN-клиента в Ubuntu 16.04 Desktop?

Я пытаюсь настроить сеть для пользовательского VPN.КЛИЕНТбиблиотека.


Чего я не могу понять

Мне нужно иметь возможность пересылать трафик в обычной настройке VPN, чтобы мой скрипт C++ мог читать/писать в туннель. Если я не ошибаюсь, настройка должна быть примерно такой:

       Normal Setup           How I think my setup should be
------------------------------------------------------------
Start → Aplication → Finish    Start → Aplication → Finish
          ↓   ↑                          ↓   ↑ 
       iface-enp0s3                   iface-enp0s3
          ↓   ↑                          ↓   ↑
        interwebs                      iface-tun1
                                         ↓   ↑
                                       c++ script
                                         ↓   ↑
                                       vpn-server
                                         ↓   ↑
                                       interwebs

Я знаю, что мой скрипт C++ в настоящее время этого не делает, в настоящее время он просто считывает данные из адаптера tun1. На данный момент это все, чего я пытаюсь добиться. Однако, похоже, я не могу заставить маршруты работать должным образом.

Когда я посещаюhttp://google.comиз моей клиентской системы я хочу видеть эти пакеты, отображаемые в скрипте C++, и чтобы трафик не направлялся куда-либо еще.

Как только я смогу правильно направить весь трафикза исключением портачто VPN подключен через скрипт C++ с использованием туннельного интерфейса, я начну отправлять его через библиотеку VPN-клиента.

Насколько мне известно, скрипт C++ в настоящее время работает. Когда я пингую 10.0.0.2 (адаптер tun1), я вижу, что пакеты проходят.

Я попробовал несколько разных вещей, а именно следующее:

sudo iptables -t nat -A POSTROUTING --out-interface tun1 -j МАСКИРОВАНИЕ
sudo iptables -A ПЕРЕСЫЛКА --in-interface enp0s3 -j ПРИНЯТЬ

Это не сработало.

Примечание: я уже убедился, что это net.ipv4.ip_forwardустановлено 1, и запустил sudo sysctl -p.

Информацию о текущей настройке смотрите ниже.

Примечание: я использую Ubuntu 16.04 Desktop.


Мои текущие адаптеры

Примечание: enp0s3 — мой основной адаптер. Он работает на виртуальной машине. enp0s3 — мое подключение к интернету.

enp0s3    Link encap:Ethernet  HWaddr 08:00:27:ea:97:d2  
           inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
           inet6 addr: fe80::8ec8:60b7:f404:77c5/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:58668 errors:0 dropped:0 overruns:0 frame:0
           TX packets:39067 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000 
           RX bytes:39002535 (39.0 MB)  TX bytes:7442839 (7.4 MB)

tun1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
           inet addr:10.0.0.1  P-t-P:10.0.0.2  Mask:255.255.255.255
           inet6 addr: fe80::fed9:4107:8688:8501/64 Scope:Link
           UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
           TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:500 
           RX bytes:0 (0.0 B)  TX bytes:984 (984.0 B)

Как я настроил свой tun1адаптер

$ sudo ip tuntap add dev tun1 режим tun

$ sudo ifconfig tun1 10.0.0.1 dstaddr 10.0.0.2 вверх


Скрипт C++, который я прослушиваюtun1

 // Includes ommited.

 using namespace std;

 typedef void data_receiver(char* data, int length);

 struct receive_handle {
     data_receiver* receiver;
 } typedef receive_handle;

 // Function used to retrieve the interface.
 static int if_nametofd(char *name)
 {
     int interface = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
     ifreq ifr;
     memset(&ifr, 0, sizeof(ifr));
     ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
     if (ioctl(interface, TUNSETIFF, &ifr)) {
         perror("Cannot get TUN interface");
         exit(1);
     }

     return interface;
 }

 // Called when a packet is received from the tun0 interface.
 void received_data(char* data, int length)
 {
     // Truncate the packet so that we only see the first 15 bytes.
     // This way we don't spam the console.
     for(int i=0; i<15; ++i)
         std::cout << std::hex << (int)data[i];

     std::cout << endl;
 }

 int main()
 {
     cout << "Getting interface..." << endl;

     int iface = if_nametofd("tun1");
     cout << "Using interface: " << iface << endl;

     cout << "Creating handler..." << endl;
     receive_handle* handle = (receive_handle*)malloc(sizeof(receive_handle));
     handle->receiver = received_data;

     char packet[1024];
     cout << "Listening..." << endl;
     while (true)
     {
         if (read(iface, packet, sizeof(packet)) > 0) {
             handle->receiver(packet, sizeof(packet));
         }
     }

     return 0;
 }

Единственная цель этого скрипта — закрепиться на tun1адаптере и непрерывно считывать с него данные.


решение1

Вам необходимо изменить шлюз по умолчанию вашей рабочей станции. Если вы выполните следующую команду, вы увидите шлюз по умолчанию вашей системы.

ip route show table main
default via 1.2.3.4 dev wanif

Вы можете изменить его, используя замену ip route (man ip-route).

Лучше всего использовать трюк с Open VPN, чтобы переопределить маршрут по умолчанию, не удаляя его (--redirect-gateway def1).

Это работает путем добавления двух маршрутов, охватывающих все адресное пространство IPv4. Поскольку каждый из этих двух маршрутов более специфичен, чем маршрут по умолчанию, маршрут по умолчанию фактически переопределяется.

Это делается так:

ip route add 0.0.0.0/1 via 10.0.2.15 dev tun1
ip route add 128.0.0.0/1 via 10.0.2.15 dev tun1

где 10.0.2.15 — локальная конечная точка вашего туннеля.

Поскольку ваш скрипт должен подключаться к чему-то «через обычный интернет», чтобы обеспечить какой-то значимый сервис туннелирования, вам нужно добавить удаленную конечную точку следующим образом, чтобы избежать попадания под действие вышеуказанного правила:

ip route add 7.8.9.10/32 via 1.2.3.4 dev wanif

где 7.8.9.10 — ваша удаленная конечная точка, а 1.2.3.4 — шлюз вашего интернет-провайдера по умолчанию.

Помните основные правила маршрутизации: наиболее конкретные правила применяются поверх менее конкретных.

Связанный контент