歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

用Iproute2配置隧道

用Iproute2配置隧道
Simone Piunno 著 wqch 翻譯
1、Iproute2簡介
Iproute2是一個在Linux下的高級網絡管理工具軟件。實際上,它是通過rtnetlink sockets方式動態配置內核的一些小工具組成的,從Linux2.2內核開始,Alexey Kuznetsov 實現了通過rtnetlink sockets用來配置網絡協議棧,它是一個現代的強大的接口。
Iproute2最吸引人的特色就是它用完整而有機制的簡單命令替代了之前以下命令的功能,如ifconfig,arp,route,iptunnel,而且還添加了其它不少的功能。
如今,Iproute2已經在很多主要的發行版裡被默認安裝,即使他們的初始化腳本命令被嵌入在一些老的網絡工具包裡,如ifconfig,以及少用的iptunnel。如果你的發行版沒有包含這個重要的工具包,你也可以從網上下載並自己編譯。下載地址FTP: //ftp.inr.ac.ru/ip-routing/。
在寫這篇文章的時候,Iproute2最大的缺點就是缺乏相關的說明文檔,然而,它的IP命令語法的簡單而且還很象英語,這在很大程度上對說明文檔做了相應的補償。相信習慣於ifconfig和route命令的人不願意在用ip的時候遇到任何困難,而且他們會覺得自己象在家裡用一樣。本文假設讀者已經有一定的網絡基礎,並且已經在Linux中用過ifconfig和route命令。
2、隧道簡介
我們想像一下在二個網絡節點間要進行數據通信的問題,如果這二個節點在不同於IPv4的協議上傳輸,或者用非全球可用IP地址直接傳送到一個私有局域網LAN中。為了解決這類問題,典型的是在兩個節點間用虛擬的點對點連接,我們稱之為隧道結構。
你可以把在網絡上傳輸的每個數據包想像為一個信封,它裡面有幾個字節,外面還寫上了發送者和接收者的地址。隧道把這個信封簡單的隱藏在另一個不同的發送者和接收者的信封裡面,有效的進行數據包的傳送。當數據包到達外部接收者(寫在最外面的信封上的接收者)的時候,就把這個外部信封去掉並扔了,所以這個時候的信封(數據包)可以繼續被傳送到它的真正目的地。
封裝和拆分附加信封的節點被叫做端點,它們需要一個全球可用的IPv4地址。這就是為什麼當經過網絡地址轉換(NAT)時隧道就不能用了。而且,如果構建一個通過防火牆的隧道,那麼防火牆就必須特殊配置來允許隧道傳輸。
一個典型的隧道應用就是通過一個純IPv4網絡來連接二個IPv6節點。這二個節點可以通過構建一個偽裝的點到點IPv6連接的IPv6-in- IPv4隧道,這種方式可以把二個IPv6島連接在一起(6bone就是通過這樣一種網絡隧道的方式工作的)。IPv6-over-IPv4傳輸隧道有二種方式:自動配置(詳見RFC2373)和人工配置,本文將討論的是後者——人工配置。
3、創建隧道
用Iproute2構建隧道是很容易的事情。首先,你需要為隧道命一個名,如果你把隧道名字選擇用foo,此時,你可以用如下命令來建立SIT模式的隧道:
ip tunnel add foo mode sit remote 192.168.1.42
以這種方式,將IPv4地址為192.168.1.42的遠程端點也建一個SIT模式的IPv6-in-IPv4隧道。注意,我們還沒有指定那個IP地址來用這個本地隧道,以及那個接口等等,這些結果可以通過命令ip tunnel show 來看到:
[root@abulafia root]# ip tunnel show
sit0: ipv6/ip remote any local any ttl 64 nopmtudisc
foo: ipv6/ip remote 192.168.1.42 local any ttl inherit
我們創建的隧道在第二行。現在需要看看所有可用接口的列表,不管他們是真正的網絡適配器還是模擬的:
[root@abulafia root]# ip link show
1: lo: <loopback,up> mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <broadcast,multicast,up> mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:48:54:1b:25:30 brd ff:ff:ff:ff:ff:ff
4: sit0@none: <noarp> mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0
6: foo@none: <pointopoint,noarp> mtu 1480 qdisc noop
link/sit 0.0.0.0 peer 192.168.1.42
事實上需要注意的是lo和eth0是被標志為up,說明是已經激活,而隧道沒有。為了再次檢查,用ifconfig查看:
[root@abulafia root]# ifconfig
eth0 link encap:ethernet hwaddr 00:48:54:1b:25:30
inet addr:192.168.0.1 bcast:192.168.0.255 mask:255.255.255.0
inet6 addr: fe80::248:54ff:fe1b:2530/10 scope:link
up broadcast running multicast mtu:1500 metric:1
rx packets:0 errors:0 dropped:0 overruns:0 frame:0
tx packets:8 errors:0 dropped:0 overruns:0 carrier:0



