轉載:http://wushank.blog.51cto.com/3489095/1306849
tun/tap 驅動程序實現了虛擬網卡的功能,tun表示虛擬的是點對點設備,tap表示虛擬的是以太網設備,這兩種設備針對網絡包實施不同的封裝。利用tun/tap 驅動,可以將tcp/ip協議棧處理好的網絡分包傳給任何一個使用tun/tap驅動的進程,由進程重新處理后再發到物理鏈路中。
開源項目openvpn (http://openvpn.sourceforge.net)和Vtun(http://vtun.sourceforge.net)都是利用tun/tap驅動實現的隧道封裝。
一、Tun/Tap驅動程序工作原理
做為虛擬網卡驅動,Tun/Tap驅動程序的數據接收和發送並不直接和真實網卡打交道,他在Linux內核中添加了一個TUN/TAP虛擬網絡設備的驅動程序和一個與之相關連的字符設備 /dev/net/tun,字符設備tun作為用戶空間和內核空間交換數據的接口。當內核將數據包發送到虛擬網絡設備時,數據包被保存在設備相關的一個隊列中,直到用戶空間程序通過打開的字符設備tun的描述符讀取時,它才會被拷貝到用戶空間的緩沖區中,其效果就相當於,數據包直接發送到了用戶空間。通過系統調用write發送數據包時其原理與此類似。
在linux下,要實現內核空間和用戶空間數據的交互,有多種方式:可以通用socket創建特殊套接字,利用套接字實現數據交互;通過proc文件系統創建文件來進行數據交互;還可以使用設備文件的方式,訪問設備文件會調用設備驅動相應的例程,設備驅動本身就是內核空間和用戶空間的一個接口,Tun/tap驅動就是利用設備文件實現用戶空間和內核空間的數據交互。
從結構上來說,Tun/tap驅動並不單純是實現網卡驅動,同時它還實現了字符設備驅動部分。以字符設備的方式連接用戶空間和內核空間。下面是示意圖:
Tun/tap 驅動程序中包含兩個部分,一部分是字符設備驅動,還有一部分是網卡驅動部分。利用網卡驅動部分接收來自TCP/IP協議棧的網絡分包並發送或者反過來將接收到的網絡分包傳給協議棧處理,而字符驅動部分則將網絡分包在用戶空間和內核空間之間傳送,模擬物理鏈路的數據接收和發送。Tun/tap驅動很好的實現了兩種驅動的結合。
二、Tun/Tap網卡創建
1. 確認內核是否支持tun/tap
1 [root@hunterfu]# modinfo tun 2 filename: /lib/modules/2.6.34.7-56.fc13.i686.PAE/kernel/drivers/net/tun.ko 3 alias: char-major-10-200 4 license: GPL 5 author: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com> 6 description: Universal TUN/TAP device driver 7 srcversion: 880DE258930FE60D765B735 8 depends: 9 vermagic: 2.6.34.7-56.fc13.i686.PAE SMP mod_unload 686
2.加載內核模塊 -
[root@hunterfu ~]# modprobe tun
[root@hunterfu ~]# lsmod | grep tun
tun 10548 1
執行以上命令后,出現如上輸出,說明模塊加載成功;
2. 創建和配置虛擬網卡
確認是否有tunctl命令,如果沒有通過yum安裝即可
[root@hunterfu ~]# yum install tunctl
創建虛擬網卡設備
[root@hunterfu ~]# tunctl -t tap0 -u root
設置虛擬網卡
[root@hunterfu ~]# ifconfig tap0 192.168.0.1 netmask 255.255.255.0 promisc
經過如上操作后,虛擬網卡已經建立和配置好了。
3. 作為系統服務隨系統自動啟動創建虛擬網卡
-
編寫配置腳本(符合chkconfig規范)
-
1 [root@hunterfu ~]# cat /etc/init.d/config_tap 2 #!/bin/bash 3 # 4 # config_tap Start up the tun/tap virtual nic 5 # 6 # chkconfig: 2345 55 25 7 8 USER="root" 9 TAP_NETWORK="192.168.0.1" 10 TAP_DEV_NUM=0 11 DESC="TAP config" 12 13 do_start() { 14 if [ ! -x /usr/sbin/tunctl ]; then 15 echo "/usr/sbin/tunctl was NOT found!" 16 exit 1 17 fi 18 tunctl -t tap$TAP_DEV_NUM -u root 19 ifconfig tap$TAP_DEV_NUM ${TAP_NETWORK} netmask 255.255.255.0 promisc 20 ifconfig tap$TAP_DEV_NUM 21 } 22 23 do_stop() { 24 ifconfig tap$TAP_DEV_NUM down 25 } 26 do_restart() { 27 do_stop 28 do_start 29 } 30 check_status() { 31 ifconfig tap$TAP_DEV_NUM 32 } 33 34 case $1 in 35 start) do_start;; 36 stop) do_stop;; 37 restart) do_restart;; 38 status) 39 echo "Status of $DESC: " 40 check_status 41 exit "$?" 42 ;; 43 *) 44 echo "Usage: $0 {start|stop|restart|status}" 45 exit 1 46 esac
可以根據具體需求修改此腳本
- 加入到系統服務中
- [root@hunterfu ~]# chkconfig --add config_tap
- [root@hunterfu ~]# chkconfig --level 345 config_tap on
- 操作完成后,就可以像其他標准服務一樣,通過service config_tap start來進行創建和啟動操作