① linux網路協議棧7--ipsec收發包流程
流程路徑:ip_rcv() --> ip_rcv_finish() --> ip_local_deliver() --> ip_local_deliver_finish()
解封側一定是ip報文的目的端,ip_rcv_finish中查到的路由肯定是本機路由(RTCF_LOCAL),調用 ip_local_deliver 處理。
下面是貼的網上的一張圖片。
ip_local_deliver_finish中 根據上次協議類型,調用對應的處理函數。inet_protos 中掛載了各類協議的操作集,對於AH或者ESP來說,是xfrm4_rcv,對於ipsec nat-t情況下,是udp協議的處理函數udp_rcv,內部才是封裝的ipsec報文(AH或者ESP)。
xfrm4_rcv --> xfrm4_rcv_spi --> xfrm4_rcv_encap --> xfrm_input
最終調用 xfrm_input 做收包解封裝流程。
1、創建SKB的安全路徑;
2、解析報文,獲取daddr、spi,加上協議類型(esp、ah等),就可以查詢到SA了,這些是SA的key,下面列出了一組linux ipsec的state(sa)和policy,方便一眼就能看到關鍵信息;
3、調用SA對應協議類型的input函數,解包,並返回更上層的協議類型,type可為esp,ah,ipcomp等。對應的處理函數esp_input、ah_input等;
4、解碼完成後,再根據ipsec的模式做解封處理,常用的有隧道模式和傳輸模式。對應xfrm4_mode_tunnel_input 和 xfrm4_transport_inout,處理都比較簡單,隧道模式去掉外層頭,傳輸模式只是設置一些skb的數據。
5、協議類型可以多層封裝,如ESP+AH,所以需要再次解析內存協議,如果還是AH、ESP、COMP,則解析新的spi,返回2,查詢新的SA處理報文。
6、經過上面流程處理,漏出了用戶數據報文(IP報文),根據ipsec模式:
流程路徑如下圖,這里以轉發流程為例,本機發送的包主要流程類似。
轉發流程:
ip_forward 函數中調用xfrm4_route_forward,這個函數:
1、解析用戶報文,查找對應的Ipsec policy(__xfrm_policy_lookup);
2、再根據policy的模版tmpl查找對應最優的SA(xfrm_tmpl_resolve),模版的內容以及和SA的對應關系見上面貼出的ip xfrm命令顯示;
3、最後根據SA生成安全路由,掛載再skb的dst上; 一條用戶流可以聲明多個安全策略(policy),所以會對應多個SA,每個SA處理會生成一個安全路由項struct dst_entry結構(xfrm_resolve_and_create_bundle),這些安全路由項通過 child 指針鏈接為一個鏈表,其成員 output掛載了不同安全協議的處理函數,這樣就可以對數據包進行連續的處理,比如先壓縮,再ESP封裝,再AH封裝。
安全路由鏈的最後一個路由項一定是普通IP路由項,因為最終報文都得走普通路由轉發出去,如果是隧道模式,在tunnel output封裝完完成ip頭後還會再查一次路由掛載到安全路由鏈的最後一個。
註: SA安全聯盟是IPsec的基礎,也是IPsec的本質。 SA是通信對等體間對某些要素的約定,例如使用哪種協議、協議的操作模式、加密演算法、特定流中保護數據的共享密鑰以及SA的生存周期等。
然後,經過FORWARD點後,調用ip_forward_finish()-->dst_output,最終調用skb_dst(skb)->output(skb),此時掛載的xfrm4_output
本機發送流程簡單記錄一下,和轉發流程殊途同歸:
查詢安全路由: ip_queue_xmit --> ip_route_output_flow --> __xfrm_lookup
封裝發送: ip_queue_xmit --> ip_local_out --> dst_output --> xfrm4_output
註:
1). 無論轉發還是本地發送,在查詢安全路由之前都會查一次普通路由,如果查不到,報文丟棄,但這條路由不一定需要指向真實的下一跳的出介面,只要能匹配到報文DIP即可,如配置一跳其它介面的defualt。
2). strongswan是一款用的比較多的ipsec開源軟體,協商完成後可以看到其創建了220 table,經常有人問裡面的路由有啥用、為什麼有時有有時無。這里做個測試記錄: 1、220中貌似只有在tunnel模式且感興趣流是本機發起(本機配置感興趣流IP地址)的時候才會配置感興趣流相關的路由,路由指定了source;2、不配置也沒有關系,如1)中所說,只要存在感興趣流的路由即可,只不過ping的時候需要指定source,否者可能匹配不到感興趣流。所以感覺220這個表一是為了保證
ipsec封裝發送流程:
xfrm4_output-->xfrm4_output_finish-->xfrm_output-->xfrm_output2-->xfrm_output_resume-->xfrm_output_one
xfrm4_output 函數先過POSTROUTING點,在封裝之前可以先做SNAT。後面則調用xfrm_output_resume-->xfrm_output_one 做IPSEC封裝最終走普通路由走IP發送。
貼一些網上的幾張數據結構圖
1、安全路由
2、策略相關協議處理結構
3、狀態相關協議處理結構
② 如何在 Debian / Ubuntu 伺服器上架設 L2TP / IPSec VPN
首先解釋一個問題:在 iPhone 的 VPN 設置介面里(Settings >> General >> Network >> VPN),你可以看到三個標簽:L2TP, PPTP, IPSec。但上面我們又講本次介紹的 VPN 方式叫「L2TP / IPSec」,這兩者究竟是什麼關系?
這三個標簽確實令人混淆,准確的寫法應該是:L2TP over IPSec, PPTP, Cisco IPSec。PPTP 跟另外兩者關系不大,且大家較為熟悉,暫且不提,L2TP 和 IPSec 的區別如下。
L2TP:一個「包裝」協議,本身並不提供加密和驗證的功能。
IPSec:在 IP 數據包的層級提供加密和驗證功能,確保中間人無法解密或者偽造數據包。
本來,只用 IPSec 就可以實現 VPN,Mac OS X 和 Linux 都支持。但是 Mac OS X 和 iPhone OS 都推薦使用 L2TP over IPSec,在兩者的圖形介面上也只能設置這個。L2TP / IPSec 是業界標准,微軟也支持。而只用 IPSec 的常見於 Linux-to-Linux 的應用,比如將兩個位於不同地區的辦公室網路安全地連在一起。這多是固定 IP 路由器到固定 IP 路由器級別的連接,只需保證數據包不被中途截獲或者偽造就可以,故使用 L2TP 的意義不大。L2TP / IPSec 主要是實現所謂「Road Warrior」的設置,即用變動的客戶端連固定的伺服器。
Cisco 的 VPN 用的也是 IPSec 加密,但那是一套不同於 L2TP 的私有包裝協議,用於提供用戶管理之類的功能,因此一般都需要用 Cisco 自家的 VPN 客戶端連接。iPhone / iPad 的 VPN 設置介面中的 IPSec 標簽里有 Cisco 的標識,就是這個原因。
以下是在 Ubuntu 和 Debian 主機上架設 L2TP / IPSec VPN 的步驟,一共十四步。你需要有伺服器的 root 許可權(所以 DreamHost, BlueHost, MediaTemple 這些服務供應商幫你把一切打點周到的主機就無緣了),也需要一些基本的 Linux 知識。不然的話,我們還是推薦您找一位比較熟技術的朋友幫忙。
一、安裝 IPSec。如上所述,IPSec 會對 IP 數據包進行加密和驗證。這意味著你的電腦 / 移動設備與伺服器之間傳輸的數據無法被解密、也不能被偽造。我推薦用 openswan 這個後台軟體包來跑 IPSec。
用以下命令安裝 openswan:
sudo aptitude install openswan二、用文字編輯器打開 /etc/ipsec.conf,改成這樣:
version 2.0
config setup
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
oe=off
protostack=netkey
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3
rekey=no
ikelifetime=8h
keylife=1h
type=transport
left=YOUR.SERVER.IP.ADDRESS
leftprotoport=17/1701
right=%any
rightprotoport=17/%any三、用文字編輯器打開 /etc/ipsec.secrets,改成這樣:
YOUR.SERVER.IP.ADDRESS %any: PSK "YourSharedSecret"(別忘了把「YOUR.SERVER.IP.ADDRESS」這部分換成你的伺服器的 IP 地址,把「YourSharedSecret」部分換成隨便一個字串,例如你喜歡的一句話,等等。)
四、運行以下命令:
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done五、檢查一下 IPSec 能否正常工作:
sudo ipsec verify如果在結果中看到「Opportunistic Encryption Support」被禁用了,沒關系,其他項 OK 即可。
六、重啟 openswan:
sudo /etc/init.d/ipsec restart七、安裝 L2TP。常用的 L2TP 後台軟體包是 xl2tpd,它和 openswan 是同一幫人寫的。
運行以下命令:
sudo aptitude install xl2tpd八、用文字編輯器打開 /etc/xl2tpd/xl2tpd.conf,改成這樣:
[global]
ipsec saref = yes
[lns default]
ip range = 10.1.2.2-10.1.2.255
local ip = 10.1.2.1
;require chap = yes
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes這里要注意的是 ip range 一項里的 IP 地址不能和你正在用的 IP 地址重合,也不可與網路上的其他 IP 地址沖突。
九、安裝 ppp。這是用來管理 VPN 用戶的。
sudo aptitude install ppp十、檢查一下 /etc/ppp 目錄里有沒有 options.xl2tpd 這個文件,沒有的話就建一個,文件內容如下:
require-mschap-v2
ms-dns 208.67.222.222
ms-dns 208.67.220.220
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4注意 ms-dns 兩行我填的是 OpenDNS。如果你想用其他的 DNS 伺服器(例如谷歌的公共 DNS),請自行更換。
十一、現在可以添加一個 VPN 用戶了。用文字編輯器打開 /etc/ppp/chap-secrets:
# user server password ip
test l2tpd testpassword *如果你之前設置過 PPTP VPN,chap-secrets 文件里可能已經有了其他用戶的列表。你只要把 test l2tpd testpassword * 這樣加到後面即可。
十二、重啟 xl2tpd:
sudo /etc/init.d/xl2tpd restart十三、設置 iptables 的數據包轉發:
iptables --table nat --append POSTROUTING --jump MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward十四、因為某種原因,openswan 在伺服器重啟後無法正常自動,所以我們可以在 /etc/rc.local 文件里寫入如下語句:
iptables --table nat --append POSTROUTING --jump MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
/etc/init.d/ipsec restart到這里,設置工作已經基本完成。你可以用 iPhone 或 iPad 試著連一下。記得在「Secret」中填入你在上述第三步里填的 YourSharedSecret。
如果連接成功,上網也沒問題的話,恭喜你,大功告成。如果連不上,恐怕還得多做一步。
Ubuntu 9.10 自帶的 openswan 版本是 2.6.22, Debian Lenny 帶的版本是 2.4.12。這兩個版本的 openswan 都有問題。我們的測試結果表明,2.6.24 版的 openswan 可以在上述兩版的 Linux 操作系統下正常工作。所以如果做完以上十四步還是連不上的話,請考慮從源碼編譯 openswan 2.6.24
③ 群暉NAS安裝VPN Server 套件三種服務協議設定
我們在群暉nas里安裝VPN Server 套件可以把我們的群暉nas變成一個VPN伺服器,我們可以安全的在遠端存取Synology NAS 區域網內分享的資源,群暉的VPN server整合了常用的通訊協定: PPTP、OpenVPN 、 L2TP/IPSec,當我們啟用了nas的vpn服務,會影響系統的網路性能。
我們先來了解一下三種協議:
PPTP
PPTP (Point-to-Point Tunneling Protocol,點對點信道協議) 是常用的 VPN 解決方案,且大多數的客戶端 (包含 Windows、Mac、Linux 及行動裝置) 皆支持。
若要啟動 PPTP VPN 伺服器:
1、開啟 VPN Server 並前往左側面板的 PPTP。
2、勾選啟動 PPTP VPN 伺服器。
3、在動態 IP 地址欄位輸入 VPN 伺服器的虛擬 IP 地址。請參閱下方的關於動態 IP 地址來了解更多信息。
4、設定最大聯機數量來限制 VPN 聯機的共同聯機數量。
5、設定同一賬號最多聯機數量來限制使用同一個賬號所進行 VPN 聯機的共同聯機數量。
6、從認證下拉式選單中選擇下列任一項目來認證 VPN 客戶端:
PAP:認證過程中,將不加密 VPN 客戶端的密碼。
MS-CHAP v2:認證過程中,將使用 Microsoft CHAP version 2 加密 VPN 客戶端的密碼。
7、若您選擇 MS-CHAP v2 驗證,請從加密下拉式選單中選擇下列任一項目來加密 VPN 聯機:
No MPPE:VPN 聯機不會受到加密機制保護。
Optional MPPE:客戶端設定將決定 VPN 聯機會 / 不會受到 40-bit 或 128-bit 加密機制保護。
Require MPPE:客戶端設定將決定 VPN 聯機會受到 40-bit 或 128-bit 加密機制保護。
8、設定 MTU (最大傳輸單元) 來限制 VPN 網路傳輸的數據封包大小。
9、勾選手動設定 DNS 並指派 DNS 伺服器的 IP 地址來發送給 PPTP 客戶端。若停用此選項,則會將 Synology NAS 目前所使用的 DNS 伺服器發送給客戶端。
10、單擊套用來讓變更生效。
注意:
聯機至 VPN 時,VPN 客戶端的驗證及加密設定必須與 VPN Server 上的相同,否則客戶端將無法成功聯機。
為兼容於運行在 Windows、Mac OS、iOS 與 Android 系統的大部分 PPTP 客戶端,預設的 MTU 值為 1400。若您的網路環境較為復雜,可能需要設定一個較小的 MTU 值。若您經常收到逾時訊息或聯機不穩定,請降低 MTU 值。
請檢查 Synology NAS 與路由器上的埠轉送規則與防火牆設定,確認 TCP 1723 埠已開啟。
部分路由器內建 PPTP VPN 服務,因此可能已佔用 1723 埠。您需先透過路由器的管理介面關閉其內建的 PPTP VPN 服務,才能確保 VPN Server 上的 PPTP VPN 服務可以正常運作。此外,部分舊式路由器可能會封鎖 GRE 協議 (IP 協議 47),造成 VPN 聯機失敗;建議使用支持 VPN pass-through 聯機的路由器。
OpenVPN
OpenVPN 是開放原始碼的 VPN 服務解決方案,會以 SSL / TLS 加密機制保護 VPN 聯機。
若要啟動 OpenVPN VPN 伺服器:
1、開啟 VPN Server,前往左側面板的 OpenVPN。
2、勾選啟動 OpenVPN 伺服器。
3、在動態 IP 地址欄位輸入 VPN 伺服器的虛擬內部 IP 地址。請參閱下方的關於動態 IP 地址來了解更多信息。
4、設定最大聯機數量來限制 VPN 聯機的共同聯機數量。
5、設定同一賬號最多聯機數量來限制使用同一個賬號進行 VPN 聯機的共同聯機數量。
6、為 OpenVPN 數據傳輸設定埠與通訊協議。您可以決定要將何種協議的數據封包透過 VPN 轉送至 Synology NAS 的哪個埠。默認值為 UDP 埠 1194
注意: 為確保 Synology NAS 上的服務可以正常運作,請避免將同樣的一組埠與通訊協議指派給其他 Synology 服務。請參閱此篇應用教學以了解更多信息。
7、在加密下拉式選單中擇一,以加密 VPN 信道中的數據封包。
8、在驗證下拉式選單中擇一,以驗證 VPN 客戶端。
9、若要在傳輸數據時壓縮數據,請勾選啟動 VPN 壓縮聯機。此選項可提升傳輸速度,但可能會消耗較多系統資源。
10、勾選允許客戶端存取伺服器的區域網絡來讓客戶端存取伺服器的區域網絡。
11、勾選啟動 IPv6 伺服器模式來啟動 OpenVPN 伺服器,以傳送 IPv6 地址。您必須先在控制面板 > 網路 > 網路介面中,透過 6in4/6to4/DHCP-PD 取得 Prefix,並在此頁面中選擇該 Prefix。
12、單擊套用來讓變更生效。
注意:
VPN Server 不支持站台對站台的橋接模式。
請檢查 Synology NAS 與路由器上的埠轉送規則與防火牆設定,確認 UDP 1194 埠已開啟。
在 Windows Vista 或 Windows 7 上執行 OpenVPN GUI 時,請注意,UAC (用戶帳戶控制) 預設為開啟。此設定開啟時,需使用以系統管理員身份執行選項來透過 OpenVPN GUI 進行聯機。
在 Windows 上透過 OpenVPN GUI 啟動 IPv6 伺服器模式時,請注意以下事項:
VPN 所使用的介面名稱不可包含空格,例如:LAN 1 須變更為 LAN1。
重新導向網關 (redirect-gateway) 選項須由客戶端於 openvpn.ovpn 檔案中設定。若您不想設定此選項,應手動設定 VPN 介面的 DNS。您可以使用 Google IPv6 DNS:2001:4860:4860::8888。
若要匯出配置文件:
單擊匯出配置文件。OpenVPN 讓 VPN 伺服器可頒發證書供客戶端使用。所匯出的檔案為 zip 壓縮文件,其中包含 ca.crt (VPN 伺服器的憑證檔案)、openvpn.ovpn (客戶端使用的配置文件案),以及 README.txt (客戶端如何設定 OpenVPN 聯機的簡易說明)。
注意:
每次啟動 VPN Server 時,便會自動復制、使用顯示於控制面板 > 安全性 > 憑證之憑證。若您需使用第三方憑證,請到控制台 > 安全性 > 憑證 > 新增來匯入憑證,並重新啟動 VPN Server。
每次修改憑證文件 (顯示於控制面板 > 安全性 > 憑證) 後,VPN Server 將會自動重新啟動。
L2TP/IPSec
L2TP (Layer 2 Tunneling Protocol) over IPSec 提供更安全的虛擬私有網路,且大多數的客戶端 (如 Windows、Mac、Linux 及行動裝置) 皆支持。
若要啟動 L2TP/IPSec VPN 伺服器:
1、開啟 VPN Server 並前往左側面板的 L2TP/IPSec。
2、勾選啟動 L2TP/IPSec VPN 伺服器。
3、在動態 IP 地址欄位輸入 VPN 伺服器的虛擬 IP 地址。請參閱下方的關於動態 IP 地址來了解更多信息。
4、設定最大聯機數量來限制 VPN 聯機的共同聯機數量。
5、設定同一賬號最多聯機數量來限制使用同一個賬號進行 VPN 聯機的共同聯機數量。
6、從認證下拉式選單中選擇下列任一項目來認證 VPN 客戶端:
PAP:認證過程中,將不加密 VPN 客戶端的密碼。
MS-CHAP v2:認證過程中,將使用 Microsoft CHAP version 2 加密 VPN 客戶端的密碼。
7、設定 MTU (最大傳輸單元) 來限制 VPN 網路傳輸的數據封包大小。
8、勾選手動設定 DNS 並指派 DNS 伺服器的 IP 地址來發送給 L2TP/IPSec 客戶端。若停用此選項,則會將 Synology NAS 目前所使用的 DNS 伺服器發送給客戶端。
9、若要發揮 VPN 最大效能,選取執行核心 (kernel) 模式。
10、輸入並確認預先共享密鑰。您應將此密鑰提供給 L2TP/IPSec VPN 使用者以驗證聯機。
11、勾選啟動 SHA2-256 兼容模式 (96 bit),以讓特定客戶端 (非 RFC 標准) 可以使用 L2TP/IPSec 聯機。
12、單擊套用來讓變更生效。
注意:
聯機至 VPN 時,VPN 客戶端的驗證及加密設定必須與 VPN Server 上的設定相同,否則客戶端將無法成功進行聯機。
為兼容於運行在 Windows、Mac OS、iOS 與 Android 系統的大部分 L2TP/IPSec 客戶端,預設的 MTU 值為 1400。若您的網路環境較為復雜,可能需要設定一個較小的 MTU 值。若您經常收到逾時訊息或聯機不穩定,請降低 MTU 值。
請檢查 Synology NAS 與路由器上的埠轉送規則與防火牆設定,以確認 UDP 1701、500、4500 埠已開啟。
部分路由器內建 L2TP 或 IPSec VPN 服務,因此可能已佔用 1701、500 或 4500 埠。您需先透過路由器的管理介面關閉其內建的 L2TP 或 IPsec VPN 服務,才能確保 VPN Server 上的 L2TP/IPsec VPN 服務可以正常運作。建議使用支持 VPN pass-through 聯機的路由器。
關於動態 IP 地址
VPN Server 會依據您在動態 IP 地址中輸入的數字,從虛擬 IP 地址范圍中選擇一個 IP 地址來分配給 VPN 客戶端使用。例如:若 VPN 伺服器的動態 IP 地址設定為「10.0.0.0」,則 PPTP VPN 客戶端的虛擬 IP 地址范圍為「10.0.0.1」至「10.0.0.[最大聯機數量]」;OpenVPN 客戶端的虛擬 IP 地址范圍則為「10.0.0.2」至「10.0.0.255」。
重要事項: 指定 VPN 伺服器的動態 IP 地址之前,請注意:
1、VPN 伺服器可使用的動態 IP 地址必須為下列其一:
從「10.0.0.0」至「10.255.255.0」
從「172.16.0.0」至「172.31.255.0」
從「192.168.0.0」至「192.168.255.0」
2、您指定的 VPN 伺服器動態 IP 地址以及指派給 VPN 客戶端的虛擬 IP 地址,皆不能與區域網絡中任一已使用的 IP 地址沖突。
關於客戶端進行 VPN 聯機時使用的網關設定
使用 VPN 聯機至 Synology NAS 的區域網絡之,客戶端可能需要為 VPN 聯機變更網關設定;否則,在 VPN 聯機建立之後,它們可能會無法聯機至網際網路。