以下のような記事を書いたものの、現在は、raspberry pi 4 で openvpn サーバを構築 に書いた構成に落ち着いている。ただし、スマートフォンからはアクセスしておらず、専ら PC からのアクセスである。

概要

a) 社外から社内(もしくは学外から学内)のネットワークに接続したり、b) インターネット上の特定のサーバから接続したように見せかけるのに VPN が利用される。

私の場合、リモートでメンテナンスや開発をすることが多い。セキュリティの関係で、接続が特定の IP アドレスからしか許可されていない場合がほとんどだ。

ssh でポートフォワードしてもよいのだが、毎度、ssh 接続をしたり、ssh が切れた場合につなぎなおしたりするのも面倒になってきた。また、開発中の WEB サイトが特定の IP アドレスからしか接続を許可されていない場合に、スマートフォンで確認するためには、ある程度の範囲の IP アドレスから接続を許可してやらないといけない。開発中なので、バグがあるだろうし、ちょっと恐い。テスト中のサイトが見える可能性があるというのもどうかと思う。

サーバ、クライアント双方でインストールが最小となる組み合わせを模索したところ、サーバに Linux + strongswan を使い、IKEv2 + 証明書で設定するのが最も簡単かつ安全で、色々な端末からの接続が可能になる組み合わせではないかと思う。

android に限り、strongSwan VPN Client をインストールする必要があるが、mac(High Sierra)で/windows(Windows 10) からは、他にインストールするものも不要で、システム環境設定のメニューから VPN 接続を追加するだけでよかった。

VPN とは

VPN とは、バーチャルプライベートネットワーク(Virtual Private Network)の略である。物理的には存在しないがあたかも存在しているかのように見える(Virtual)、非公式(Private)なネットワークということだろうか。

ネットワーク上(例えばイーサネット接続や WiFi接続)など既存のネットワーク接続の上に構築される。外から見えないので、現実世界との類似性からトンネルと呼ばれたりする。

VPN の種類

OS のメニューから選べる VPN の種類としては、以下のようなものがある。

  • PPTP
  • L2TP/IPSEC
  • SSTP (Secure Socket Tunneling Protocol)
  • IKEv2

この他にアプリ(ネットワークドライバを含む)をインストールすれば OpenVPN などの SSL VPN を利用することができる。

違いについては、

などがわかりやすい。IPSEC とは、IP security の略で、IP レベルでセキュリティを確保するためのプロトコルである。RFC6071として公開されている。

サーバ(Linux)、クライアント(Windows / Mac / iPhone / Android)への設定・インストールを最小にしたいと考えたのであるが、この条件に合うのは、IKEv2 による VPN 接続であった。ただし、Android にはアプリのインストールが必要。

Windows/MacOS/Android で共通に使えるものは、L2TP/IPSEC は、サーバに L2TP サーバと IPSEC の鍵交換サーバを、OPENVPN はクライアントPC/スマートフォンに SSL VPN 対応のソフトをインストールする必要がある。

そのため、IKEv2 が最善と考えた。

L2TP/IPSEC vs IKEv2

L2TP/IPSECは、L2TP にはセキュリティが、IPSEC には認証が欠けているためそれらを組み合わせて使う。L2TP と IPSEC の両プロトコルに対してファイアウォール設定をする必要があり、かなり設定の難易度が高い。

IKEv2(+IPSEC) では認証、NAT などが追加されており、IKEv2 で使う UDP 500 番、4500 番のポートに対してのみファイアウォール設定すればよい。

SSL VPN vs IKEv2

SSL VPN である OPENVPN と比較すると、OPENVPN は強力なセキュリティと、何か一つ TCP が通ればトンネリングできるのがすばらしい(IKEv2は UDP 500 番ポートが必要)が、ネットワークドライバをインストールする必要があるのでやっかいだ。OS のバージョンアップに対応できるかどうかを考える必要がある。

一方で、IKEv2 は、IPSEC なので、最近のOSであれば、カーネルレベルでIPSECをサポートしているであろう。ネットワークドライバを入れなくていいのがすばらしいと思う。(私の理解では、IKEv2 デーモンが、IPSEC 設定を行う。)

IKEv2 による VPN 環境構築の方法を以降に書いておく。

VPN サーバの環境

さくらインターネット VPS+CENTOS7。さくらインターネットの場合は、インタフェースにグローバルIPアドレスが直接割り当てられている。AWS はプライベート IP アドレスが割り振られている。(NAT?)面倒を避けるため、さくらインターネットの VPS を使用。

os インストール後、strongswan をインストールする。