collisions:0 txqueuelen:100
rx bytes:0 (0.0 b) tx bytes:528 (528.0 b)
interrupt:9 base address:0x5000
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:35402 errors:0 dropped:0 overruns:0 frame:0
tx packets:35402 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
rx bytes:3433996 (3.2 mb) tx bytes:3433996 (3.2 mb)
顯然,不顯示沒有被激活的接口,所以必須記住,ip連接命令顯示所有可用接口,不管他們是否被激活。為了激活foo,用命令:
ip link set foo up
解除它用:
ip link set foo down
徹底的刪掉隧道用:
ip tunnel del foo
4、特殊隧道
在之前的段落中,介紹了怎樣構建一個IPv6-in-IPv4隧道,現在來看看幾個不同的情況。
4.1、GRE隧道
如果你不需要IPv6,但是假如你想通過一個不同協議的傳輸網絡來傳遞普通IPv4數據包,那麼最好用GRE模式代替SIT模式。例如:
[root@abulafia root]# ip tunnel add foo4 mode gre remote 192.168.1.42
[root@abulafia root]# ip tunnel show
gre0: gre/ip remote any local any ttl inherit nopmtudisc
foo4: gre/ip remote 192.168.1.42 local any ttl inherit
[root@abulafia root]# ip link show
1: lo: <loopback,up> mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <broadcast,multicast,up> mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:48:54:1b:25:30 brd ff:ff:ff:ff:ff:ff
7: gre0@none: <noarp> mtu 1476 qdisc noop
link/gre 0.0.0.0 brd 0.0.0.0
9: foo4@none: <pointopoint,noarp> mtu 1476 qdisc noop
link/gre 0.0.0.0 peer 192.168.1.42
GRE模式是一個特殊的隧道傳輸,它被Cisco路由器支持,Cisco路由器可以在IPv4上實現不同協議之間數據包的傳送。還有另外一種被 Linux實現的隧道:ipip,它同樣可以實現IPv4-in-IPv4的封裝,但是它只被Linux實現,而且只有單播的IP over IP(所以你不能傳送IPX或者廣播數據包)。總的來說,GRE模式更好。
4.2 直接本地端點
即使內核很聰明的可以為你做隧道選擇,最好還是很清楚的說明將要用做隧道的IPv4地址和接口標志。用命令帶本地和設備參數來實現:
[root@abulafia root]# ip tunnel add foo mode sit local 192.168.0.1 remote 192.168.1.42 dev eth0
[root@abulafia root]# ip tunnel show
sit0: ipv6/ip remote any local any ttl 64 nopmtudisc
foo: ipv6/ip remote 192.168.1.42 local 192.168.0.1 dev eth0 ttl inherit
[root@abulafia root]# ip link show
1: lo: <loopback,up> mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <broadcast,multicast,up> mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:48:54:1b:25:30 brd ff:ff:ff:ff:ff:ff
4: sit0@none: <noarp> mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0
11: foo@eth0: <pointopoint,noarp> mtu 1480 qdisc noop
link/sit 192.168.0.1 peer 192.168.1.42
Please notice that now the interface is labeled as foo@eth0, to remind us where the tunnel has been eXPlicitly connected.
請注意接口被標志為foo@eth0,這樣可更清楚的提示我們隧道在哪兒被連接。
4.3 生存時間
使用隧道時,建一個附加的環回網絡接口是很容易的。為了限制這個問題,基本原則是生成一個較底TTL值的數據包。初始的TTL可以用命令ip tunnel add來指定TTL值,默認值是從關聯的隧道網絡接口繼承下來的。IANA建議TTL的值是64。
5、為接口指派IP地址
像其它網絡接口一樣,隧道也可以被指派一個或者多個地址。
5.1、主地址
直接指派主地址:
ip addr add 3ffe:9001:210:3::42/64 dev foo


