如何使用tun作为LAN和路由器之间的网关?

时间:2019-04-19 15:06:30

标签: c++ linux network-programming iptables tun

我正在尝试让局域网中的主机B通过另一个主机A作为路由器访问Internet。而且我希望数据包在主机A和主机B的两个通道之间传递。

我以编程方式在centos上设置了两个调音台。并且ifconfig这样显示主机A和B上的Tun状态。

tun1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
      inet addr:20.0.0.1  P-t-P:20.0.0.1  Mask:255.255.255.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)

tun1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
      inet addr:20.0.0.10  P-t-P:20.0.0.10  Mask:255.255.255.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)

主机A上tun的IP地址为20.0.0.1,主机B为20.0.0.10。

主机A上的物理卡为172.16.1.10、172.16.2.1.10,主机B上的物理卡为172.16.1.15、172.16.2.15。

主机B的路由是这个。

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.16.2.0      *               255.255.255.0   U     1      0        0 em2
172.16.3.0      *               255.255.255.0   U     0      0        0 em3
172.16.1.0      *               255.255.255.0   U     1      0        0 em1
20.0.0.0        *               255.255.255.0   U     0      0        0 tun1
link-local      *               255.255.0.0     U     1004   0        0 em3
default         20.0.0.1        0.0.0.0         UG    0      0        0 tun1

主机B可以ping到20.0.0.1,但是不能ping通外部网络,并且路由器(主机A)上的隧道处于静默状态。

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun1, link-type RAW (Raw IP), capture size 65535 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

考虑到B可以ping 20.0.0.1,我试图将数据包的目标从20.0.0.0传输到20.0.0.1,但这是行不通的。

iptables -t nat -A PREROUTING -s 20.0.0.0/24 -j DNAT --to-destination 20.0.0.1

我试图更改B的路由,并使用物理卡作为网关,并且B可以ping通外部网络。但是双方的屯仍然沉默。数据包直接通过物理卡而不经过tun处理,因此有关tun的程序毫无意义。

在程序中,用它们设置了两个调音

ifr.ifr_flags = dev->dev_flags;  
strncpy(ifr.ifr_name, dev->name, IFNAMSIZ);  
int err = ioctl(dev->dev_fd,TUNSETIFF,(void *)&ifr); 

标志是IFF_TUN | IFF_NO_PI

int fd = socket(AF_INET, SOCK_STREAM, 0);
int err = ioctl(fd, SIOCSIFADDR, &ifr);
paddr->sin_addr.s_addr = inet_addr(dev->mask);
err = ioctl(fd, SIOCSIFNETMASK, &ifr);

掩码是255.255.255.0

strcpy(ifr.ifr_name, dev->name);
int err = ioctl(fd, SIOCGIFFLAGS, &ifr);
ifr.ifr_ifru.ifru_flags |= IFF_UP;        
err = ioctl(fd, SIOCSIFFLAGS, &ifr);

路线也被添加。如上所示。

总而言之,当两个通道可以作为它们之间的连接时,如何让局域网中的主机B以A作为路由器ping到外部网络?

至少,当目的地设置为外部时,如何让B接收B发送的数据包?从那时起,A上的iptables可能会起作用。

如有任何建议,我们感激不尽。非常感谢。

0 个答案:

没有答案