如何将流量从隧道接口转发到 eth0

如何将流量从隧道接口转发到 eth0

网络拓扑结构:

  互联网
     |
     |
  (eth0)IP:202.xxx.xxx.xxx/255.255.255.0
答:Remote_Server(Debian)
  (tun0)IP:10.10.1.1/255.255.255.0
     |
     |
  (utun0)IP:10.10.1.2/255.255.255.0
B:iOS_设备(iOS 9)


设备 A:
一个 TCP 服务器,监听 7777 以连接客户端(iOS 设备)。

设备 B:
一个已经通过 WIFI 连接到互联网的 iOS 设备。

工作流程:

  1. 服务器正在监听“0.0.0.0:7777”
  2. 客户端连接到“202.xxx.xxx.xxx:7777”(使用用户名等)
  3. 服务器检查客户端的用户名以进行客户端身份验证
  4. 服务器向客户端发送隧道配置信息(例如:10.10.1.2/24,dns:8.8.8.8)
  5. 客户端建立新隧道连接到服务器
  6. 客户端通过隧道向服务器发送网络数据包(DNS查询,HTTPS请求等)(并等待服务器的响应)

服务器端日志(客户端通过隧道连接后):

$ sudo ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
      inet addr:10.10.1.1  P-t-P:10.10.1.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)
-----------------------------------------------------------
tun0      Link encap:UNSPEC  HWaddr ...
      ...
      RX packets:12 errors:0 dropped:12 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      ...
      RX bytes:742 (742.0 B)  TX bytes:0 (0.0 B)
-----------------------------------------------------------
tun0      Link encap:UNSPEC  HWaddr ...
      ...
      RX packets:25 errors:0 dropped:25 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      ...
      RX bytes:1548 (1.5 KiB)  TX bytes:0 (0.0 B)
-----------------------------------------------------------

RX字节:0 -> 742 -> 1548 字节

现在的问题是:
在服务器端,如何将流量从 tun0 转发到 eth0?
有人能帮忙吗?


已尝试以下命令,但似乎不起作用。

$sudo sysctl net.ipv4.ip_forward
    net.ipv4.ip_forward = 1

$sudo iptables -L -n -v
 Chain INPUT (policy ACCEPT 13472 packets, 4929K bytes)
 pkts bytes target     prot opt in     out     source               destination         
  207 13105 ACCEPT     all  --  tun+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tap+   *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  *      *       10.30.0.0/24         0.0.0.0/0           
  288 18484 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 ACCEPT     all  --  tun+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tap+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 13436 packets, 5315K bytes)
 pkts bytes target     prot opt in     out     source               destination

$
$sudo iptables -A FORWARD --in-interface tun0 -j ACCEPT
$sudo iptables --table nat -A POSTROUTING --out-interface eth0 -j MASQUERADE
$

更多日志(服务器端):

$ ip a show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: dummy0@NONE: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default 
    link/ether 8a:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether f2:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 202.xxx.xxx.xxx/24 brd 202.a.b.c scope global eth0
       valid_lft forever preferred_lft forever
    inet6 xxxx:xxxx::xxxx:xxxx:xxxx:xxxx/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 aaaa::bbbb:cccc:dddd:eeee/64 scope link 
       valid_lft forever preferred_lft forever
4: teql0: <NOARP> mtu 1500 qdisc noop state DOWN group default qlen 100
    link/void 
5: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default 
    link/ipip 0.0.0.0 brd 0.0.0.0
6: gre0@NONE: <NOARP> mtu 1476 qdisc noop state DOWN group default 
    link/gre 0.0.0.0 brd 0.0.0.0
7: gretap0@NONE: <BROADCAST,MULTICAST> mtu 1462 qdisc noop state DOWN group default qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
8: ip_vti0@NONE: <NOARP> mtu 1428 qdisc noop state DOWN group default 
    link/ipip 0.0.0.0 brd 0.0.0.0
9: ip6_vti0@NONE: <NOARP> mtu 1500 qdisc noop state DOWN group default 
    link/tunnel6 :: brd ::
10: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default 
    link/sit 0.0.0.0 brd 0.0.0.0
11: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default 
    link/tunnel6 :: brd ::
12: ip6gre0@NONE: <NOARP> mtu 1448 qdisc noop state DOWN group default 
    link/gre6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
175: tun0@NONE: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 10.10.1.1/24 scope global tun0
       valid_lft forever preferred_lft forever

$ ip ro show
default via 202.xxx.xxx.1 dev eth0 
10.10.1.0/24 dev tun0  proto kernel  scope link  src 10.10.1.1 
202.xxx.xxx.0/24 dev eth0  proto kernel  scope link  src 202.xxx.xxx.xxx     

