使用 Strongswan 架設 Ipsec VPN
什麼是 IPsec?
IPsec 是 虛擬私密網路(VPN) 的一種,用於在伺服器和客戶端之間建立加密隧道並傳輸敏感資料之用。它由兩個階段組成,第一階段(Phrase 1, ph1),交換金鑰建立連線,使用網際網路金鑰交換(ike)協議; 第二階段(Phrase 2, ph2),連線建立後對資料進行加密傳輸,使用封裝安全載荷(esp)協議。參考:維基百科 IPsec 詞條
其中,第一階段和第二階段可以使用不同的加密方法(cipher suites)。甚至,第一階段 ike 協議的第一版(ikev1)有兩種模式,主力模式(main mode)和積極模式(aggressive mode),主力模式進行六次加密握手,而積極模式並不加密,以實現快速建立連線的目的。
第一階段的 ike 協議有兩個版本(ikev1/ikev2),不同的開源/閉源軟體實現的版本均不同,不同的裝置實現的版本也不同。再聯絡到第一階段/第二階段使用的各種不同加密方法,使得 IPsec 的配置有點黑魔法的性質,要麼完全懂,通吃; 要麼完全不懂,照抄。
裝置/作業系統規格
這裡主要介紹了裝置/作業系統使用的 ike 版本及其特殊要求。
Linux
命令列客戶端就是 strongswan 本身,因此完美相容,支援 ikev1/ikev2 和所有加密方法的連線。因此如果使用者只使用 Linux 命令列客戶端,不使用各種移動裝置也不使用 Windows,那麼完全沒有那麼多事。
但 Linux 的圖形介面客戶端 NetworkManager-strongswan 目前只支援 ikev2 連線,必須使用證書或 EAP (各種加密方法都支援,包括微軟的 MSCHAPv2)進行認證,不支援純密碼(PSK)認證。這並不是 strongswan 的錯誤,或者技術不行(開源總是走在技術最前沿的,畢竟命令列是支援的),而僅僅是體現一種選擇:ikev1 被 strongswan 專案認為是該淘汰的協議,而 PSK 加密被認為是非常不安全的。參考 strongswan 維基 NetworkManager 詞條。
Android
Android 和 Linux 不一樣,只支援 ikev1。其它方面和 Linux 一樣,甚至有好多種 IPsec VPN 配置模式可供選擇。
iOS/Mac OS X
它們宣告使用的 IPsec 客戶端為 Cisco,實際為自己修改的 racoon。它只支援 ike 協議的第一版即 ikev1,可以使用證書或純密碼(PSK)認證,但必須輔之 xauth 使用者名稱/密碼認證。
該修改版的 racoon 會優先使用不加密的積極模式,而積極模式是 strongSwan 所不支援的。所以要使用主力模式。
iOS 6 還有一個「銜尾」故障:它在第一階段握手時會把資料包拆分成小塊(fragmentation),然後「加密」傳送。然而這種加密僅僅是宣告的,其實並未加密,這就導致 strongSwan 及其它標準伺服器端/Cisco 裝置無法解密。另外 ikev1 的 fragmentation 外掛是閉源的。開源伺服器端無法對這些小塊進行重組。參考:Cisco VPN stop working after upgrading to IOS 6
所以產生了一種權宜之計,就是使用小證書(小於 1024,預設一般為 2048),來達到不拆包的目的。但是 Mac OS X 10.7 的更新卻對這種方式進行了封殺,學習微軟加入了證書驗證,小證書直接拒絕。
Windows
微軟的差勁只比 iOS 好一點。好處在於它支援了 ikev2,但是隻在 Windows 7 以後支援,Vista 之前依然使用 ikev1。
壞處在於它的 ikev2 支援非常詭異,指定了 Diffie Hellman group(DH,迪菲-赫爾曼金鑰交換組)必須是 modp1024。這是非常少見理論上不應該由系統管理員操心的加密選項:
在 strongswan 中,定義第一階段(ike)和第二階段(esp)加密方法的語法是:
ike/esp=encryption-integrity[-dhgroup][-esnmode] 第一階段/第二階段=加密方法-健壯性認證方法 (後面兩項可選)[-DH 組] [-擴充套件序列號支援模式(RFC4304)]
Windows 定義了一個可選的選項,導致了我們必須去定義整個第一階段的加密方法。這樣被破解的可能性就提高了。
其次在於它的 rekey(重連)。IPsec 的認證是有時效的,超過時間會重新認證。這種 CHILD_SA 認證可由伺服器發出,也可由客戶端發出,一般是由伺服器發出。但是 Windows 7 的 ikev2 的表現是,如果你在路由器(NAT)後,收到這種請求會把微軟內部的通知程式碼發出去,程式碼為 12345, 經過 strongswan 專案偵錯後發現這個程式碼的意思是 ERROR_IPSEC_IKE_INVALID_SITUATION。但是處理不了,它不是 IPsec 標準協議定義過的錯誤。
於是有兩種權宜之計:
一種是讓 Windows 7 來主動 rekey。Windows 7 rekey 的時間大約是 58 分 46 秒,所以要配置伺服器 rekey 時間比它長。但是效果非常不好。因為 rekey 是由三個變數控制的,key 的生命週期,key 的邊際時間(生命週期前多久進行 rekey),和邊際時間誤差(rekeyfuzz),誤差是不可控的。參考:ExpiryRekey。
即使能控制 strongswan 這邊,Windows 依然是「大約」; 即使兩邊都能控制,假設伺服器延後一秒 rekey,理論上如果連線持續時間足夠長,依然能夠撞車:58x60+46 次 rekey 後即 146 天后撞車,連一年都沒有,在 Linux 伺服器對 Windows 伺服器這種使用例項中就明顯不符合要求。
所以目前只能使用後一種方法即完全禁用伺服器端 rekey。
最後,它的 EAP 認證也非常糟糕。MSCHAPv2 的 eap 身份不是 ikev2 身份(ikev2 身份一般是 EAP 使用者名稱),所以必須在伺服器端顯式定義 eap_identity 來使用 Windows 7 的 eap 身份。
安裝 Srongswan
這裡 --no-recommends 是不帶推薦軟體包,因為推薦的軟體包都是針對桌面環境的,伺服器用不到。
如果你的版本是 openSUSE 12.1/12.2,請相應替換源地址。生成證書(可選)
注意 如果不生成證書,後面配置部分的配置中用 pubkey 認證的 conn 都不能用,甚至不能保留在配置中。每一個完整的 ssl 證書都有一個公鑰和一個私鑰,它們可以在一起也可以分開放(當然如果你要在網路上傳輸,肯定只能用公鑰)。公鑰是在網路上傳輸的,而私鑰是藏好用來和接收到的公鑰配對的(因此私鑰裡也有整個公鑰,用來配對)。
生成 CA 證書
生成一個私鑰:
ipsec pki --gen --outform pem > ca.pem
沒什麼好解釋的,--outform 一共有三個格式可選,但是另外兩個是 der 和 pgp...
基於這個私鑰自己籤一個 CA 證書:
ipsec pki --self --in ca.pem --dn "C=CN, O=strongSwan, CN=strongSwan CA" --ca --outform pem > ca.cert.pem
這裡 --self 表示自簽證書,--in 是輸入的私鑰,--dn 是判別名,--ca 表示生成 CA,其它同上。這裡需要解釋下判別名:
- C 表示國家名,同樣還有 ST 州/省名,L 地區名,STREET(全大寫) 街道名。
- O 表示組織名。
- CN 為通用名。
生成伺服器證書
同樣生成私鑰:
ipsec pki --gen --outform pem > server.pem
用我們剛才自籤的 CA 證書給自己發一個伺服器證書:
ipsec pki --pub --in server.pem | ipsec pki --issue --cacert ca.cert.pem \ --cakey ca.pem --dn "C=CN, O=strongSwan, CN=forum.suse.org.cn" \ --san="forum.suse.org.cn" --flag serverAuth --flag ikeIntermediate \ --outform pem > server.cert.pem
這條命令的意思解釋下:
ipsec pki --pub --in server.pem
是從我們剛生成的私鑰裡把公鑰提取出來,然後用公鑰去參與後面的伺服器證書籤發(這個是 VPN 連線時候要用的,你不想把私鑰也給它吧?那樣跟沒簽證書一樣...)。
--issue, --cacert 和 --cakey 就是表明要用剛才自籤的 CA 證書來籤這個伺服器證書。
--dn, --san,--flag 是一些客戶端方面的特殊要求:
- iOS 客戶端要求 CN 也就是通用名必須是你的伺服器的 URL 或 IP 地址;
- Windows 7 不但要求了上面,還要求必須顯式說明這個伺服器證書的用途(用於與伺服器進行認證),--flag serverAuth;
- 非 iOS 的 Mac OS X 要求了「IP 安全網路金鑰互換居間(IP Security IKE Intermediate)」這種增強型金鑰用法(EKU),--flag ikdeIntermediate;
- Android 和 iOS 都要求伺服器別名(serverAltName)就是伺服器的 URL 或 IP 地址,--san。
生成客戶端證書
依然是生成私鑰:
ipsec pki --gen --outform pem > client.pem
然後用剛才自籤的 CA 證書來籤客戶端證書:
ipsec pki --pub --in client.pem | ipsec pki --issue --cacert caCert.pem \ --cakey caKey.pem --dn "C=CN, O=strongSwan, CN=client" \ --outform pem > client.cert.pem
這時命令列會提示你輸入兩遍密碼,這個就是你的客戶端證書密碼。
看懂了伺服器的,客戶端的也就不難理解了。除了沒有那一堆特殊要求別的都一樣。
客戶端證書可以每個客戶端籤一個,也可以讓它們公用一個。是否多籤看用途,一般用於區分裝置(計費是不用這樣的,是用賬戶來區分的)。
生成 pkcs12 證書(可選)
你可能還想生成一個可以直接匯入的 pkcs12 證書(用於手機,諾基亞沒這東西還不行):
openssl pkcs12 -export -inkey client.pem -in client.cert.pem -name "client" \ -certfile ca.cert.pem -caname "strongSwan CA" -out client.cert.p12
安裝證書
cp -r ca.cert.pem /etc/ipsec.d/cacerts/ cp -r server.cert.pem /etc/ipsec.d/certs/ cp -r server.pem /etc/ipsec.d/private/ cp -r client.cert.pem /etc/ipsec.d/certs/ cp -r client.pem /etc/ipsec.d/private/
CA 證書、客戶證書(兩個)和 .p12 證書用 FTP 複製出來給客戶端用。有幾種 Android 配置還需要伺服器證書(server.cert.pem)。
配置 Strongswan
ipsec.conf
config setup uniqueids=never conn iOS_cert keyexchange=ikev1 # strongswan version >= 5.0.2, compatible with iOS 6.0,6.0.1 fragmentation=yes left=%defaultroute leftauth=pubkey leftsubnet=0.0.0.0/0 leftcert=server.cert.pem right=%any rightauth=pubkey rightauth2=xauth rightsourceip=10.0.0.0/24 rightcert=client.cert.pem auto=add # also supports iOS PSK and Shrew on Windows conn android_xauth_psk keyexchange=ikev1 left=%defaultroute leftauth=psk leftsubnet=0.0.0.0/0 right=%any rightauth=psk rightauth2=xauth rightsourceip=10.0.0.0/24 auto=add # compatible with "strongSwan VPN Client" for Android 4.0+ # and Windows 7 cert mode. conn networkmanager-strongswan keyexchange=ikev2 left=%defaultroute leftauth=pubkey leftsubnet=0.0.0.0/0 leftcert=server.cert.pem right=%any rightauth=pubkey rightsourceip=10.0.0.0/24 rightcert=client.cert.pem auto=add conn windows7 keyexchange=ikev2 ike=aes256-sha1-modp1024! rekey=no left=%defaultroute leftauth=pubkey leftsubnet=0.0.0.0/0 leftcert=server.cert.pem right=%any rightauth=eap-mschapv2 rightsourceip=10.0.0.0/24 rightsendcert=never eap_identity=%any auto=add
其中 config setup 只能出現一次,而 conn <連線名稱> 可以有很多個。這裡的名稱不是預定義的,可以隨意寫,只要你能識別就行,主要用來定義一種連線,就是為了讓你在日誌裡好找。
新版 strongswan 裡 config setup 的內容不如舊版的多,許多舊版必須有的選項都被作廢了。比如:
- plutostart 新版所有的 ike 協議都由原來 ikev2 的 daemon:charon 接管。根本就沒有 pluto 了。
- nat_traversal 新版所有的 ike 協議都是可以穿越路由器(NAT)的。
- virtual_private 定義伺服器的區域網 IP 地址。現在被魔術字 0.0.0.0/0 取代了。
- pfs 完美向前保密,用於 rekey 時。意思是你現在的金鑰互換過程如果被攻破了,會不會對已經互換過的金鑰產生影響。以前一般設定成 no 來適用於 iOS 這種客戶端會以積極模式發出非加密的 rekey 請求的情況。現在這個選項完全沒作用了。第一階段永遠是完美向前保密的,第二階段(esp)如果指定了 DH 組那麼也是完美向前保密的,但是預設加密方法就已經指定了 DH 組。所以該選項永遠為 yes。
而另外舊版和新版都有的選項也都定義了預設值,比如:
- strictpolicy 是否一定需要證書吊銷列表(CRL)的 URL。預設就是 no。
- charonstart 是否啟動 ikev2 的 daemon。這是舊版加入的,因為那個時候的主力是 pluto。現在預設就是 yes,你改成 no 那你連原先 pluto 的連線都無法連線,因為 ike 協議的實現全被 charon 接管了。
所以 config setup 基本上佔位就行了。這裡我們修改了 uniqueids 的值來實現多裝置同時線上。
而 conn 最主要要理解左右的概念。其實左右是可以不分的,它們只是用來表示一個連線的兩端。只是在如果你定義的不夠全面時,左側會預設被認為是本機(你的 VPS),右側預設為他機(你的筆記本),即以左為尊。
- left/right 是左右 id。它們用來識別伺服器/客戶端,可以是證書的判別名(DN),比如 "C=CN, O=strongSwan, CN=strongSwan CA",也可以是 IP 地址,也可以是 EAP 的使用者名稱,還可以是魔術字 %any,表示什麼都行。只是在 5.0.0 之前,為本機這邊定義 %any 的話,ikev1 連線即 keyexchange=ikev1 的連線是識別不了,所以要改成 %defaultroute 表示自己從 ifconfig 裡取 IP。為了和 right 的 %any 區分開,我們使用這種方法。所以說到最後這兩個選項似乎沒有什麼用。但它們是必須的。
- leftauth/rightauth 這是最重要的改動。新版主要是作廢了之前的 authby 和 xauth=server/client 選項而都改用這種方法。因此使得 ikev1 也能夠出現混血認證(左右兩邊認證的方法不同)了。引數主要有 pubkey 表示用證書,psk 表示用密碼,eap 表示用擴充套件驗證協議。
- leftauth2/rightauth2 是為了應對舊版很常見的 authby=xauthpsk/xauthrsasig 的。現在 xauth 只能寫在這裡。而 psk 對應 leftauth/rightauth 裡的 PSK 方法,rsasig 則對應 pubkey 方法。
- leftsubnet 最重要的,引入了魔術字 0.0.0.0/0。如果你在右側為客戶端分配虛擬 IP 地址的話,那表示你之後要做 iptables 轉發,那麼左邊就必須是用魔術字。
- leftcert/rightcert 就是指定證書名字。
- rightsourceip 為客戶端分配的虛擬 IP 段。
- auto 定義 strongswan 啟動時該連線的行為。start 是啟動; route 是新增路由表,有資料通過就啟動; add 是新增連線型別但不啟動; ignore 是當它不存在。預設是 ignore。看起來似乎是 route 比較好,但問題是我們伺服器端不能預分配虛擬 IP,所以伺服器端一般用的都是 add。而客戶端文字配置可以選擇 start。
另外說下舊版的 xauth=server/client 的問題。它表示在伺服器端還是在客戶端執行 xauth 認證。而在新版中主要通過左右方向來體現。比如你在伺服器端執行認證,那認證請求是由客戶端發出的,所以要寫 rightauth2=xauth。如果在客戶端執行認證,那認證請求是伺服器發出的,所以要寫 leftauth2=xauth。
另外網上很常見的一個配置選項是 leftfirewall=yes。這是完全錯誤的。看上去它的唯一作用是定義你的伺服器是不是在防火牆後面,但實際上它是作為 ipsec_updown 指令碼的引數被開發出來,是表明你的本機 subnet 是不是用 iptables 轉發/偽裝出來的。如果是的話,就呼叫 left/rightupdown 定義的路徑下的指令碼,指令碼的作用是對通過 ipsec 連線的資料包進行 iptables 豁免。
之所以說它是錯到離譜的(雖然沒有產生影響),因為這些人完全就不懂,有公網 IP 的伺服器的 subnet 很少是偽裝的。另外必須寫了指令碼該選項才有意義,沒看過一個定義了這個選項的人寫過指令碼。還有,leftsubnet=0.0.0.0/0 通過魔術字把 subnet 定義為了 any,你根本沒法寫指令碼啊。所以我們這裡完全就不用。
至於某型別連線,主要是根據裝置規格定義的,一些特殊選項的解釋如下:
- fragmentation=yes 開啟對 iOS 拆包的重組支援。
- ike=aes256-sha1-modp1024! Windows 指定的第一階段加密方法。
- rekey=no 伺服器對 Windows 發出 rekey 請求會斷開連線。
- rightsendcert=never 因為這是一個混血連線。伺服器對自己的身份進行認證時使用的是證書,而伺服器對客戶端的認證使用的只是 eap-mschapv2。如果不設定的話預設是 ifasked,意思是如果伺服器向客戶端請求證書,客戶端就會給它,但客戶端給不出,連線就會斷。這裡設定為客戶端永遠不給,實際上的意思其實是伺服器不要向客戶端請求證書。
- eap_identity=%any 使用 Windows 的 eap 身份。不然會出現”no eap key found for host <rightid>“錯誤。
ipsec.secrets
# # ipsec.secrets # # This file holds the RSA private keys or the PSK preshared secrets for # the IKE/IPsec authentication. See the ipsec.secrets(5) manual page. # : RSA server.pem : PSK "PSK password" marguerite : XAUTH "user password" marguerite : EAP "user password"
看上去比較好理解,實際不是。
有些人可能會誤以為:
: PSK "PSK password" marguerite : XAUTH "user password"
是成對的,用於比如 android-xauth-psk 這樣的連線,於是到了 iOS 的時候又寫了一對:
: RSA server.pem marguerite : XAUTH "user password"
來支援 iOS 的 RSA + XAUTH 認證。
這樣做是沒有必要的,上面定義的是四種認證方法。它們之間是遵循「各找各媽」的原則的,可以任意混搭。即你寫了一個 XAUTH 即可支援所有完全使用或部分使用 XAUTH 方法的連線。
實際上:
: PSK "PSK password"
相當於:
%any %any : PSK "PSK password"
遵循:
主機 對等點 : 方法 <本機證書/協議密碼> <本機證書密碼>
的格式。以 :為分界,分別從左到右填充,除了各類密碼缺失以 null 補位,其它都用 %any 補位(密碼怎麼可能是 %any)。
於是
marguerite : EAP "user password"
相當於
marguerite %any : EAP "user password" // EAP 方法沒有證書,也就沒有證書密碼
這裡有些人可能迷惑了,前面不是說過以左為尊、本機(這裡是 VPS)預設在左邊嗎,你剛才定義 eap-mschapv2 的時候可是定義給的 rightauth,這次怎麼把 EAP 的使用者名稱寫在左邊了?
請注意,ipsec.conf 使用的是本機/他機的邏輯,本機預設在左; 而 ipsec.secrets 使用的是主機/對等點的邏輯,主機永遠在左。
ipsec.conf 裡面定義的是連線,左側的本機(對你來說,本機是你的筆記本,而對伺服器來說,本機是它自己,你才是它的「他機」,這個配置是在伺服器上的,不要混淆)用證書認證,右側是你的 win7 用 mschapv2 認證; 而 ipsec.secrets 裡定義的是認證,認證過程是你的 win7 用這個使用者名稱和後面定義的密碼去連線主機,認證是主機上發生的,所以要寫在左邊。
另外一部分人可能會混淆主機/對等點的含義,認為他們和 BT 是一樣的,你開啟了一個 strongswan 連線,於是你是主機,而其它人都是對等點,於是他們統一了本機/他機和主機/對等點這兩種截然不同的邏輯。前面已經說了我們的例子是以 VPS/客戶機這種典型案例為主,而你的客戶機是圖形介面自適配的,你沒有改過客戶機的配置檔案(所以官方維基上提供的例子你要看的是 moon 的配置),這種尷尬的統一的影響幾乎沒有。
而這種案例下,你不能理解主機/對等點的含義的後果是致命的:
你有一臺國外 VPS,一臺國內 VPS,想讓國內 VPS 也能科學上網。那你在國內 VPS 上就可能產生這樣的配置:
<國外 VPS 的 IP> <國內 VPS 的 IP> : RSA <國內 VPS 的私人證書名稱> <私人證書密碼>
國外 VPS:
<國外 VPS 的 IP> <國內 VPS 的 IP> : RSA <國外 VPS 的伺服器證書名稱> // 伺服器證書一般沒有密碼
這裡國外伺服器是主機,國內伺服器是對等點。主機永遠只有一臺,而且是在一開始便確定並固定不變的。如果你把國內 VPS 配置成:
<國內 VPS 的 IP> <國外 VPS 的 IP> : RSA <國內 VPS 的私人證書名稱> <私人證書密碼>
是無法連線的。因為主機始終是國外的 VPS。你可以想象為 BT 中心種子伺服器和你的計算機的關係。中心種子伺服器是固定不變的。
另外也間接證明了 ipsec 連線的代理是單向的,只能是主機為對等點做代理。就是說即使兩臺都是伺服器,它們的 ipsec 連線也不是雙向的,比如你國內伺服器可以科學上網,而國外伺服器可以看優酷,這是不可能在一個連線裡發生的。
strongswan.conf
# strongswan.conf - strongSwan configuration file charon { duplicheck.enable = no dns1 = 208.67.222.222 dns2 = 208.67.220.220 # for Windows only nbns1 = 208.67.222.222 nbns2 = 208.67.220.220 filelog { /var/log/strongswan.charon.log { time_format = %b %e %T default = 2 append = no flush_line = yes } } }
從 strongswan 5 起,無論是 ikev1 還是 ikev2 協議都使用 ikev2 的 daemon:charon 來實現。也就是說不必再在 /etc/strongswan.conf 裡配置 pluto 了。
duplicheck.enable = no 是為了你能同時連線多個裝置,所以要把冗餘檢查關閉。
dns 就不說了。nbns 是 Windows 的 NetBIOS 名稱伺服器實現, wins 服務會請求的。實際上 NBNS 協議是一個標準協議,但問題是 Linux 不強制而 Windows 強制請求,你不定義就無法連線。所以對於 ipsec VPN 來說,這個就是隻供 Windows 使用的。
下面的 filelog 定義了一個文字日誌。ipsec 協議的各種實現似乎都沒有顯式定義文字日誌(比如 racoon,strongswan 都沒有),而是寫入系統日誌 syslog。那樣不利於除錯,所以顯式定義一下。
- default 是預設日誌級別:-1,0,1,2,3,4。-1 是完全沒有日誌; 0 只告訴你連線建立、連線關閉; 1 只輸出錯誤提示; 2 會輸出錯誤、警告和除錯資訊; 3 會把連線傳輸的資料也列印; 4 則會把金鑰內容這些敏感資料也列印。一般情況下,1 或 2 都可以。
- append 是當你重啟 strongswan 後,是接上次日誌寫,還是新建一個日誌(上次的會被刪除)。因為 strongswan 的日誌太多了,所以用 no。
- flush_line 是每產生一行日誌,就寫入到磁碟一次。防止突然斷電,磁碟快取資料丟失。
另外你還可以詳細定義每個 strongswan 模組的日誌級別,但是沒什麼必要,具體可見 LoggerConfiguration。
啟動 Strongswan
sudo systemctl enable strongswan.service sudo systemctl start strongswan.service
注:如果是 openSUSE12.2 發行版,包中預設沒有strongswan.service,需要使用者到 /etc/init.d/ 目錄下啟動服務。
cd /etc/init.d/ sudo ipsec start
配置 Iptables 轉發
sudo iptables -A INPUT -p udp --dport 500 -j ACCEPT sudo iptables -A INPUT -p udp --dport 4500 -j ACCEPT sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE sudo iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT sudo echo 1 > /proc/sys/net/ipv4/ip_forward
為了每次 VPS 啟動不重新輸入這些命令,我們做成了一個 Systemd 服務 strongswan-iptables.service。下載扔到 /etc/systemd/system,然後:
systemctl enable strongswan-iptables.service systemctl start strongswan-iptables.service
即可執行上述命令。以後系統啟動時也將自動執行上述命令。
openSUSE 客戶端配置
strongswan 專案同時開發了 NetworkManager-strongswan,最新版本是 1.3。
安裝 NetworkManager-strongswan
sudo zypper in NetworkManager-strongswan
GNOME 要安裝 NetworkManager-strongswan-gnome
sudo zypper in NetworkManager-strongswan-gnome
KDE 要安裝 NetworkManager-strongswan-kde4
sudo zypper in NetworkManager-strongswan-kde4
如果你的 strongswan 是 5.0.0 以上的話,你還要安裝 strongswan-nm
sudo zypper in strongswan-nm
然後編輯 /etc/NetworkManager/VPN/nm-strongswan-service.name,替換
program=/usr/lib/ipsec/charon
為:
program=/usr/lib/ipsec/charon-nm
並重載 systemd 的全部系統服務
sudo systemctl --system daemon-reload
不然會出現 “vpn service 'strongswan' start timed out” 即 “signal of type SIGTERM received. Shutting down” 錯誤。因為 5 版的 strongswan 引入了一個 strongswan-nm 來避免與系統的 strongswan 衝突,而 openSUSE 的 NetworkManager-strongswan 的 systemd 服務有 bug(待修復),並不會去使用 strongswan-nm。
之後一定要重啟 NetworkManager.service 服務:
sudo systemctl restart NetworkManager.service
不然你設定好了會發現無法儲存私鑰(private key)的密碼,也不會彈出視窗,錯誤資訊為:
<error> [1370608229.893778] [nm-vpn-connection.c:1355] plugin_need_secrets_cb(): (f4f7fcdb-110b-4f80-8fc8-23934fc29a0c/strongswan) plugin NeedSecrets request #1 failed: dbus-glib-error-quark Rejected send message, 1 matched rules; type="method_call", sender=":1.3" (uid=0 pid=569 comm="/usr/sbin/NetworkManager --no-daemon ") interface="org.freedesktop.NetworkManager.VPN.Plugin" member="NeedSecrets" error name="(unset)" requested_reply="0" destination="org.freedesktop.NetworkManager.strongswan" (uid=0 pid=11246 comm="/usr/lib/ipsec/charon-nm ")
這是因為 NetworkManager 的 DBus 服務沒有過載,不能識別 strongswan 的緣故。
配置要點如下:
- 勾選系統連線,不然啟動不了 daemon
- 閘道器:你的伺服器 URL 或 IP,必須和證書裡面那個一樣(證書裡是 URL 這裡就不能是 IP)
- 證書:你的 CA 證書
- 認證方式:證書/私鑰
- 證書:你的客戶證書
- 私鑰:客戶證書對應的私鑰
- 私鑰密碼:生成客戶證書時讓你輸入的那個密碼,沒有就選不需要,否則選儲存或總是詢問
- 勾選請求內部 IP 地址,不然你沒有虛擬地址,tun 裝置自然也沒法為你中轉流量
- 勾選強制 UDP 封裝,這是因為 strongswan 5 以後即使 ikev1 也是通過 ikev2 的 charon 後端通訊的。而 charon 有一個新的特性叫 MOBIKE,也就是手機端上的自動重連(只適用於使用證書的情況),這個特性是預設開啟的。而開啟了這個特性所有的流量都會走 4500 埠也就是 UDP。你不勾根本連不上。
其它客戶端配置
其它 Linux
Chakra Linux
方法和openSUSE的大同小異,不過關鍵問題在於Chakra預設所有源中是沒有Strongswan,這個時候各位可以藉助CCR來實現安裝,CCR中有三個包,分別是strongswan, networkmanager-strongswan, networkmanager-dispatcher-strongswan-systemd(目前三者由我自己維護,從AUR照抄,修改了其中一個依賴而已)。其中,第一個是主要的,第二個大家都知道,第三個是systemd服務。推薦客戶端使用者只需要安裝前兩個。(我的源中預設啟用了所有的源,包括core, platform, desktop, apps, games, lib32, extra以及測試源和不穩定源,個人認為主要要啟動extra源,因為需要到一些gtk庫)
- 編譯安裝兩個主要包
ccr -S strongswan && ccr -S networkmanager-strongswan
(各位可以去喝喝茶,聽聽歌)
- 下載strongswan原始碼編譯安裝strongswan-nm,下載地址,下載到一個你知道的地方,我放到/home/source/目錄下,解壓後,開始編譯strongswan-nm外掛
# build charon with OpenSSL/NM Plugin ./configure --sysconfdir=/etc --prefix=/usr --libexecdir=/usr/lib \ --disable-aes --disable-des --disable-md5 --disable-sha1 --disable-sha2 \ --disable-fips-prf --disable-gmp --enable-openssl --enable-nm --enable-agent \ --enable-eap-gtc --enable-eap-md5 --enable-eap-mschapv2 make make install
完成安裝後,注意/usr/lib/ipsec/目錄下多出了一個charon-nm,這個就是我麼需要的東西。下面的設定基本遵循瑪麗蘇的方式。
- 編輯/etc/NetworkManager/VPN/nm-strongswan-service.name,替換
program=/usr/lib/strongswan/charon
為:
program=/usr/lib/ipsec/charon-nm
- 後面的步驟依照openSUSE中“並重載 systemd 的全部系統服務”
- NetworkManager 的配置要點同 openSUSE
- 補充:這個時候你的客戶端應該能夠連線了,如果不能,首先看看防火牆策略,如果還是不行,你可以試試先隨便連線一個 VPN ,然後斷開再連自己的 strongswan
其他 Linux 發行版參考 openSUSE 配置。
iOS
把 CA 證書和之前做好的 pkcs12(.p12)發郵件給自己。在 iOS 上收郵件,匯入兩者。然後新建 IPSec VPN:
- 伺服器,和 openSUSE 的要求一樣,都是 IP 或都是 URL
- 賬戶和密碼寫 ipsec.secrets 裡 XAUTH 前後的那兩個
- 如果要使用證書,證書選剛才的那個。否則可以不使用證書,輸入 ipsec.secrets 裡設定的 PSK 密碼。
Android
IPSec Xauth PSK
我的 Jelly Bean 是有這個的,設定 VPN 之前 JB 要求你必須設定鎖屏密碼或者 PIN 碼。
主要還是:
- 伺服器,同上
- IPSec 預共享金鑰:寫 ipsec.secrets 裡 PSK 後面的那個密碼。
然後登入時還是用 XAUTH 前後的那兩個做使用者名稱密碼。
"strongSwan VPN Client" for Android 4.0 (ICS)+
這是官方自己出的客戶端,Google Play 裡就有。
把之前做好的 pkcs12 發郵件給自己。實際上 pkcs12 裡就包含了 CA 證書,iOS 是有 bug 才必須明確要求匯入 CA 證書(鄙視之)。Android 不用。直接在 GMail 裡點選就會提示你匯入。
然後開啟官方客戶端,新建方案:
- Gateway 就是伺服器,同上
- Type 選 IKEv2 Certificate
- User certificate 選你剛才匯入的
- 取消自動選擇 CA 證書,然後在使用者證書裡選你剛才從 pk12 匯入的
Windows XP/Vista
注意 XP/Vista 本身不支援純 IPsec 連線。如果使用 L2TP/IPsec 模式,使用證書會 fallback 到 iOS_cert 這個連線型別,使用預共享密碼會 fallback 到 android-xauth-psk 這個連線型別。使用 Shrew Soft VPN Client
安裝後開啟,選「Add」:
- 「General」選項卡下,把「Host Name or IP address」添好
-
「Authorization」選項卡下:
- 「Authorization Method」選「Mutual PSK + XAuth」
- 「Local Identity」的「Identification Type」選「IP Address」
- 「Credentials」下面「Pre Shared Key」裡輸入 PSK 密碼
- 「Phrase 1」,「Exchange Type」選「Main」
- 「Phrase 2」,「PFS Exchange」選「auto」
儲存。連線時使用者名稱密碼是你的 XAUTH 使用者名稱密碼。
伺服器端對應的配置是 android-xauth-psk 的連線型別。
Windows 7+
使用 Shrew Soft VPN Client 客戶端:和上面 XP 的一樣。
使用自帶客戶端(Agile):
匯入證書:
- 開始選單搜尋「cmd」,開啟後輸入 mmc(Microsoft 管理控制檯)。
- 「檔案」-「新增/刪除管理單元」,新增「證書」單元
- 證書單元的彈出視窗中一定要選「計算機賬戶」,之後選「本地計算機」,確定。
- 在左邊的「控制檯根節點」下選擇「證書」-「個人」,然後選右邊的「更多操作」-「所有任務」-「匯入」開啟證書匯入視窗。
- 選擇剛才生成的 client.cert.p12 檔案。下一步輸入私鑰密碼。下一步「證書儲存」選「個人」。
- 匯入成功後,把匯入的 CA 證書剪下到「受信任的根證書頒發機構」的證書資料夾裡面。
- 開啟剩下的那個私人證書,看一下有沒有顯示「您有一個與該證書對應的私鑰」,以及「證書路徑」下面是不是顯示「該證書沒有問題」。
- 然後關閉 mmc,提示「將控制檯設定存入控制檯1嗎」,選「否」即可。
至此,證書匯入完成。
注意 千萬不要雙擊 .p12 證書匯入!因為那樣會匯入到當前使用者而不是本機計算機中,ipsec 守護精靈是訪問不了它的。建立連線:
- 「控制面板」-「網路和共享中心」-「設定新的連線或網路」-「連線到工作