(# yum install epel-release)
# yum install strongswan

設定ファイル

サーバ側

/etc/strongswan/ipsec.conf

conn ikev2
        keyexchange=ikev2
        ike=aes256-sha256-modp2048,aes256-sha256-modp1024,aes128-sha256-modp3072,aes256-sha1-modp1024!

        dpdaction=clear
        dpddelay=300s
        rekey=no

        left=%any
        leftsubnet=0.0.0.0/0
        leftauth=pubkey
        leftcert=cert_server.der
        leftsendcert=always
        leftid=@vpn.runserver.jp
        right=%any
        rightsourceip=10.101.1.0/24
        #rightauth=eap-mschapv2 # ユーザー名、パスワードを使う場合
        rightauth=eap-tls # 証明書を使う場合
        rightdns=8.8.8.8
        eap_identity=%any
        auto=add

(leftid のところは適当に自分のサイト用のものを設定。)

以下のファイルを作る。

  • /etc/strongswan/ipsec.d/cacerts/ca_cert.der
  • /etc/strongswan/ipsec.d/certs/cert_server.der
  • /etc/strongswan/ipsec.d/private/key_server.der

作り方は、Setting-up a Simple CA Using the strongSwan PKI Toolを参考に。ipsec コマンドは strongswan コマンドに読みかえる。

ca_cert.der (dn の引数は自分の好みのものに)

$ strongswan pki --gen > ca_key.der
$ strongswan pki --self --in ca_key.der --dn "C=JP, O=runserver, CN=runserver private ca" --ca --flag sererAuth > ca_cert.der

(–flag serverAuth が必要かどうか未検証)

cert_server.der (CN=の後ろは VPN サーバの DNS 名を入れておく)

$ strongswan pki --gen > key_server.der
$ strongswan pki --pub --in key_server.der | strongswan pki --issue --cacert ca_cert.der --cakey ca_key.der --dn "C=JP, O=runserver, CN=vpn.runserver.jp" --flag serverAuth --san vpn.runserver.jp > cert_server.der 

(–san が必要かどうか未検証)

/etc/strongswan/ipsec.secrets

: RSA key_server.der
moriya : EAP "hogehoge"

2行目は、ユーザー名、パスワードを使用する場合、接続時に指定するユーザー名、パスワード。(証明書を使う場合は不要)

サーバ起動

/etc/sysctl.d/00-ipsec.conf

net.ipv4.ip_forward=1

(再起動、もしくは、systemctl restart systemd-sysctl)

以下を実行。

# firewall-cmd --permanent --zone=public --add-service=ipsec
# firewall-cmd --permanent --zone=public --add-port=4500/udp
# firewall-cmd --permanent --add-masquerade
# systemctl enable strongswan
# systemctl start strongswan

クライアント側

ca_cert.der もインストール。Mac の場合は、キーチェーンアクセスで証明書を信頼(情報を見る->信頼->常に信頼する)しないと接続できなかった。

クライアント側の証明書も同様にして作り、p12 ファイルにしてクライアントにインストールする。

$ strongswan pki --gen > key_client1.der
$ strongswan pki --pub --in key_client1.der | strongswan pki --issue --cacert ca_cert.der --cakey ca_key.der --dn "C=JP, O=runserver, CN=moriya@vpn.runserver.jp" --san moriya@vpn.runserver.jp > cert_client1.der

$ openssl x509 -inform der -outform pem -in ca_cert.der -out ca_cert.pem
$ openssl x509 -inform der -outform pem -in cert_client1.der -out cert_client1.pem
$ openssl rsa -inform der -outform pem -in key_client1.der -out key_client1.pem
$ openssl pkcs12 -export -inkey key_client1.pem -in cert_client1.pem -certfile ca_cert.pem -out client1.p12

(–san が必要かどうか未検証)

Windows の場合は、
IKEv2
ユーザー名とパスワード
ユーザー名
パスワード
を設定した後、「アダプタのオプションを変更する」で、WAN MINI Port(IKEv2) アダプタのプロパティの
ネットワークタブ / インターネットプロトコルバージョン4 プロパティ
全般タブ / 詳細設定
IP 設定タブにある、「リモートネットワークでデフォルトゲートウェイを使う」
をチェックして OK。

Mac の場合は、IKEv2 の設定画面で、上記設定だと、以下のように設定する。

サーバアドレス:vpn.runserver.jp
リモートID:vpn.runserver.jp
ローカルID:moriya@vpn.runserver.jp

トラブルシュート

  1. Windows のイベントビューワで見て 13801 番のエラーコードで失敗する場合は、Troubleshooting IKEv2 VPN Connectionsなどが参考になった。
  2. 「no trusted rsa public key found」のエラーがログに表示されている場合は、自己署名した ca certificate をインストールしたか確認。

aws を使う場合

  • アクション > ネットワーク > 送信元/送信先の送信チェックを選択し無効にすること。
  • セキュリティグループのインバウンドの設定で、UDP 500、UDP 4500、プロトコル 50、プロトコル 51 を許可すること。

感想

  • インストールの手間が少ない。
  • 接続が早い。
  • OS の機能から呼び出せて気持ちよい。
  • ファイアウォールの設定がシンプル。

参考サイト

strongSwan のサイト

少し見づらいが、役にたった。


[PR] こちらの PC、ラズパイにインストールしてみてはどうでしょうか?