有了上一篇關(guān)于tun/tap的介紹之后,大家應(yīng)該對虛擬網(wǎng)絡(luò)設(shè)備有了一定的了解,本篇將接著介紹另一種虛擬網(wǎng)絡(luò)設(shè)備veth。 veth設(shè)備的特點
下面這張關(guān)系圖很清楚的說明了veth設(shè)備的特點: +----------------------------------------------------------------+ | | | +------------------------------------------------+ | | | Newwork Protocol Stack | | | +------------------------------------------------+ | | ↑ ↑ ↑ | |..............|...............|...............|.................| | ↓ ↓ ↓ | | +----------+ +-----------+ +-----------+ | | | eth0 | | veth0 | | veth1 | | | +----------+ +-----------+ +-----------+ | |192.168.1.11 ↑ ↑ ↑ | | | +---------------+ | | | 192.168.2.11 192.168.2.1 | +--------------|-------------------------------------------------+ ↓ Physical Network 上圖中,我們給物理網(wǎng)卡eth0配置的IP為192.168.1.11, 而veth0和veth1的IP分別是192.168.2.11和192.168.2.1。 示例我們通過示例的方式來一步一步的看看veth設(shè)備的特點。 只給一個veth設(shè)備配置IP先通過ip link命令添加veth0和veth1,然后配置veth0的IP,并將兩個設(shè)備都啟動起來 dev@debian:~$ sudo ip link add veth0 type veth peer name veth1 dev@debian:~$ sudo ip addr add 192.168.2.11/24 dev veth0 dev@debian:~$ sudo ip link set veth0 up dev@debian:~$ sudo ip link set veth1 up 這里不給veth1設(shè)備配置IP的原因就是想看看在veth1沒有IP的情況下,veth0收到協(xié)議棧的數(shù)據(jù)后會不會轉(zhuǎn)發(fā)給veth1。 ping一下192.168.2.1,由于veth1還沒配置IP,所以肯定不通 dev@debian:~$ ping -c 4 192.168.2.1 PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data. From 192.168.2.11 icmp_seq=1 Destination Host Unreachable From 192.168.2.11 icmp_seq=2 Destination Host Unreachable From 192.168.2.11 icmp_seq=3 Destination Host Unreachable From 192.168.2.11 icmp_seq=4 Destination Host Unreachable --- 192.168.2.1 ping statistics --- 4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3015ms pipe 3 但為什么ping不通呢?是到哪一步失敗的呢? 先看看抓包的情況,從下面的輸出可以看出,veth0和veth1收到了同樣的ARP請求包,但沒有看到ARP應(yīng)答包: dev@debian:~$ sudo tcpdump -n -i veth0 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes 20:20:18.285230 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:19.282018 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:20.282038 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:21.300320 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:22.298783 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:23.298923 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 dev@debian:~$ sudo tcpdump -n -i veth1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes 20:20:48.570459 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:49.570012 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:50.570023 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:51.570023 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:52.569988 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 20:20:53.570833 ARP, Request who-has 192.168.2.1 tell 192.168.2.11, length 28 為什么會這樣呢?了解ping背后發(fā)生的事情后就明白了:
給兩個veth設(shè)備都配置IP給veth1也配置上IP dev@debian:~$ sudo ip addr add 192.168.2.1/24 dev veth1 再ping 192.168.2.1成功(由于192.168.2.1是本地IP,所以默認會走lo設(shè)備,為了避免這種情況,這里使用ping命令帶上了-I參數(shù),指定數(shù)據(jù)包走指定設(shè)備) dev@debian:~$ ping -c 4 192.168.2.1 -I veth0 PING 192.168.2.1 (192.168.2.1) from 192.168.2.11 veth0: 56(84) bytes of data. 64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.032 ms 64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.048 ms 64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.055 ms 64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.050 ms --- 192.168.2.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3002ms rtt min/avg/max/mdev = 0.032/0.046/0.055/0.009 ms 注意:對于非debian系統(tǒng),這里有可能ping不通,主要是因為內(nèi)核中的一些ARP相關(guān)配置導(dǎo)致veth1不返回ARP應(yīng)答包,如ubuntu上就會出現(xiàn)這種情況,解決辦法如下: 再來看看抓包情況,我們在veth0和veth1上都看到了ICMP echo的請求包,但為什么沒有應(yīng)答包呢?上面不是顯示ping進程已經(jīng)成功收到了應(yīng)答包嗎? dev@debian:~$ sudo tcpdump -n -i veth0 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes 20:23:43.113062 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 1, length 64 20:23:44.112078 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 2, length 64 20:23:45.111091 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 3, length 64 20:23:46.110082 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24169, seq 4, length 64 dev@debian:~$ sudo tcpdump -n -i veth1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes 20:24:12.221372 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 1, length 64 20:24:13.222089 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 2, length 64 20:24:14.224836 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 3, length 64 20:24:15.223826 IP 192.168.2.11 > 192.168.2.1: ICMP echo request, id 24174, seq 4, length 64 看看數(shù)據(jù)包的流程就明白了:
抓一下lo設(shè)備上的數(shù)據(jù),發(fā)現(xiàn)應(yīng)答包確實是從lo口回來的: dev@debian:~$ sudo tcpdump -n -i lo tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes 20:25:49.590273 IP 192.168.2.1 > 192.168.2.11: ICMP echo reply, id 24177, seq 1, length 64 20:25:50.590018 IP 192.168.2.1 > 192.168.2.11: ICMP echo reply, id 24177, seq 2, length 64 20:25:51.590027 IP 192.168.2.1 > 192.168.2.11: ICMP echo reply, id 24177, seq 3, length 64 20:25:52.590030 IP 192.168.2.1 > 192.168.2.11: ICMP echo reply, id 24177, seq 4, length 64 試著ping下其它的IPping 192.168.2.0/24網(wǎng)段的其它IP失敗,ping一個公網(wǎng)的IP也失?。?/p> dev@debian:~$ ping -c 1 -I veth0 192.168.2.2 PING 192.168.2.2 (192.168.2.2) from 192.168.2.11 veth0: 56(84) bytes of data. From 192.168.2.11 icmp_seq=1 Destination Host Unreachable --- 192.168.2.2 ping statistics --- 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms dev@debian:~$ ping -c 1 -I veth0 baidu.com PING baidu.com (111.13.101.208) from 192.168.2.11 veth0: 56(84) bytes of data. From 192.168.2.11 icmp_seq=1 Destination Host Unreachable --- baidu.com ping statistics --- 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms 從抓包來看,和上面第一種veth1沒有配置IP的情況是一樣的,ARP請求沒人處理 dev@debian:~$ sudo tcpdump -i veth1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes 02:25:23.223947 ARP, Request who-has 192.168.2.2 tell 192.168.2.11, length 28 02:25:24.224352 ARP, Request who-has 192.168.2.2 tell 192.168.2.11, length 28 02:25:25.223471 ARP, Request who-has 192.168.2.2 tell 192.168.2.11, length 28 02:25:27.946539 ARP, Request who-has 123.125.114.144 tell 192.168.2.11, length 28 02:25:28.946633 ARP, Request who-has 123.125.114.144 tell 192.168.2.11, length 28 02:25:29.948055 ARP, Request who-has 123.125.114.144 tell 192.168.2.11, length 28 結(jié)束語從上面的介紹中可以看出,從veth0設(shè)備出去的數(shù)據(jù)包,會轉(zhuǎn)發(fā)到veth1上,如果目的地址是veth1的IP的話,就能被協(xié)議棧處理,否則連ARP那關(guān)都過不了,IP forward啥的都用不上,所以不借助其它虛擬設(shè)備的話,這樣的數(shù)據(jù)包只能在本地協(xié)議棧里面打轉(zhuǎn)轉(zhuǎn),沒法走到eth0上去,即沒法發(fā)送到外面的網(wǎng)絡(luò)中去。 下一篇將介紹Linux下的網(wǎng)橋,到時候veth設(shè)備就有用武之地了。 參考 |
|