Ubuntu 16.04 Desktop에서 VPN 클라이언트용 터널 어댑터를 구성하시겠습니까?

Ubuntu 16.04 Desktop에서 VPN 클라이언트용 터널 어댑터를 구성하시겠습니까?

맞춤형 VPN을 위한 네트워크 설정을 구성하려고 합니다.고객도서관.


내가 알 수 없는 것

내 C++ 스크립트가 터널을 읽고 쓸 수 있도록 일반 VPN 설정에서 트래픽을 전달할 수 있어야 합니다. 내가 착각한 것이 아니라면 설정은 다음과 같아야 합니다.

       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++ 스크립트에 표시된 패킷을 보고 트래픽이 다른 곳으로 이동하지 않는 것을 보고 싶습니다.

모든 트래픽을 적절하게 라우팅할 수 있게 되면항구는 제외터널 인터페이스를 사용하여 C++ 스크립트를 통해 VPN이 연결되어 있으면 VPN 클라이언트 라이브러리를 통해 전송을 시작하겠습니다.

내가 아는 한 C++ 스크립트는 현재 작동합니다. 10.0.0.2(어댑터)를 ping하면 tun1패킷이 통과하는 것을 볼 수 있습니다.

나는 다음과 같은 몇 가지 다른 것을 시도했습니다.

sudo iptables -t nat -A POSTROUTING --out-interface tun1 -j MASQUERADE
sudo iptables -A FORWARD --in-interface enp0s3 -j ACCEPT

이것은 작동하지 않았습니다.

참고: 나는 이미 가 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 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 경로 대체(man ip-route)를 사용하여 이를 변경할 수 있습니다.

더 나은 방법은 개방형 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는 ISP 기본 게이트웨이입니다.

라우팅 규칙의 기본 규칙을 기억하세요. 가장 구체적인 규칙이 덜 구체적인 규칙보다 적용됩니다.

관련 정보