Linux 路由器:ping 不路由回来

Linux 路由器:ping 不路由回来

我有一个 Debian 盒子,想把它设置为路由器,还有一个 Ubuntu 盒子,用作客户端。

我的问题是,当 Ubuntu 客户端尝试 ping 互联网上的服务器时,所有数据包都会丢失(不过,正如您在下面看到的,他们似乎可以毫无问题地进入服务器并返回)。

我在 Ubuntu Box 中执行此操作:

# ping -I eth1 my.remote-server.com
PING my.remote-server.com (X.X.X.X) from 10.1.1.12 eth1: 56(84) bytes of data.
^C
--- my.remote-server.com ping statistics ---
13 packets transmitted, 0 received, 100% packet loss, time 12094ms

(为了保护隐私,我更改了远程服务器的名称和 IP)。

从 Debian 路由器上我看到了这一点:

# tcpdump -i eth1 -qtln icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 305, seq 7, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 305, seq 8, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 305, seq 8, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 305, seq 9, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 305, seq 9, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 305, seq 10, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 305, seq 10, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 305, seq 11, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 305, seq 11, length 64
^C
9 packets captured
9 packets received by filter
0 packets dropped by kernel

# tcpdump -i eth2 -qtln icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth2, link-type EN10MB (Ethernet), capture size 65535 bytes
IP 192.168.1.10 > X.X.X.X: ICMP echo request, id 360, seq 213, length 64
IP X.X.X.X > 192.168.1.10: ICMP echo reply, id 360, seq 213, length 64
IP 192.168.1.10 > X.X.X.X: ICMP echo request, id 360, seq 214, length 64
IP X.X.X.X > 192.168.1.10: ICMP echo reply, id 360, seq 214, length 64
IP 192.168.1.10 > X.X.X.X: ICMP echo request, id 360, seq 215, length 64
IP X.X.X.X > 192.168.1.10: ICMP echo reply, id 360, seq 215, length 64
IP 192.168.1.10 > X.X.X.X: ICMP echo request, id 360, seq 216, length 64
IP X.X.X.X > 192.168.1.10: ICMP echo reply, id 360, seq 216, length 64
IP 192.168.1.10 > X.X.X.X: ICMP echo request, id 360, seq 217, length 64
IP X.X.X.X > 192.168.1.10: ICMP echo reply, id 360, seq 217, length 64
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

在远程服务器上我看到了这个:

# tcpdump -i eth0 -qtln icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 1, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 1, length 64
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 2, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 2, length 64
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 3, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 3, length 64
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 4, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 4, length 64
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 5, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 5, length 64
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 6, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 6, length 64
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 7, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 7, length 64
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 8, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 8, length 64
IP Y.Y.Y.Y > X.X.X.X: ICMP echo request, id 360, seq 9, length 64
IP X.X.X.X > Y.Y.Y.Y: ICMP echo reply, id 360, seq 9, length 64

18 packets captured
228 packets received by filter
92 packets dropped by kernel

这里“XXXX”是我的远程服务器的 IP,“YYYY”是我的本地网络的公共 IP。因此,我的理解是 ping 数据包从 Ubuntu 机器 (10.1.1.12) 发出,到达路由器 (10.1.1.1),再从那里到达下一个路由器 (192.168.1.1),然后到达远程服务器 (XXXX)。然后它们一路返回到 Debian 路由器,但再也没有回到 Ubuntu 机器。

我错过了什么?

以下是 Debian 路由器设置:

# ifconfig
eth1      Link encap:Ethernet  HWaddr 94:0c:6d:82:0d:98  
          inet addr:10.1.1.1  Bcast:10.1.1.255  Mask:255.255.255.0
          inet6 addr: fe80::960c:6dff:fe82:d98/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:105761 errors:0 dropped:0 overruns:0 frame:0
          TX packets:48944 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:40298768 (38.4 MiB)  TX bytes:44831595 (42.7 MiB)
          Interrupt:19 Base address:0x6000 

