KUSONEKOの見る世界

IPsec VPN 高セキュリティ&爆速? AES-GCM + ECP に変更した

 strongSwan 5.9.0が公開されていますが、更新内容にESPのアルゴリズムAES-GCMの優先度を上げたという記載がありました。

今までAES-CBCとそんなに変わらないだろうと無視してきましたが、調べてみるとパフォーマンスが高いことが分かり、Windowsでも使用する方法があること、更に鍵交換方式にECPを使用することで、ECDSA証明書を使えることが判明し、(私の狭い)世界が一気に広がりました。

 これはもうAES-GCMとECPを使用するしかないと思い、色々と調べ変更しました。
この記事では調べた結果と設定方法をまとめます。

アルゴリズムの話

AES-GCM

冒頭に書きましたが、AES-GCMはパフォーマンスが高いことが報告されています。
AES-CBCと違い、AES-GCMは効率的な認証メカニズムも備えているためのようです。

IntelのCPUでは、AES-GCMのパフォーマンスが大幅改善され、AES-CBC + SHAより高い性能になっているのだそうです。

手元のCPUでもパフォーマンスを計ってみました。
以下のコマンドで測定しています。(AES-NIを使用)

openssl speed -evp aes-256-cbc
openssl speed -evp aes-256-gcm
Intel Celeron N3150 (OpenSSL 1.1.1c)

64 bytes 1024 bytes 8192 bytes
aes-256-cbc 195314.41k 251602.60k 256631.52k
aes-256-gcm 168791.84k 259244.84k 266009.86k

Intel Core i7 3930K C2 (OpenSSL 1.1.1g)

64 bytes 1024 bytes 8192 bytes
aes-256-cbc 481273.85k 534473.92k 538753.46k
aes-256-gcm 598871.42k 1230228.41k 1289487.69k

Intel Core i5-7200U (OpenSSL 1.1.1g)

64 bytes 1024 bytes 8192 bytes
aes-256-cbc 560429.08k 714512.04k 755561.81k
aes-256-gcm 670229.12k 2428955.31k 2790327.31k

AMD Ryzen 3 2200G (OpenSSL 1.1.1g)

64 bytes 1024 bytes 8192 bytes
aes-256-cbc 769812.52k 896551.59k 904260.27k
aes-256-gcm 672425.05k 2671248.04k 3500255.91k

Intel Core i5-11600KF (OpenSSL 1.1.1g)

64 bytes 1024 bytes 8192 bytes
aes-256-cbc 1670651.31k 1697916.54k 1707470.19k
aes-256-gcm 1771954.35k 6084933.73k 7509207.72k

新しいCPUほどCBCよりGCMに変更した方が効果が高いようです。
VPNサーバで使っているN3150の効果が微増だったのは少し残念です。

更にオーバーヘッドが小さくなるメリットもありました。
これによりVPNインターフェースのMTU/MSSを大きくできます。


ESP IV ESP Padding ESP Authentication
AES-CBC + SHA256 16byte 0~15byte 16byte
AES-GCM with a 16 octet ICV 8byte 0~3byte 16byte

こちらの内容は計算機の方にも反映をしました。
>>IPsec 備忘録

ECP 

ECPは、Diffie-Hellmanグループのひとつで、IPsecの鍵共有で使用します。
よく使われるMODPよりビット数が少なく、計算的にも効率的で安全のようです。

Windowsでは、ECPを選択することで、マシン証明書認証でECDSA証明書を使用することができます。
ECDSA証明書もRSA証明書よりビット数が少なく計算が効率的だそうです。

設定方法

ECDSA証明書の作成

CA、サーバ、クライアントの証明書は、ECP384を使用するため、ECDSA証明書を鍵長384bitで作成します。

かなり前のログから書き起こしましたので、今ではできない可能性がありますがご了承ください。

CA証明書はsha384を使用しているのに、サーバとクライアント証明書はデフォルトのsha256になっています。詰めが甘かったですが、これでも使用できています。

CA証明書

openssl ecparam -out ca-private.key -name secp384r1 -genkey
openssl req -config openssl.cnf -new -x509 -key ca-private.key -sha384 -days 3650 -out ca.pem

サーバ証明書

CNの入力が求められたら、subjectAltNameと同じ物、この例では『vpn.example.com』を入力してください。

