OpenVPN實際上是在應用程式層做的傳輸, 傳輸協議可以選擇UDP/TCP, 其中UDP更為常用, 原因有專門文章論述。
為何需要OpenVPN網路?
如果我想在家裡訪問單位的網路資源, VPN是個不錯的選擇, 但一般來說, 架設VPN需要有VPN伺服器, 也就是說至少需要有一個真實IP, 這個並不是誰個人都有的. 但別忘了OpenVPN支援UDP傳輸, 在BT大行其道的今天, UDP很多時候就是NAT穿透的代名詞, 那麼, OpenVPN能不能也使用這種模式呢? 如果能, 那將會解決不少問題,
設想:
1, 我是一個學生, 我在寫論文, 但我目前不在學校, 因而不能下載學校論文資料庫的資料, 老讓同學下也不是辦法, 而且不方便, 這樣我可以考慮在學校任意電腦上開一個OpenVPN軟體, 然後讓它穿越NAT對外提供服務, 這樣我就可以在校外網路上和學校裡一樣使用.
2, 我是一個上班族, 我想在家裡做一些要在單位網路裡才能完成的事情, 但單位沒有VPN或者有VPN但我沒帳號, 我可以在單位的工作機上放個OpenVPN然後回家接入再用, 呵呵.
聽起來不錯, 但如何?呢? 這裡我先說明一些技術前提: 你應該知道平常怎麼配置OpenVPN, 即有真實IP時候怎麼配置, 如果不瞭解, 上GOOGLE搜尋吧, 文章很多.
處於防火牆或者NAT裝置後面的主機想要對外提供服務, 比如和其他同樣處於不通網路NAT裝置之後的主機通訊, 可以使用UDP打洞技術, 這個細節網上也有很多文章講, 可以參考http://www.ppcn.net/n1306c2.aspx
解決UDP穿越防火牆問題
在能使用UDP成功打洞之前, 要先解決以下幾個問題:
1, 確認通訊雙方所處NAT的類型, NAT可以大致的分成兩類: 錐形NAT和對稱NAT(關於NAT的詳細分類可以參考RFC3489第5節, 那裡分了4類, 前三類歸為錐形NAT, 第4類為對稱NAT). 做UDP穿透的一般原則是, 錐形NAT之間可以做UDP穿透, 而對稱NAT不能, 事實上, 當一端為錐形一段為對稱也是有可能的, 但這不能保證, 主要看對稱NAT有沒有規律可循.
如何確定自身的NAT類型呢? 可以利用STUN的用戶端查看, 軟體可以從這裡擷取:
Linux版: http://sourceforge.net/projects/stun/
Java版(適用各種作業系統): http://jstun.javawi.de/
這些軟體很好使用, 比如Linux版的stun, 編譯好後運行 ./client stun01.sipphone.com 即可.
Java版則直接雙擊jar檔案執行, 它會將結果記錄在同目錄的log檔案裡. 你只需要確認通訊雙方都不是對稱NAT即可. 如果雙方均為對稱NAT那本文所描述的方法沒有希望了. 如果查類型失敗, 這可能的原因有兩種:
a, 無法訪問該STUN伺服器, 你可以試試後面STUN列表中的其他伺服器, 如果你是教育網使用者且不能訪問國外流量, 那麼暫時沒有辦法用, 因為還沒有找到國內的開放STUN伺服器.
b, 你所在網路的防火牆把UDP禁了, 這種情況我見過, 很變態, 沒有任何辦法.
確認了兩端NAT類型都不是對稱NAT則繼續往下看, 否則希望不大, 但也還有機會.
2, 通訊建立前需要通訊雙方告知對方自己經NAT裝置轉換後的IP/PORT, IP/PORT也可以通過STUN伺服器得到, 公網上有不少這種免費STUN服務, 只是國內的很少見.
前兩個問題歸結一下, 其實就是如何找到免費的STUN伺服器, 下面的列表是我試過能用的, 但都在國外, 這對教育網使用者不是個好訊息, 國內的還在尋找中, 也希望有人能提供線索
stun01.sipphone.com
stun.ekiga.net
stun.fwdnet.net
stun.ideasip.com
stun.iptel.org
stun.rixtelecom.se
stun.schlund.de
stunserver.org
stun.softjoys.com
stun.voiparound.com
stun.voipbuster.com
stun.voipstunt.com
stun.voxgratia.org
stun.xten.com
3, 現在已經能知道自己經NAT映射後的真真實位址了, 但如何才能告訴對方呢, 目前廣泛使用的BT應用中實際上都有一個中繼伺服器, 但我們不會有, 否則的話我直接就拿它做VPN伺服器了
解決這個問題有點麻煩, 在我的這個例子裡是用的GMail做互動, 用戶端註冊一個GMail帳號, 服務端註冊一個GMail帳號, 這樣就有了一個速度很慢的管道, 但至少能完成通訊了, 流程也就可以通了.
到了這裡, 能查自己的IP/PORT, 有通訊兩端互動的管道, 剩下的問題就是定一個簡單的協議把這些真正的跑起來.
如何建立UDP通道?
1, 用戶端發起, 通過Mail告訴伺服器用戶端經NAT映射後的IP/PORT.
2, 服務端查詢自己經NAT映射後的IP/PORT並將其通過郵件返回給用戶端, 同時向用戶端的UDP連接埠做打洞操作.
3, 用戶端收到服務端的Mail後向服務端UDP連接埠發送資料, 這時服務端UDP連接埠應該能收到資料, 返回一條UDP資訊給用戶端, 標誌通道建立成功.
4, 服務端啟動OpenVPN, 用戶端開啟OpenVPN用戶端, 通過剛才建立的通道即可建立VPN串連.這個過程我用Python做了一個模型實現, 不能說是軟體, 只是一些指令碼, 但能穩定工作, 這裡介紹一下使用過程:
1, 配置OpenVPN, 這個過程和有真實IP完全相同, 我這裡列舉一個非常簡單的例子, 這裡預設伺服器運行在Linux平台, 用戶端則在Windows上, OpenVPN採用2.0.9版本, 用戶端我用的是OpenVPN GUI for
Windows V1.0.3, 預設安裝路徑.
可以在區域網路找兩台機器(或者虛擬機器)做測試, 你需要將用戶端配置中的remote改為OpenVPN服務所在主機IP/PORT.
圖1 OpenVPN服務端簡明配置
圖2 OpenVPN用戶端簡明配置
配置好之後, 用用戶端串連服務, 應該可以連通, 然後從用戶端機器ping 10.4.0.1如果響應, 則配置完成, 可進行下一步, 否則, 請尋找原因, 參考OpenVPN的相關文檔以及網路上關於OpenVPN配置的文章.
2, 申請兩個GMail帳號做通訊使用, 比如openvpn.nat.server@gmail.com, openvpn.nat.client@gmail.com, 注意申請完後進入GMail郵箱設定, 開啟IMAP支援, 否則後面無法繼續.
3, 擷取UDP穿透NAT的代碼, 從http://code.google.com/p/natvpn/downloads/list擷取最新包即可, 也可以從svn擷取最新的代碼. 擷取後解壓包, 我的例子是伺服器運行在Linux作業系統, 用戶端運行在Windows上, 其實和系統關係不大, 圖方便而已, OpenVPN和Python都是跨平台的, 需要的只是修改路徑. Python版本是2.5.
解壓, 先設定管理員, 把源碼目錄下的幾個*.py和OpenVPN設定檔都拷貝到你習慣的位置, 比如/usr/local/etc下, 然後修改server.py檔案中的路徑, 與你的系統保持一致:
圖3 server.py中需要更改的變數
然後是用戶端, 將*.py和OpenVPN用戶端設定檔拷貝到OpenVPN安裝路徑下的config目錄. 注意client.ovpn檔案要可寫, 因為指令碼會在後面重寫該檔案中的remote地址等部分.
圖4 client.py中需要更改的變數
4, 啟動服務端, 注意要用root啟動:
# ./server.py
5, 回家:) 然後啟動用戶端. Windows首先要安裝Python, 我用ActiveState Python 2.5, 很方便安裝, 軟體可以從http://www.activestate.com/Products/activepython/下載. 然後雙擊執行client.py, 運行一直到它提示可以串連, 這個過程在當前的配置狀態下需要三到五分鐘左右,
這主要是因為GMail設定的查新郵件時間有3分鐘, 最後應該出現如提示:
圖5 用戶端執行UDP打洞成功後的提示介面
看到這個畫面, 說明UDP通道已經打通, 這是你需要儘快(1分種以內)啟動OpenVPN用戶端, 這樣即可完成串連.
圖6 啟動OpenVPN用戶端串連
我從家裡串連單位, 單位是對稱NAT, 家裡是錐形NAT, 本來這種網路連通的希望不大, 但我對單位的NAT方式稍有瞭解, 他的NAT映射具有時間局部性, 所以在server.py/client.py中做了一些最佳化: 針對一個PORT範圍打洞, 而不是針對某個具體PORT, 這樣, 串連可以成功建立, 從無失手:)
不得不說, OpenVPN的通訊品質還是很不錯的, 我使用的這段時間從沒有出現過串連中斷, 值得一試!
轉載:http://cisco.chinaitlab.com/compose/757854_5.html