1. 程式人生 > >使用 Strongswan 架設 Ipsec VPN

使用 Strongswan 架設 Ipsec VPN

本教學介紹瞭如何使用 Strongswan 5.0.x 在 openSUSE 12.3+ 伺服器上架設支援 ikev1/ikev2 的 Ipsec VPN。適用於 openSUSE、iOS、Android、Windows 和其它 Linux。 注意 Strongswan 5 即現在的主力支援版本和 Strongswan 4 的 ipsec.conf 有很大的不同(作廢了很多選項),請保證您的版本為 5.0.4+ 本教學才有參考價值。因此請不要往 Debian 這些軟體包版本舊的系統上套,同樣 openSUSE 使用者也不要拿 Debian 的來套。 注意 本文的例子僅以最常見的 VPS/客戶機模式為例,假設客戶機使用圖形客戶端,因此並不涉及客戶端文字配置的內容。其中的原理和伺服器端配置可用於其它用途比如伺服器到伺服器(Site to Site)的連線,但這種連線的客戶端文字配置部分需要領會原理自己寫。 注意 本文只適用於有 VPS 的愛好者使用,並不提供已建立好的 demo 供測試,但保證文中出現的配置如無意外如上游改選項,實際中都是能夠使用的。因此並不可用於「免費 VPN」這樣的話題,如何優惠購買 VPS 請到我們的論壇 
forum.suse.org.cn
。本文也不討論如何進行後臺計費,但提供了計費軟體的名稱供 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 守護精靈是訪問不了它的。

建立連線:

  • 「控制面板」-「網路和共享中心」-「設定新的連線或網路」-「連線到工作