ip addr add 192.168.0.2/24 dev foo4
ip addr add 10.20.30.40/8 dev eth0
The number immediately following the slash is to suggest to the kernel the network prefix we prefer, useful to automatically compute broadcast address and netmask on IPv4 LANs (this is called CIDR notation). However, tunnels are point-to-point interfaces and this number is then ignored.
緊跟在地址後面的數字是網絡前綴,用來在IPv4局域網中自動計算廣播地址和網絡掩碼(叫做CIDR)。然而,隧道是點到點接口,這些數字是被忽略的。
注意:為了給接口指派一個IP地址,首先你需要用ip link 來把該接口激活。
要從一個接口去掉一個地址,可以直接用del代替之前添加地址所用的add:
ip addr del 3ffe:9001:210:3::42/64 dev foo
ip addr del 192.168.0.2/24 dev foo4
列出在自己服務器上可用的IP地址:
[root@abulafia root]# ip addr show
1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
inet6 ::1/128 scope host
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:48:54:1b:25:30 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0
inet6 fe80::248:54ff:fe1b:2530/10 scope link
4: sit0@NONE: <NOARP> mtu 1480 qdisc noop
link/sit 0.0.0.0 brd 0.0.0.0
5: foo@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop
link/sit 0.0.0.0 peer 192.168.1.42
inet6 3ffe:9001:210:3::42/64 scope global
inet6 fe80::c0a8:1/10 scope link
5.2、別名
當在一個接口上用多個地址時,習慣於用ifconfig的人會對ip addr add命令在添加多個IP後,卻不產生像eth0:1,eth0:2等這樣的虛擬接口而吃驚。這個是從2.0內核繼承下來的一個命名機制,直到今天也沒有改變。例如:
[root@abulafia root]# ip addr add 192.168.0.11/24 dev eth0
[root@abulafia root]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:48:54:1b:25:30 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0
inet 192.168.0.11/24 scope global secondary eth0
inet6 fe80::248:54ff:fe1b:2530/10 scope link
[root@abulafia root]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:48:54:1B:25:30
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::248:54ff:fe1b:2530/10 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:0 (0.0 b) TX bytes:528 (528.0 b)
Interrupt:9 Base address:0x5000

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:34732 errors:0 dropped:0 overruns:0 frame:0
TX packets:34732 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3386912 (3.2 Mb) TX bytes:3386912 (3.2 Mb)

foo Link encap:IPv6-in-IPv4
inet6 addr: 3ffe:9001:210:3::42/64 Scope:Global
inet6 addr: fe80::c0a8:1/10 Scope:Link
UP POINTOPOINT RUNNING NOARP MTU:1480 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:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
添加的IP地址已經工作,並用ip addr show可以顯示,但是ifconfig甚至看不見它的存在。為了解決這個問題,加上一個標簽參數:
[root@abulafia root]# ip addr add 192.168.0.11/24 label eth0:1 dev eth0
[root@abulafia root]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:48:54:1b:25:30 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0
inet 192.168.0.11/24 scope global secondary eth0:1
inet6 fe80::248:54ff:fe1b:2530/10 scope link
[root@abulafia root]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:48:54:1B:25:30
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::248:54ff:fe1b:2530/10 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:0 (0.0 b) TX bytes:528 (528.0 b)
Interrupt:9 Base address:0x5000

