我在 Linux 上一直不太理解的一件事是,不针对环回的本地流量会发生什么情况。
例如,假设有以下网络设置:
[root@pe-323-master ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:2B:59:85
inet addr:172.16.90.133 Bcast:172.16.90.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe2b:5985/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1881 errors:0 dropped:0 overruns:0 frame:0
TX packets:1205 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:234047 (228.5 KiB) TX bytes:134389 (131.2 KiB)
eth1 Link encap:Ethernet HWaddr 00:0C:29:2B:59:8F
inet addr:10.20.2.2 Bcast:10.20.2.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe2b:598f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:77 errors:0 dropped:0 overruns:0 frame:0
TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:14880 (14.5 KiB) TX bytes:1188 (1.1 KiB)
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:13585 errors:0 dropped:0 overruns:0 frame:0
TX packets:13585 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:6501824 (6.2 MiB) TX bytes:6501824 (6.2 MiB)
当我 ping 本地非环回地址时实际上会发生什么?
[root@pe-323-master ~]# ping -c 1 172.16.90.133
PING 172.16.90.133 (172.16.90.133) 56(84) bytes of data.
64 bytes from 172.16.90.133: icmp_seq=1 ttl=64 time=0.011 ms
--- 172.16.90.133 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.011/0.011/0.011/0.000 ms
该流量是通过线路发出并返回,还是在内部路由?
答案1
嗯,因为它很简单——我在自己的系统上做了一个实验。
1号航站楼
$ uname -a
Linux my-pc 3.15.1-1-ARCH #1 SMP PREEMPT Tue Jun 17 09:32:20 CEST 2014 x86_64 GNU/Linux
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.2 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::21f:bcff:fe09:7b0a prefixlen 64 scopeid 0x20<link>
ether 66:60:13:37:06:66 txqueuelen 1000 (Ethernet)
RX packets 451273 bytes 458871230 (437.6 MiB)
RX errors 0 dropped 12 overruns 0 frame 0
TX packets 305732 bytes 32068185 (30.5 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 13166 bytes 667544 (651.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13166 bytes 667544 (651.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
$ ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.048 ms
^C
--- 192.168.1.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.048/0.048/0.048/0.000 ms
第2航站楼
$ sudo tcpdump -i lo 'icmp and src 192.168.1.2'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
21:27:17.944958 IP my-pc.home > my-pc.home: ICMP echo request, id 32419, seq 1, length 64
21:27:17.944975 IP my-pc.home > my-pc.home: ICMP echo reply, id 32419, seq 1, length 64
第3航站楼
$ sudo tcpdump -i eth0 'icmp and src 192.168.1.2'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
结果.. 至少在我的电脑上,ping 永远不会lo
离开我的系统。
另一种方法是使用跟踪路由。
$ sudo traceroute 192.168.1.2
traceroute to 192.168.1.2 (192.168.1.2), 30 hops max, 60 byte packets
1 my-pc.home (192.168.1.2) 0.048 ms 0.014 ms 0.022 ms
答案2
您可以在对计算机的 IP 地址执行 ping 操作时,在环回接口上执行 tcpdump。这将向您展示正在发生的情况。
确实,流量永远不会离开机器。如果这样做了,它就不会收回它。交换机或路由器不会将流量转发回其来源接口。
答案3
Linux(我认为大多数其他 Unix 变体,但我不确定)在本地路由本地绑定的流量,其中:
- “本地绑定”是指系统发出的流量,其目的地是与系统网络接口之一关联的 IP 地址;
- 通过“本地路由”,我的意思是流量不会发送到网络接口驱动程序,而是直接从传出队列移动到传入队列。
本地绑定的数据包确实会通过 netfilter ( iptables
) 链,就好像它们不是本地绑定的一样 — 它们不会重新路由到 127.0.0.1 或接口lo
。我不知道它们如何影响数据包调度。