openssl.cnfを以下に編集
subjectAltName = DNS:vpn.example.com
extendedKeyUsage = serverAuth, 1.3.6.1.5.5.8.2.2

openssl ecparam -out server-private.key -name secp384r1 -genkey
openssl req -config openssl.cnf -new -key server-private.key -outform PEM -keyform PEM -out server-req.pem
openssl ca -config openssl.cnf -in server-req.pem -keyfile ca-private.key -cert ca.pem  -extensions usr_cert -out server.pem

クライアント証明書

必要数分作成。

CNの入力が求められたら、subjectAltNameと同じ物、この例では『username@vpn.example.com』を入力してください。

openssl.cnfを以下に編集
subjectAltName = DNS:username@vpn.example.com
extendedKeyUsage = clientAuth

openssl ecparam -out client-private.key -name secp384r1 -genkey
openssl req -config openssl.cnf -new -key client-private.key -outform PEM -keyform PEM -out client-req.pem
openssl ca -config openssl.cnf -in client-req.pem -keyfile ca-private.key -cert ca.pem  -extensions usr_cert -out client.pem
openssl pkcs12 -export -in client.pem -inkey client-private.key -certfile ca.pem -out username@vpn.example.com.p12

strongSwan

CA、サーバ証明書とサーバ証明書のプライベートキーは所定のディレクトリに配置します。
ipsec.secretの指定も忘れずに。

ipsec.conf の ike と esp にAES-GCMとECPのアルゴリズムを指定します。
カンマ後の二つ目のアルゴリズムは既存のクライアント用に残しておきました。

conn %default
     left=%defaultroute
     leftcert=server.pem
     leftsubnet=0.0.0.0/0
     right=%any
     rightsourceip=192.168.255.0/24
     keyexchange=ikev2
     auto=add
     ike=aes256gcm16-sha384-ecp384,aes256-sha256-modp2048!
     esp=aes256gcm16,aes256-sha1!
     dpdaction=clear
     dpddelay=300s
     rekey=no

conn win10-ecdsa
     rightid="C=JP, ST=Tokyo, O=example.com, CN=username@vpn.example.com"

conn ios-ecdsa
     leftid=vpn.example.com
     leftsubnet=192.168.0.0/24
     leftsendcert=always
     rightid="username2"

conn win7-rsa
     leftcert=server_rsa.pem
     rightid="C=JP, ST=Tokyo, O=example.com, CN=username3@vpn.example.com"

conn ios-rsa
     leftcert=server_rsa.pem
     leftsubnet=192.168.0.0/24
     leftsendcert=always
     rightid="username4"

Windows

p12ファイルをローカルコンピューターにインストールしてください。
CA証明書は、信頼されたルート証明機関に入れること。

アルゴリズムは、PowerShellで指定ができます。
ここでは、Add-VpnConnection でVPNという名前のIKEv2接続を作成し、Set-VpnConnectionIPsecConfiguration でアルゴリズムを変更します。

もし、レジストリにNegotiateDH2048_AES256を追加している場合は、値を0にするか削除してください。レジストリの方が優先されてしまいます。

Add-VpnConnection `
 -Name "VPN" `
 -ServerAddress "vpn.example.com" `
 -TunnelType "IKEv2" `
 -EncryptionLevel "Required" `
 -AuthenticationMethod "MachineCertificate" `
 -SplitTunneling -AllUserConnection `
 -Force `
 -RememberCredential `
 -PassThru `
 -DnsSuffix "example.com"

Set-VpnConnectionIPsecConfiguration `
 -Name "VPN" `
 -CipherTransformConstants GCMAES256 `
 -EncryptionMethod GCMAES256 `
 -IntegrityCheckMethod SHA384 `
 -DHGroup ECP384 `
 -AuthenticationTransformConstants GCMAES256 `
 -PfsGroup None `
 -Force

iPhone (macOS)

構成プロファイルを作成します。p12ファイルをbase64で記載します。

こちらの記事のプロファイルから以下の部分を変更します。
>>iPhoneで strongSwan (IPsec VPN) に接続する (Machine Certificates)

<key>IKESecurityAssociationParameters</key>
<dict>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-384</string>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
</dict>
<key>ChildSecurityAssociationParameters</key>
<dict>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-256</string>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
</dict>

追記

iPerf3を使用し、実際の通信速度を測ってみました。
>>IPsec VPN AES-CBC/GCM/ChaCha20 の実効速度を測定してみた