SDB:Setup Ipsec VPN with Strongswan

By hack520 on
本教學介紹了如何使用 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 的更新卻對這種方式進行了封殺,學習微軟加入了證書驗證,小證書直接拒絕。

所幸 strongswan 5.0.2 已經完成了 fragmentation 的開套件庫實現和對 iOS 那個聲明加密其實未加密故障的處理:IKE message fragmentation (cisco) + IOS 6.0 Hack for encrypted flaged ike fragmentation packets,該鏈接中也能找到 strongswan 4 的補丁。

Windows

微軟的差勁只比 iOS 好一點。好處在於它支援了 ikev2,但是只在 Windows 7 以後支援,Vista 之前依然使用 ikev1。

壞處在於它的 ikev2 支援非常詭異,指定了 Diffie Hellman group(DH,迪菲-赫爾曼密鑰交換組)必須是 modp1024。這是非常少見理論上不應該由系統管理員操心的加密選項:

在 strongswan 中,定義第一階段(ike)和第二階段(esp)加密方法的語法是:

 ike/esp=encryption-integrity[-dhgroup][-esnmode]
 第一阶段/第二阶段=加密方法-健壮性认证方法 (后面两项可选)[-DH 组] [-扩展序列号支持模式(RFC4304)]

參考:IKEv2CipherSuites

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,理論上如果連接持續時間足夠長,依然能夠撞車:58×60+46 次 rekey 後即 146 天后撞車,連一年都沒有,在 Linux 伺服器對 Windows 伺服器這種使用實例中就明顯不符合要求。

所以目前只能使用後一種方法即完全禁用伺服器端 rekey。

最後,它的 EAP 認證也非常糟糕。MSCHAPv2 的 eap 身份不是 ikev2 身份(ikev2 身份一般是 EAP 用戶名),所以必須在伺服器端顯式定義 eap_identity 來使用 Windows 7 的 eap 身份。

安裝 Srongswan

sudo zypper ar -f http://download.opensuse.org/repositories/network:/vpn/openSUSE_12.3/ network:vpn
sudo zypper ref
sudo zypper in --no-recommends strongswan-ipsec

這裡 –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 為通用名。

具體見微軟的文件:Distinguished Names

生成伺服器證書

同樣生成私鑰:

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

下載:https://www.shrew.net/download/vpn

安裝後打開,選「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 守護精靈是訪問不了它的。

建立連接:

  • 「控制面板」-「網路和共享中心」-「設置新的連接或網路」-「連接到工作區」-「使用我的 Internet 連接」
  • Internet 地址寫伺服器地址,注意事項同 openSUSE 的,都是 IP 或都是 URL。
  • 描述隨便寫。
  • 用戶名密碼寫之前配置的 EAP 的那個。
  • 確定
  • 點擊右下角網路圖標,在新建的 VPN 連接上右鍵屬性然後切換到「安全」選項卡。
  • VPN 類型選 IKEv2
  • 數據加密是「需要加密」
  • 身份認證這裡需要說一下,如果想要使用 EAP-MSCHAPV2 的話就選擇「使用可擴展的身份認證協議」-「Microsoft 安全密碼」,想要使用私人證書認證的話就選擇「使用計算機證書」。

調試

如果沒有特殊需要,伺服器端的日誌就足夠檢測出絕大多數問題的來套件庫。

我唯一需要在客戶端上偵錯的那次是 iOS 客戶端。

日誌閱讀技巧

strongswan 的 charon daemon 啟動後,會初始化並載入之前你定義好的 conn,這部分 log 是沒有必要去讀的。當然在你配置有問題時可能就有必要了,但當配置有問題的時候,systemctl start strongswan.service 會失敗,systemctl status strongswan.service 就會指出你配置問題所在的行號(=。=)…

所以你只要去查找「added configuration “windows7″」,這裡 windows7 是你配置的最後一個 conn 的名稱,然後從那裡往下看就好了。

另外連接失敗是會把連接狀態從 CONNECTING 變為 DELETEING 的,DELETEING 又會刷一大堆日誌,但那些日誌都是沒用的。

伺服器端調試

/var/log/strongswan-charon.log 文件

Linux 調試

參照 strongswan 配置教學改 /etc/strongswan.conf,之後同伺服器端調試。

iOS 調試

越獄安裝 iFile。編輯 /etc/racoon/racoon.conf 文件,找到 #log debug; 欄位,改成:

log debug;
path logfile "/var/log/racoon.log";

保存。

Android 調試

  • strongSwan 官方客戶端提供了日誌查看功能。
  • android 自帶的 VPN 調試方法如下:

打開「終端模擬器」,輸入 su,會彈出超級用戶,允許。

cd /storage/sdcard0
logcat -f ./log.txt

然後用 Airdroid 等工具把 SD 卡中的 log.txt 傳到電腦上,打開搜索 VPN 即可。

Windows 調試

微軟 technet:VPN Troubleshooting Tools

擴展閱讀

計費軟體

  • FreeRadius:賬戶認證和計費
  • daloRadius:用戶賬單管理

參考:使用 StrongSwan 搭建 IKEv1 IKEv2 VPN伺服器|莓玩沒了。註:該文的 strongswan 配置僅供參考(有很多冗餘配置)。

  • MySQL:賬戶管理後台資料庫

參考:SDB:搭建LAMP伺服器

參考文獻

配置選項:

設備/作業系統特殊要求:


作者:hack520

文章链接:SDB:Setup Ipsec VPN with Strongswan

短连接:https://zhu.vn/?p=473

One comment

  1. Pingback: Õæ·âÉñ¿ª·þÒ»ÌõÁúÖÆ×÷47ev.comQQ49333685

发表评论