eth0:1 Link encap:Ethernet HWaddr 00:48:54:1B:25:30
inet addr:192.168.0.11 Bcast:0.0.0.0 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Interrupt:9 Base address:0x5000
注意:我們可以選擇任意的字符串作接口標簽,沒有強迫使用2.0內核的命名機制;如果要用ifconfig實現向後兼容,就必須依照此命名機制。
5.3、隧道IP地址
當我們的計算機是一個獨立主機或者不是一個提供到整個局域網IPv6連接的路由器時,為本地端節點隧道選擇一個全球/公用IP地址是最好的事,分別是一個SIT/IPv6-in-IPv4隧道的IPv6地址和一個GRE/IPv4-in-IPv4隧道的IPv4地址。
取而代之,若配置一個路由器,最好讓SIT/IPv6-in-IPv4隧道用一個鏈路本地地址(IPv6的鏈路本地地址可以通過無狀態地址自動配置或者人工配置)和GRE/IPv4-in-IPv4隧道用一個私有地址(IPv4沒有鏈路本地地址)。有效的地址只能用在eth0上(或者在局域網那邊的接口上)。注意在配置的時候需要激活轉發接口,用命令:
sysctl -w net.ipv4.conf.all.forwarding=1 # for GRE (IPv4-in-IPv4)
sysctl -w net.ipv6.conf.all.forwarding=1 # for SIT (IPv6-in-IPv4)
甚至可以決定打開在一對間轉發,這種情況下,用如下命令:
sysctl -w net.ipv6.conf.eth0.forwarding=1
sysctl -w net.ipv6.conf.pippo.forwarding=1
6、路由
既然隧道已經被配置好了,現在需要指定哪些數據運輸將被定向通過它。IPv6的一般命令格式如下:
ip route add 2000::/3 dev foo
這樣,在目的地址前3位是001的地址(即全球IPv6單播地址空間)將被定向到foo接口,這只是IPv6地址空間的八分之一,但要保證所有可能的遠程主機都是在這個范圍內。
在IPv4路由表中:
[root@abulafia root]# ip route
192.168.0.0/24 dev eth0 scope link
127.0.0.0/8 dev lo scope link
而IPv6路由表:
[root@abulafia root]# ip -6 route
2000::/3 dev foo proto kernel metric 256 mtu 1480 advmss 1420
fe80::/10 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440
fe80::/10 dev foo proto kernel metric 256 mtu 1480 advmss 1420
ff00::/8 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440
ff00::/8 dev foo proto kernel metric 256 mtu 1480 advmss 1420
default dev eth0 proto kernel metric 256 mtu 1500 advmss 1440
unreachable default dev lo metric -1 error -101
如果想指定一個網關(不是給隧道的),可以用via參數,例如:
ip route add 192.168.1.0/24 via 192.168.0.254 dev eth0
去掉路由可以用ip route del命令,但是要小心的是如果這樣寫ip route del default將移除默認的IPv4路由,並不是IPv6的路由。要移除IPv6默認的目的地址需要用命令ip -6 route del default。
7、一個完整的例子
一個典型的6bone的IPv6隧道:
ip tunnel add $TUNNEL mode sit local any remote $V4_REMOTEADDR ttl 64


ip link set $TUNNEL up
ip addr add $V6_LOCALADDR dev $TUNNEL
ip route add 2000::/3 dev $TUNNEL
$TUNNEL是一個任意的指定隧道的名稱,$V4_REMOTEADDR是隧道另一端的IPv4地址,$V6_LOCALADDR是分配給本地主機的IPv6本地地址。為本地端節點地址用一個任意值,因為這樣可以處理一個動態IPv4地址(如通過撥號連接到ISP)。顯然,當我們的地址改變時,需要通知隧道代理,但是這個已經不是本文所設計的范圍,而且也沒有一個標准的處理程序。
關閉隧道:
ip tunnel del $TUNNEL
也可以自動的移除路由接口和地址。

原文:
http://members.ferrara.linux.it/pioppo/howto/iproute2tunnel-en.Html[/url]



right">



$TUNNEL是一個任意的指定隧道的名稱,$V4_REMOTEADDR是隧道另一端的IPv4地址,$V6_LOCALADDR是分配給本地主機的IPv6本地地址。為本地端節點地址用一個任意值,因為這樣可以處理一個動態IPv4地址(如通過撥號連接到ISP)。顯然,當我們的地址改變時,需要通知隧道代理,但是這個已經不是本文所設計的范圍,而且也沒有一個標准的處理程序。
關閉隧道:
ip tunnel del $TUNNEL
也可以自動的移除路由接口和地址。

原文:
http://members.ferrara.linux.it/pioppo/howto/iproute2tunnel-en.html[/url]



Copyright © Linux教程網 All Rights Reserved