一個傳統的 VPN(如 OpenVPN、PPTP)由一個 VPN 服務器和一個或多個連接到這臺服務器的客戶端組成。當任意兩個 VPN 客戶端彼此通信時,VPN 服務器需要中繼它們之間的 VPN 數據流量。這樣一個中心輻射型的 VPN 拓撲結構存在的問題是,當連接的客戶端增多以后,VPN 服務器很容易成為一個性能上的瓶頸。從某種意義上來說,中心化的 VPN 服務器也同樣成為一個單點故障的來源,也就是當 VPN 服務器出現故障的時候,整個 VPN 都將無法被任何 VPN 客戶端訪問。
點對點 VPN(又稱 P2P VPN)是另一個 VPN 模型,它能解決傳統的基于服務器-客戶端模型的 VPN 存在的這些問題。一個 P2P VPN 中不再有一個中心的 VPN 服務器,任何擁有一個公開 IP 地址的節點都能引導其他節點進入 VPN。當連接到一個 VPN 之后,每一個節點都能與 VPN 中的任何其他節點直接通信,而不需要經過一個中間的服務器節點。當然任何節點出現故障時,VPN 中的剩余節點不會受到影響。節點中的延遲、帶寬以及 VPN 擴展性在這樣的設定中都有自然的提升,當你想要使用 VPN 進行多人游戲或者與許多朋友分享文件時,這都是十分理想的。
開源的 P2P VPN 實現已經有幾個了,比如 Tinc、peerVPN,以及 n2n。在本教程中,我將會展示如何在 Linux 上用 n2n 配置點對點 VPN。
n2n 是一個開源(GPLv3)軟件,它允許你在用戶間構建一個加密的 2/3 層點對點 VPN。由 n2n 構建的 VPN 是“對 NAT 友好”的,也就是說,不同 NAT 路由器后方的兩個用戶可以通過 VPN 直接與對方通信。n2n 支持對稱的 NAT 類型,這是 NAT 中限制最多的一種。因此,n2n 的 VPN 數據流量是用 UDP 封裝的。
一個 n2n VPN 由兩類節點組成:邊緣(edge)節點和超級(super)節點。一個邊緣節點是一臺連接到 VPN 的電腦,它可能在一個 NAT 路由器后方。一個超級節點則是擁有一個可以公共訪問的 IP 地址的電腦,它將會幫助 NAT 后方的邊緣節點進行初始通信。想要在用戶中創建一個 P2P VPN 的話,我們需要至少一個超級節點。
準備工作
在這篇教程中,我將會創建一個擁有 3 個節點的 P2P VPN:一個超級節點和兩個邊緣節點。唯一的要求是,邊緣節點需要能夠 ping 通超級節點的 IP 地址,而它們是否在 NAT 路由器之后則沒有什么關系。
在 Linux 上安裝 n2n
若想用 n2n 構建一個 P2P VPN,你需要在每個節點上安裝 n2n,包括超級節點。
由于它非常精簡的依賴需求,在大多數 Linux 平臺上 n2n 都能被輕松編譯。
在基于 Debian 的系統上安裝 n2n:
在基于 Red Hat 的系統上安裝 n2n:
用 n2n 配置一個 P2P VPN
如前文所述,我們需要至少一個超級節點,它將會作為一個初始化引導服務器。我們假設這個超級節點的 IP 地址是 1.1.1.1。
超級節點:
在一個作為超級節點的電腦上運行下面的命令。其中“-l ”指定超級節點的監聽端口。運行 supernode 并不需要 root 權限。
邊緣節點:
在每個邊緣節點上,使用下面的命令來連接到一個 P2P VPN。edge 守護程序將會在后臺運行。
邊緣節點 #1:
邊緣節點 #2:
下面是對命令行的一些解釋:
“-d ”選項指定了由 edge 命令創建的 TAP 接口的名字。
“-a ”選項(靜態地)指定了分配給 TAP 接口的 VPN 的 IP 地址。如果你想要使用 DHCP,你需要在其中一臺邊緣節點上配置一臺 DHCP 服務器,然后使用“-a dhcp:0.0.0.0”選項來代替。
“-c ”選項指定了 VPN 組的名字(最大長度為 16 個字節)。這個選項可以被用來在同樣一組節點中創建多個 VPN。
“-u”和“-g”選項被用來在創建一個 TAP 接口后降權放棄 root 權限。edge 守護進程將會作為指定的用戶/組 ID 運行。
“-k ”選項指定了一個由 twofish 加密的密鑰來使用。如果你想要將密鑰從命令行中隱藏,你可以使用 N2N_KEY 環境變量。
“-l ”選項指定了超級節點的監聽 IP 地址和端口號。為了冗余,你可以指定最多兩個不同的超級節點(比如 -l -l )。
“-m ”給 TAP 接口分配了一個靜態的 MAC 地址。不使用這個參數的話,edge 命令將會隨機生成一個 MAC 地址。事實上,為一個 VPN 接口強制指定一個靜態的 MAC 地址是被強烈推薦的做法。否則,比如當你在一個節點上重啟了 edge 守護程序的時候,其它節點的 ARP 緩存將會由于新生成的 MAC 地址而遭到污染,它們將不能向這個節點發送數據,直到被污染的 ARP 記錄被消除。
至此,你應該能夠從一個邊緣節點用 VPN IP 地址 ping 通另一個邊緣節點了。
故障排除
在調用 edge 守護程序的時候得到了如下錯誤。
n2n[4405]: ERROR: ioctl() [Operation not permitted][-1]
注意 edge 守護進程需要超級用戶權限來創建一個 TAP 接口。因此需要確定用 root 權限來執行,或者對 edge 命令設置 SUID。之后你總是可以使用“-u”和“-g”選項來降權放棄 root 權限。
總結
n2n 可以成為對你來說非常實用的免費 VPN 解決方案。你可以輕松地配置一個超級節點,無論是用你自己家里的網絡,還是從云主機提供商購買一個可以公共訪問的 VPS 實例。你不再需要把敏感的憑據和密鑰放在第三方 VPN 提供商的手里,使用 n2n,你可以在你的朋友中配置你自己的低延遲、高帶寬、可擴展的 P2P VPN。