🎄

VPNのいろいろ

2021/12/08に公開

前書き

あなたがこの記事を読んでいるということは、私がなんとか記事をかきあげたということでしょう。
ということでACCESS Advent Calenderの9日目は@ten_takanoです。

最近業務の都合でVPNをプログラム側から触ることになって調査をしたのですが、時間をかけた割に結構とっちらかっている&思ったほど何もできないということがあったので、まとめることにしました。

そもそもVPNってなに?

この記事をご覧の方ならそれぐらい知っている!という方がほとんだとは思いますが、念の為まとめておきます。
VPN(Vertial Private Network)とはその名前の通り、仮想的にPrivate Networkを作るための技術やそれを実現するプロトコルスタックのことを指します。おそらくこんなケースで利用することがほとんどなのではないでしょうか。

  • 外部に非公開なサーバーにプライベートネットワーク外からアクセスしたいとき
  • 特定のIPアドレスからしかアクセスを許可していないサーバーにアクセスしたいとき
  • フリーWi-Fiなどを利用しているがセキュリティが気になるとき(これが有効かどうかはさておき)

ちなみに私は1年のほとんどをリモートで仕事をしているので(お家サイコー!)、上記2つの目的のために日常的にVPNを利用しています。

VPNで接続されたネットワーク同士またはネットワークと端末は、あたかも同じPrivate Networkに接続されているかのように振る舞います。
普通のPrivate Networkに接続された端末を使用する場合を考えてみましょう。その端末では、Private Networkアドレスを使用して同じネットワークに接続されている別の端末を参照することができます。もしPrivate Network内にサーバーが立てられていたら、Private Networkアドレスを使用してそのサーバーへアクセスすることができます。端末から外部のサーバーへアクセスしようとしたら、NAT変換によって、そのPrivate Networkのゲートウェイを介してIPアドレスが変換されて目的のサーバーにアクセスされます。
では逆にインターネットから見た場合はどうでしょうか?Private Network内にあるサーバーには、ポートフォワーディングされていなければ直接アクセスすることはできません。Private Networkの構成がどのようになっているのかも知ることができません。また、言うまでもなく内部でどのような通信が行われているかも見ることはできません。
これらの特性を、物理的には同じPrivate Networkではないにもかかわらず、論理的に同じPrivate Networkとしてしまう機能を提供するのがVPNなのです。

これを実現するため、VPNは物理的にインターネットを情報が流れる際に、通信内容を暗号化・復号を行います。これにより第三者が通信内容を盗み見ようとしても復号ができないため、仮想的なPrivate Networkが実現されます。なので、

  • 外部に非公開なサーバーでもVPNを接続すれば同じネットワーク内なのでアクセスすることができます
  • アクセス制限がかけられているサーバーにも、接続元をVPNサーバーのあるネットワークのゲートウェイを通すことで制限を回避することができます
  • フリーWi-Fiを利用している際に、VPNで通信を暗号化するため、通信を秘匿することが期待できます(設定による)

VPNの利用のされ方

VPNには、ネットワーク同士を接続する「拠点間VPN」と呼ばれるものと、端末そのものをVPNサーバーに接続させる「リモートアクセスVPN」があります。
拠点間VPNはその名前の通り、遠く離れたオフィスなどのネットワーク同士を接続させるVPNです。拠点間VPNではネットワーク同士が接続されるので、各端末の利用者が利用時に何かを意識することはありません。どの端末がどちらのネットワークに接続されているかなども全く感知する必要はなく、あたかも同じ建物内に存在しているかのように利用することができます。利用者がすべきことはネットワーク管理者への感謝だけです。
これに対し、リモートアクセスVPNは利用する端末そのものをVPNサーバーへ接続するため、利用者が明示的に設定・操作を行う必要が有ります。

前置きがかなり長くなってしまいましたが、この先が本題です。この記事ではリモートアクセスVPNを利用する際に必要な知識を掘り下げていきます。

VPNのプロトコル

VPNはトンネリングとカプセル化(暗号化)により実現されます。トンネリングとは2つの点を仮想的に直接接続する回線を確立することです。トンネリングによってオープンなネットワーク上に、外部から中を覗き見ることができない通り道を作ることができます。しかし、トンネリングだけでは、トンネル内部に侵入されてしまった場合、通信内容を盗聴されてしまう恐れが有ります。そこで、VPNはトンネル内を流すパケットをカプセル化(暗号化)します。これにより、万一トンネル内部に侵入されたとしてもパケットの中身を覗き見ることはできなくなります。

様々なVPNのプロトコルはこのトンネリングかカプセル化、またはその両方を行うように作られています。よく目にする(VPNの設定時に選択肢に現れる)プロトコルには以下のようなものがあります。

  • PPTP
  • L2TP/IPsec
  • IPsec Xauth PSK
  • IPsec Xauth RSA
  • IKEv2

PPTP

設定が簡単で速度が速いことが特徴。しかし、現在用いられている中で最もセキュリティが低く、脆弱性を抱えているため安全性にかけている。

L2TP/IPsec

