在 Ubuntu 16.04 桌面上為 VPN 用戶端設定隧道適配器?

在 Ubuntu 16.04 桌面上為 VPN 用戶端設定隧道適配器?

我正在嘗試為自訂 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++ 腳本目前可以運行。當我 ping 10.0.0.2(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 桌面版。


我當前的適配器

注意: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 Route Replace (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 預設閘道。

請記住路由規則的基本規則:最具體的規則適用於較不具體的規則

相關內容