程式扎記: [Linux 文章收集] Linux下 TUN/TAP 虛擬網卡的使用

標籤

2016年11月15日 星期二

[Linux 文章收集] Linux下 TUN/TAP 虛擬網卡的使用

Source From Here 
Preface 
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網卡創建 

確認內核是否支持 tun/tap 
確認內核是否有 tun 模塊: 

# modinfo tun
filename: /lib/modules/2.6.32-642.3.1.el6.x86_64/kernel/drivers/net/tun.ko
alias: char-major-10-200
license: GPL
...

加載內核模塊: 
# modprobe tun
# lsmod | grep tun
tun 17094 2 vhost_net

執行以上命令後,出現如上輸出,說明模塊加載成功. 

創建和配置虛擬網卡 
確認是否有 tunctl 命令,如果沒有通過 yum 安裝即可: 
# yum install tunctl

// -t interface: Specifies the desired interface name.
// -u user: Specifies the owner of the interface. This user is allowed to attach to the "network/wire" side.
# tunctl -t tap0 -u root // 創建虛擬網卡設備
# ifconfig tap0 192 .168 .0 .1 netmask 255 .255 .255 .0 promisc // 設置虛擬網卡

經過如上操作後,虛擬網卡已經建立和配置好了。 

作為系統服務隨系統自動啟動創建虛擬網卡 
編寫配置腳本(符合 chkconfig 規範): 
# cat /etc/init.d/config_tap
  1. #!/bin/bash   
  2. #   
  3. # config_tap Start up the tun/tap virtual nic   
  4. #   
  5. # chkconfig: 2345 55 25  
  6.     
  7. USER= "root"   
  8. TAP_NETWORK= "192.168.0.1"  
  9. TAP_DEV_NUM=0  
  10. DESC= "TAP config"  
  11.      
  12. do_start () {  
  13.     if [ ! -x /usr/sbin/tunctl ]; then   
  14.         echo  "/usr/sbin/tunctl was NOT found!"   
  15.         exit 1  
  16.     fi   
  17.     tunctl -t tap $TAP_DEV_NUM -u root  
  18.     ifconfig tap $TAP_DEV_NUM  ${TAP_NETWORK}   netmask 255.255.255.0 promisc  
  19.     ifconfig tap $TAP_DEV_NUM  
  20. }  
  21.     
  22. do_stop () {  
  23.     ifconfig tap $TAP_DEV_NUM down  
  24. }  
  25. do_restart () {  
  26.     do_stop  
  27.     do_start  
  28. }  
  29. check_status () {  
  30.     ifconfig tap $TAP_DEV_NUM   
  31. }  
  32.     
  33. case  $1  in   
  34.     start) do_start;;  
  35.     stop) do_stop;;  
  36.     restart) do_restart;;  
  37.     status)  
  38.         echo  "Status of $DESC : "  
  39.         check_status  
  40.         exit  "$?"  
  41.         ;;  
  42.     *)  
  43.     echo  "Usage: $0 {start|stop|restart|status}"   
  44.     exit 1   
  45. esac  

可以根據具體需求修改此腳本. 加入到系統服務中: 
# chkconfig --add config_tap
# chkconfig --level 345 config_tap on

操作完成後,就可以像其他標準服務一樣,通過 service config_tap start 來進行創建和啟動操作. 

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!