我正在尝试让局域网中的主机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可能会起作用。
如有任何建议,我们感激不尽。非常感谢。