はじめに
自宅回線のプロバイダからIPv6への切り替えを強く推奨されたため、移行を検討することにしました。
自宅のルータがIPoE方式に対応しているので、回線の切り替え自体は可能だとすぐに判明しましたが、問題はリモートアクセスです。
これまでルータ付帯のOpenVPNサーバを利用して自宅ネットワークへのリモートアクセスを行っていましたが、IPoE環境では固定IPv4アドレスが持てず、従来のVPNでの実現が困難ということが分かりました。
そこで辿り着いたのが、次世代VPNサービス「Tailscale」になります。導入があまりに簡単で感動したので、今更ながら備忘を兼ねてまとめてみました。
そもそもVPNとは?
専用の物理回線を敷設せずにロケーション間を仮想的な通信経路でセキュアに接続する仕組みです。
VPNには以下のような種類があります。
| 名称 | 説明 | 主な用途 |
|---|---|---|
| IPsec VPN | インターネットVPNの一種。ネットワーク層(L3)で暗号化し、プライベート接続を行う方式。 | 拠点間接続 |
| L2TP/IPsec | インターネットVPNの一種。データリンク層(L2)のトンネリングと、IPsecを組み合わせた技術。 | リモートアクセス |
| SSL-VPN | インターネットVPNの一種。SSL/TLSを使用して暗号化する。OpenVPNもSSL-VPNの一種である。 設定が比較的容易だが、脆弱性が発生しやすくセキュリティ面ではIPsecより劣る。 |
リモートアクセス |
| IP-VPN | キャリアの閉域ネットワーク上でプライベートアクセスを実現する方式。高価な帯域確保型回線を利用することで、高い通信品質を確保できる。 MPLSと呼ばれるラベルを利用したパケット転送技術を用いる。 |
拠点間接続 |
| 広域イーサネット | キャリアの閉域ネットワーク上でプライベートアクセスを実現する方式。データリンク層(L2)による接続を確立しており、IP以外の様々なプロトコルに対応できる。コストは高額だが、ネットワーク構築の自由度が高い。 | 拠点間接続 |
TailScaleの特徴
TailScaleはモダンなVPN技術「WireGuard」をベースに作られたメッシュVPNサービスです。
以下のような特徴があります。
- P2Pの暗号化通信:サーバを介さず、デバイス間が直接通信(UDPホールパンチング技術)
- NATトラバーサル:ルータのポート開放(インバウンド許可)が一切不要
- シンプルな設定:端末にアプリをインストールして機能を有効化するだけ
クライアントの設定
iPhoneの場合はApp Storeからダウンロードしてインストールします。
インストール後、アプリにログインします。
ホーム画面が表示されたら画面上部のトグルを有効にします。
これだけです。
私はiPhoneの他にMac、Raspberry Pi、Synology NASを使っていますが、いずれの場合も導入はとても簡単でした。
Tailscaleの管理コンソールでは端末間のアクセスコントロールや、外部ユーザのネットワークへの招待なども可能となっています。
Cryptokey Routingの仕組み
WireGuardの中核技術を成すのはCryptokey Routingと呼ばれる概念です。
Cryptokey Routingは、「公開鍵」と「許可されたIPアドレス(AllowedIPs)」を紐づけることで、セキュアな通信を実現する仕組みです。
以下の構成の想定でTailscaleの通信フローを解説します。
事前準備
まず、前述の「クライアントの設定」までの作業が完了すると、クライアントは管理コンソールからピア(通信可能なデバイス)の仮想IPアドレス、公開鍵などの情報を取得します。
UNIX系OSでは以下のコマンドで情報を確認することができます。
tailscale status --json
以下のような情報が登録されていることがわかります。
"Self": {
"PublicKey": "nodekey:yyyy",
"HostName": "iphone-12-mini",
"TailscaleIPs": [
"100.yy.yy.yy",
"fd7a:115c:a1e0::6"
],
"AllowedIPs": [
"100.yy.yy.yy/32",
"fd7a:115c:a1e0::6/128"
],
},
"Peer": {
"nodekey:xxxx": {
"PublicKey": "nodekey:xxxx",
"HostName": "DS218j",
"AllowedIPs": [
"100.xx.xx.xx/32",
"fd7a:115c:a1e0::5/128"
]
},
}
パケット送信時の流れ
Tailscaleを使用するデバイス(図中のiphone-12-mini)がLAN内のデバイス(図中のDS218j)に対して通信を行う際、以下のステップで処理します。
- 宛先IPの確認
送ろうとしているパケットの宛先IPアドレス(100.xx.xx.xx)を確認します。
宛先IPアドレスにはTailscaleによりデバイスに割り当てられたAllowedIPsを指定します。 - ピアの特定
設定内の「AllowedIPs」リストを照合し、その宛先IPが含まれているピアを探します。- 一致するピアがいれば、そのピアの公開鍵(nodekey:xxxx)を選択します。
- 一致するピアがなければ、パケットを破棄します。
- 暗号化
選択したピアの公開鍵を使用して、パケット全体を暗号化します。 - 送信
暗号化したデータを、そのピアの既知の「エンドポイント(実際のIPとUDPポート)」に向けて、UDPパケットとしてインターネット越しに送信します。
エンドポイントの情報は管理コンソールに事前に通知され、相手方に教えているため、ピア同士の通信が可能となります。
パケット受信時の流れ
外部から暗号化されたパケットが届いたとき、以下のステップで処理します。
- 復号と認証
届いたパケットを復号し、認証を試みます。正しく復号できれば、どのピア(どの公開鍵の持ち主)から送られてきたものかが確定します。 - 送信元IPの検証
復号された「中身のパケット」の送信元IPアドレス(100.yy.yy.yy)を確認します。 - AllowedIPsとの照合
その送信元IPが、そのピアの設定にある「AllowedIPs」に含まれているかチェックします。- 含まれている場合: 正当なパケットとみなし、デバイス内のネットワークスタックへ渡します。
- 含まれていない場合: 認証された相手からのパケットであっても、「なりすまし」や不正なルートと判断して破棄します。
- エンドポイントの更新
パケットが正しく認証された場合、そのパケットが送られてきた「外側のIPアドレスとポート」を、そのピアの最新の接続先(エンドポイント)として記憶します。これにより、相手のIPが変わっても自動追従(ローミング)が可能になります。
まとめ
なんと言ってもTailscaleの設定の手軽さに驚きました。
VPNサーバを自宅に構築することなくリモートアクセス環境を構築できてしまうということが、VPNに依存してきた身としては衝撃でした。
一方で、VPNサーバの場合は自前で構築・運用ができるため、ランニングコストが発生することはありませんでしたが、Tailscaleを導入する場合はSaaSを利用する形になります。
現在私は無料版の範囲内で使用することができていますが、料金の改定など将来的なプラン変更には注視しておく必要がありそうです。
参考ドキュメント