eth2      Link encap:Ethernet  HWaddr 6c:f0:49:a4:47:38  
          inet addr:192.168.1.10  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::6ef0:49ff:fea4:4738/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:38335992 errors:0 dropped:0 overruns:0 frame:0
          TX packets:37097705 errors:0 dropped:0 overruns:0 carrier:1
          collisions:0 txqueuelen:1000 
          RX bytes:4260680226 (3.9 GiB)  TX bytes:3759806551 (3.5 GiB)
          Interrupt:27 

eth3      Link encap:Ethernet  HWaddr 94:0c:6d:82:c8:72  
          UP BROADCAST 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:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:20 Base address:0x2000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:3408 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3408 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:358445 (350.0 KiB)  TX bytes:358445 (350.0 KiB)

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:2767779 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1569477 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:3609469393 (3.3 GiB)  TX bytes:96113978 (91.6 MiB)


# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.8.0.2        0.0.0.0         255.255.255.255 UH    0      0        0 tun0
127.0.0.1       0.0.0.0         255.255.255.255 UH    0      0        0 lo
10.8.0.0        10.8.0.2        255.255.255.0   UG    0      0        0 tun0
192.168.1.0     0.0.0.0         255.255.255.0   U     1      0        0 eth2
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 eth1
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 eth2

# arp -n 
# Note: Here I have changed all the different MACs except the ones corresponding to the Ubuntu box (on 10.1.1.12 and 192.168.1.12)
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.1.118            ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.72             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.94             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.102            ether   NN:NN:NN:NN:NN:NN   C                     eth2
10.1.1.12                ether   00:1e:67:15:2b:f0   C                     eth1
192.168.1.86             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.2              ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.61             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.64             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.116            ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.91             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.52             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.93             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.87             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.92             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.100            ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.40             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.53             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.1              ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.83             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.89             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.12             ether   00:1e:67:15:2b:f1   C                     eth2
192.168.1.77             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.66             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.90             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.65             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.41             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.78             ether   NN:NN:NN:NN:NN:NN   C                     eth2
192.168.1.123            ether   NN:NN:NN:NN:NN:NN   C                     eth2


# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination   

# iptables -L -n -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  10.1.1.0/24         !10.1.1.0/24         
MASQUERADE  all  -- !10.1.1.0/24          10.1.1.0/24         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

这是 Ubuntu 盒子:

# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1e:67:15:2b:f1  
          inet addr:192.168.1.12  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::21e:67ff:fe15:2bf1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:28785139 errors:0 dropped:0 overruns:0 frame:0
          TX packets:19050735 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:32068182803 (32.0 GB)  TX bytes:6061333280 (6.0 GB)
          Interrupt:16 Memory:b1a00000-b1a20000 

eth1      Link encap:Ethernet  HWaddr 00:1e:67:15:2b:f0  
          inet addr:10.1.1.12  Bcast:10.1.1.255  Mask:255.255.255.0
          inet6 addr: fe80::21e:67ff:fe15:2bf0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:285086 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12719 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:30817249 (30.8 MB)  TX bytes:2153228 (2.1 MB)
          Interrupt:16 Memory:b1900000-b1920000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:86048 errors:0 dropped:0 overruns:0 frame:0
          TX packets:86048 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:11426538 (11.4 MB)  TX bytes:11426538 (11.4 MB)

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 eth0
0.0.0.0         10.1.1.1        0.0.0.0         UG    100    0        0 eth1
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 eth1
10.8.0.0        192.168.1.10    255.255.255.0   UG    0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0

# arp -n
# Note: Here I have changed all the different MACs except the ones corresponding to the Debian box (on 10.1.1.1 and 192.168.1.10)
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.1.70             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.90             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.97             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.103            ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.13             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.120                    (incomplete)                              eth0
192.168.1.111            ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.118            ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.51             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.102                    (incomplete)                              eth0
192.168.1.64             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.52             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.74                     (incomplete)                              eth0
192.168.1.94             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.121            ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.72             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.87             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.91             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.71             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.78             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.83             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.88                     (incomplete)                              eth0
192.168.1.82             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.98             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.100            ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.93             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.73             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.11             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.85                     (incomplete)                              eth0
192.168.1.112            ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.89             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.65             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.81             ether   NN:NN:NN:NN:NN:NN   C                     eth0
10.1.1.1                 ether   94:0c:6d:82:0d:98   C                     eth1
192.168.1.53             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.116            ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.61             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.10             ether   6c:f0:49:a4:47:38   C                     eth0
192.168.1.86                     (incomplete)                              eth0
192.168.1.119            ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.66             ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.1              ether   NN:NN:NN:NN:NN:NN   C                     eth0
192.168.1.1              ether   NN:NN:NN:NN:NN:NN   C                     eth1
192.168.1.92             ether   NN:NN:NN:NN:NN:NN   C                     eth0

# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

# iptables -L -n -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination 

编辑:根据 Patrick 的建议,我在 Ubuntu 机器上执行了 tcpdump,看到了以下信息:

# tcpdump -i eth1 -qtln icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 21967, seq 1, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 21967, seq 1, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 21967, seq 2, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 21967, seq 2, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 21967, seq 3, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 21967, seq 3, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 21967, seq 4, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 21967, seq 4, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 21967, seq 5, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 21967, seq 5, length 64
IP 10.1.1.12 > X.X.X.X: ICMP echo request, id 21967, seq 6, length 64
IP X.X.X.X > 10.1.1.12: ICMP echo reply, id 21967, seq 6, length 64
^C
12 packets captured
12 packets received by filter
0 packets dropped by kernel

所以问题是:如果所有数据包似乎都在来来去去,为什么 ping 会报告 100% 数据包丢失?

答案1

根据您在评论中提出的问题:

在远程服务器上,我可以看到请求和回复。但在 Debian 路由器上,我什么都看不到……在所有接口上都看不到!我猜现在 Ubuntu 盒子正在直接与 192.168.1.1 上的路由器通信,尽管它使用 IP 10.1.1.12 发送请求,所以它无法路由回来。但为什么呢?

从 Ubuntu 服务器:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 eth0 <---
0.0.0.0         10.1.1.1        0.0.0.0         UG    100    0        0 eth1

捕获此路由表时,通过eth0指向 192.168.1.1 的路由器(即不是 Debian 机器),您有一个较低的度量默认值。始终首先遵循较低的度量默认值,这意味着 Ubuntu 希望将所有非连接流量直接发送到 192.168.1.1。

当您有空闲时间时,请使用以下命令删除该默认设置:

route del default gw 192.168.1.1 dev eth0

我仍在为更大的问题而烦恼(原始嗅探器跟踪显示 Ubuntu:eth1 上有 ping 回复,但操作系统不接受任何 ping)。您能否从 Ubuntu:eth1 执行 ping 操作并同时在 Debian:eth2 上捕获,以演示在您强制 Ubuntu 再次通过 Debian 发送所有流量后 NAT 发生了什么?

答案2

你检查过吗反向路径过滤在 Ubuntu 机器上启用了吗?

这是一个 sysctl 设置(net.ipv4.conf.all.rp_filter),如果源地址来自“错误”的接口(即不是内核路由到的接口),它将过滤传入的数据包

您也可以尝试net.ipv4.conf.all.log_martians=1看看发生了什么。

答案3

实现此功能的关键是为不同的接口创建单独的路由表,并告诉网络堆栈使用这些路由表而不是默认路由表。

在你的情况下这应该可以ping -I eth2 8.8.8.8工作:

# register the 'foo' table name and give it id 1
echo '1 foo' >> /etc/iproute2/rt_tables

# setup routing table 'foo'
ip route add 192.168.1.0/24 dev eth2 src 192.168.1.10 table foo
ip route add default via 192.168.1.1 table foo

# use routing table 'foo' for address 192.168.1.10
ip rule add from 192.168.1.10 table foo

有关多个上行链路路由的更多信息,请参阅 LARTC HOWTO: http://lartc.org/howto/lartc.rpdb.multiple-links.html

答案4

您需要配置 NAT。

在典型配置中,本地网络使用指定的“私有”IP 地址子网之一。该网络上的路由器在该地址空间中有一个私有地址。路由器还通过 Internet 服务提供商分配的“公共”地址连接到 Internet。当流量从本地网络传输到 Internet 时,每个数据包中的源地址都会从私有地址即时转换为公共地址。路由器会跟踪有关每个活动连接的基本数据(特别是目标地址和端口)。当回复返回路由器时,它会使用在出站阶段存储的连接跟踪数据来确定将回复转发到的内部网络上的私有地址。

相关内容