$ ip rule show
0:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default

$ sudo iptables -L -vn
Chain INPUT (policy ACCEPT 1291 packets, 198K bytes)
 pkts bytes target     prot opt in     out     source               destination         
   87  5541 ACCEPT     all  --  tun+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tap+   *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  *      *       10.30.0.0/24         0.0.0.0/0           
  168 10829 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 ACCEPT     all  --  tun+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tap+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 1230 packets, 300K bytes)
 pkts bytes target     prot opt in     out     source               destination         

$ sudo iptables -L -vn
Chain INPUT (policy ACCEPT 1312 packets, 201K bytes)
 pkts bytes target     prot opt in     out     source               destination         
   87  5541 ACCEPT     all  --  tun+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tap+   *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  *      *       10.30.0.0/24         0.0.0.0/0           
  169 10900 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 ACCEPT     all  --  tun+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tap+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 1258 packets, 311K bytes)
 pkts bytes target     prot opt in     out     source               destination 

$ sudo iptables -t nat -L -vn
Chain PREROUTING (policy ACCEPT 111 packets, 6908 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 68 packets, 4153 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 38 packets, 3678 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      eth0    10.30.0.0/24         0.0.0.0/0           
 138K 9623K MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0

$ sudo route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         xxxxxx.xxxx     0.0.0.0         UG    0      0        0 eth0
10.10.1.0       *               255.255.255.0   U     0      0        0 tun0
202.xxx.xxx.0   *               255.255.255.0   U     0      0        0 eth0

$ cat /proc/sys/net/ipv4/ip_forward
1

网络数据包通过隧道(tun0,服务器端):

No. Time        Source      Destination                     Protocol    Length  Info
3   4.603031    10.10.1.2   google-public-dns-a.google.com  DNS         59      Standard query 0xc09d A apple.com
4   4.708703    10.10.1.2   google-public-dns-a.google.com  DNS         67      Standard query 0x6f6d A guzzoni.apple.com
...
21  95.530358   10.10.1.2   10.10.1.1                       DNS         75      Standard query 0x850b A 20-courier.push.apple.com
22  104.468535  10.10.1.2   10.10.1.1                       DNS         75      Standard query 0x850b A 20-courier.push.apple.com

第 3 帧的详细信息:

Frame 3: 59 bytes on wire (472 bits), 59 bytes captured (472 bits) on interface 0
    Interface id: 0 (utun0)
    Encapsulation type: NULL/Loopback (15)
    Arrival Time: Jan  3, 2016 23:40:31.564933000 HKT
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1451835631.564933000 seconds
    [Time delta from previous captured frame: 0.614315000 seconds]
    [Time delta from previous displayed frame: 0.614315000 seconds]
    [Time since reference or first frame: 4.603031000 seconds]
    Frame Number: 3
    Frame Length: 59 bytes (472 bits)
    Capture Length: 59 bytes (472 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: null:ip:udp:dns]
    [Coloring Rule Name: UDP]
    [Coloring Rule String: udp]
Null/Loopback
    Family: IP (2)
Internet Protocol Version 4, Src: 10.10.1.2 (10.10.1.2), Dst: google-public-dns-a.google.com (8.8.8.8)
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 55
    Identification: 0x16e2 (5858)
    Flags: 0x00
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    Fragment offset: 0
    Time to live: 255
    Protocol: UDP (17)
    Header checksum: 0x89b8 [validation disabled]
        [Good: False]
        [Bad: False]
    Source: 10.10.1.2 (10.10.1.2)
    Destination: google-public-dns-a.google.com (8.8.8.8)
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
User Datagram Protocol, Src Port: 59951 (59951), Dst Port: domain (53)
    Source Port: 59951 (59951)
    Destination Port: domain (53)
    Length: 35
    Checksum: 0xe181 [validation disabled]
        [Good Checksum: False]
        [Bad Checksum: False]
    [Stream index: 0]
Domain Name System (query)
    Transaction ID: 0xc09d
    Flags: 0x0100 Standard query
        0... .... .... .... = Response: Message is a query
        .000 0... .... .... = Opcode: Standard query (0)
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...1 .... .... = Recursion desired: Do query recursively
        .... .... .0.. .... = Z: reserved (0)
        .... .... ...0 .... = Non-authenticated data: Unacceptable
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 0
    Queries
        apple.com: type A, class IN
            Name: apple.com
            [Name Length: 9]
            [Label Count: 2]
            Type: A (Host Address) (1)
            Class: IN (0x0001)

2016-01-04 编辑 1:
执行命令“iptables -F FORWARD”后:

$ sudo ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
    inet addr:10.10.1.1  P-t-P:10.10.1.1  Mask:255.255.255.0
    UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
    RX packets:250 errors:0 dropped:250 overruns:0 frame:0
    TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:500 
    RX bytes:15845 (15.4 KiB)  TX bytes:0 (0.0 B)

RX数据包:250 错误:0掉落:250


$ sudo iptables -L -vn
Chain INPUT (policy ACCEPT 207 packets, 22574 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  258 16411 ACCEPT     all  --  tun+   *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  tap+   *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 8 packets, 1632 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    8   578 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0          

$ sudo iptables -L -vn -t nat
Chain PREROUTING (policy ACCEPT 18 packets, 1056 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 16 packets, 914 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 2 packets, 128 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      eth0    10.30.0.0/24         0.0.0.0/0           
 138K 9687K MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0     

2016-01-04 编辑 2:
我执行的客户端测试步骤:

  1. 客户端(iOS 设备)连接到服务器。
  2. 在服务器端运行 tcpdump。
  3. 客户端打开一个 URL:“https://www.apple.com“使用 Safari。
  4. 检查服务器端的 tcpdump 日志
  5. 检查客户端是否收到来自服务器的响应内容(应该是 HTTP 200 响应)

测试结果:
客户端确实发送了HTTP请求,并且请求超时(等待响应超时)。


tcpdump 日志:

$ sudo tcpdump -i tun0 -s 0 -B 524288 -w ~/tmp/tun0_traffic.pcap
tcpdump: listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
^C
98 packets received by filter
0 packets dropped by kernel
58 packets dropped by interface

-----------------------------------------------------------

$ tcpdump -s 0 -n -e -x -vvv -r ~/tmp/tun0_traffic.pcap 
reading from file /home/tube/tmp/tun0_traffic.pcap, link-type RAW (Raw IP)
01:40:03.445148 ip: (tos 0x0, ttl 255, id 2395, offset 0, flags [none], proto UDP (17), length 76)
    10.10.1.2.65368 > 8.8.8.8.53: [udp sum ok] 52854+ A? p02-keyvalueservice.icloud.com. (48)
    0x0000:  4500 004c ...

01:40:07.461931 ip: (tos 0xc0, ttl 64, id 34376, offset 0, flags [none], proto ICMP (1), length 104)
    10.10.1.1 > 10.10.1.2: ICMP 10.10.1.1 udp port 53 unreachable, length 84
    (tos 0x0, ttl 255, id 36211, offset 0, flags [none], proto UDP (17), length 76)
    10.10.1.2.65368 > 10.10.1.1.53: [udp sum ok] 52854+ A? p02-keyvalueservice.icloud.com. (48)
    0x0000:  45c0 0068 ...

$ sudo tcpdump -i eth0 -s 0 -B 524288 -n src net 10.10.1.0/24 -w ~/tmp/eth0_traffic_from_tun0.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
^C
0 packets captured
1 packet received by filter
0 packets dropped by kernel

-----------------------------------------------------------

$ tcpdump -s 0 -n -e -x -vvv -r ~/tmp/eth0_traffic_from_tun0.pcap 
reading from file /home/tube/tmp/eth0_traffic_from_tun0.pcap, link-type EN10MB (Ethernet)
$

2016-01-04 编辑 3:
新的 tcpdump 日志:(非常感谢@MadHatter。)

sudo tcpdump -i eth0 -s 0 -B 524288 -n -w ~/tmp/eth0_traffic_all.pcap

And read the ~/tmp/eth0_traffic_all.pcap file:
No. Time        Source          Destination     Protocol    Length  Info
51  3.268219    202.xxx.xxx.xxx 8.8.8.8         DNS         69      Standard query 0x4d19 A apple.com
57  3.270244    8.8.8.8         202.xxx.xxx.xxx DNS         117     Standard query response 0x4d19 A apple.com A ...

来自 tun0 转发(到 eth0)的数据包运行正常!eth0 确实收到了来自 8.8.8.8 的响应

答案1

首先,你的FORWARD链条出了问题。其中的第三条规则是阻塞全部转发的流量不满足前几个规则,并且根据前三个规则的数据包数量来判断,前两个规则不匹配任何内容,这意味着规则 3 停止了一切。

你已经编写了允许所需流量的规则,但由于这些规则规则 3,交通永远不会到达他们(首场决定性比赛获胜)。当您清除链中的所有规则FORWARD并让ACCEPT策略生效时,流量就会流动。

其次,你使用高度限制性的tcpdump咒语来查看流量。具体来说,你正在寻找源地址位于10.10.1.0/24 转发 - 但您的 nat 规则正在伪装此流量,因此tcpdump无法捕获它。当您打开调用时tcpdump,您会看到现在转发的流量。

相关内容