L2TPはトンネリングを行うプロトコルです。しかし、L2TPのみではカプセル化を行うことができません。IPSecもまたトンネリングを行うプロトコルです。ただし、IPsecはトンネリングだけでなくカプセル化も行うことができます。しかし、IPsecはマルチキャストを行うことができません。このようなそれぞれの足りない部分を補い合わせるため、IPsecと別のトンネリングプロトコルを組み合わせて使うということが行われます。(名前としてIPsecがない場合でも使われている場合が有ります)
セキュリティが高いためよく使われていましたが、動作が重いため少しずつ使われなくなっていくと思います。

IPsec Xauth PSK/RSA

拠点間VPNの場合、接続する機器同士がそれぞれラックなどに設置された機器である場合にはここまでで説明した内容で十分ですが、リモートアクセスVPNの場合にはPCの紛失などによりVPNを不正に使用されてしまう危険性があります。そのため、機器の認証に加えて、ユーザーが正当であるかを認証するために、Xauthというプロトコルを使用してユーザー認証を行うプロトコルです。
ちなみに、PSK/RSAは機器の認証に用いるもので、それぞれ事前に共有鍵を共有しておくPSK(Pre Shared Key)、証明書をつかうRSAが選べます。

IKEv2

IPsecでは認証部分をIKEというプロトコルで行っています。IKEv2ということは全身となるIKEv1というものがあるのですが、こちらは選択肢として見ることはあまりないように思います。IKEv2はIKEv1をより高速によりセキュアにするための改良が加えられたプロトコルで、2021年現在で比較的新しいプロトコルです。(新しいためあまり見ることがありません)
こちらもIKEv2という名前にはなっていますが、相変わらずIPsecを利用しています。

その他

そもそもここまでIPsecを利用するプロトコルを多く利用していましたが、IPsec以外にも暗号化を行えるプロトコルが有ります。超有名なSSLですね。SSLを利用したVPNは一般的にSSL-VPNと呼ばれていて、IPsecと異なりWebブラウザを利用して通信します。そのため、OS標準の機能で提供されることはなく、Webブラウザの拡張機能として機能をインストールして使うことになります。(SSL-VPNの種類については解説できるほど知らないのでゴメンナサイ)

結局どれを使うべきか(開発者向け)

いくつか紹介をしましたが、結局どれを使うべきなのかと思っている方がいるかもしれません。(私がこの記事を書こうと思った理由です)
業務の関係でどのプロトコルを使用するべきかを調べる機会があったので、ここからは主観を交えて比較を行っていきます。(結論から言ってしまうと技術が移行する期間にあるためか、どれも帯に短し襷に長しなのですが。。。)

絶対に使うべきでないもの

  • PPTP

これは論外です。脆弱性を抱えたプロトコルなので、そもそも選択肢として考えてはいけません。また、特に古いプロトコルなので、対応しているデバイスもどんどん少なくなっています(現在進行系)。例えば、iOSは9以前ではサポートしていますが、現在はされていません。

使ってもよいが近い将来改修が必要になる可能性があるもの

  • L2TP/IPsec
  • IKEv1を利用したプロトコル

これらはAndroid APIドキュメント曰くレガシーVPNと呼ぶそうで、現状セキュリティ面に問題を抱えているわけではなく、OS組み込みのVPNクライアントでサポートされていることも多いため、経験が有ってスピードが必要な開発の場面では選択肢として考えられると思います。ただし、最新のOSではサポートされなくなっているため、長く開発を続けていく必要のある場面では他のプロトコルと合わせて対応や、近い将来実装の置換を行う必要が出てくることになります。ちなみに、私が調べた範囲ではAndroid 12、iOS 14では選択できなくなっているようです(ただし、古いバージョンで設定してからOSをアップグレードした場合には、古い設定のものは使用できる模様?)さらに、OS組み込みでないサードパーティでこれらを実現するアプリも調査しましたが、私の調べた限りでは存在していなかったので、サードパーティに期待するのは(マネジメント的に)危険かと思います。

今後の互換性が期待できるが、現時点で対応デバイスが少ないもの

  • IKEv2

こちらは最新版のOSを使用していれば組み込みのVPNクライアントでサポートされているものです。Android 12、iOS 14(ちょっと自信ない)以降であれば利用することができます。Androidであれば、strongSwanというVPNアプリを導入することで12以前でも利用することができます。

その他

SSL-VPNを使うというのがひょっとすると普遍的で有効な手段かもしれません。SSL-VPNであれば、対応するソフトが存在しないという可能性が低いと思うので。残念ながらこちらについては数がかなり存在しているので、どれが良いかについてはちゃんと調査ができていません(ゴメンナサイ)

あとがき

どのプロトコルを使うかについては、なんだか時間をかけて調査をした割にはスッキリしない結果となってしまいました。これから同じような調査をしようとしている人の助けに少しでもなれば嬉しいです。
ちなみに、AndroidはAPI level 30からIKEv2が使えるようになるようなので、今後はもっと簡単にVPNが使えるようになっていくのかもしれませんね。(API level 30までは認証・暗号化を行える機能が提供されておらず、トンネリングの機能しか提供されないため、その上に自前で実装する必要がありかなり大変な作業になってしまいます。)

明日は@krmtmintさんの投稿です。お楽しみに!!

Discussion