Open12

Tailscaleについて調べる

mactkgmactkg

読んでる...


TailscaleはWireGuardというOSSを使っている。WireGuardはとても軽量な端末間の暗号化されたトンネルを作っていて、各端末のことをWireGuardは「endpoint」、Tailscaleは「node」と呼んでいる。

多くの場合、VPNユーザーは「hub and spoke」アーキテクチャを作っていて、それにはVPNゲートウェイといった何らかの「コネクタ」が必要になってくる。

シンプルにWireGuardを設定しようとすると、各端末と通信するためにN * (N-1)のトンネルが必要になってくるけど、hub and spokeなら中心のゲートウェイを使えば良いのでお手軽で、トンネルはN個ですむ。ただし、これにも問題もある。

まず多くの会社は一つの場所だけで働いていないということ。オフィスは複数あり、クラウドのデータセンターやリージョン、VPCはいくつもあるだろう。ネットワークの分だけ、IPSecなどを利用してセカンダリのトンネルを作り通信可能にしなくてはならない...。

さらに、スケールしにくい。まずそもそも、リモートユーザーがVPNのゲートウェイの近くにいない可能性がある。NYCで働いていてもSFOにしかゲートウェイがなければ、SFOにあるゲートウェイを経由しないといけない。また、アクセスしたい環境がVPNゲートウェイの近くにないという問題もある。SFOにゲートウェイがあるけど、データセンターはNYCにあるような場合。こうなるとアメリカを横断することになり、レイテンシは高まる。(me: 多分、多くの会社はこれでやっているな)

幸い、WireGuardはこうなっていない。めちゃめちゃ軽いトンネルを作るので、Clientから各拠点にトンネルをはれるので、最短経路でできる。静的なIPと、Firewall、公開鍵だけ用意すれば良い。新しいユーザーには各拠点の鍵を渡せば問題ない。

mactkgmactkg

hub-and-spokeだと、各ノードが直接会話することができない。(me: IPSecとかでセカンダリのトンネルを作っているなら別だよね?)

WireGuardのトンネルは「非常に軽量」なのを覚えている?全てのノードがお互いに接続できたらどうだろうか?それを、「メッシュネットワーク」と呼ぶ。

mactkgmactkg

メッシュネットワークは、各ノードが接続できるようにする。Nノードあったら、N * (N-1)トンネルを作成する。

メッシュネットワークの課題

  • 静的IPが常に割り当てられるわけではないので、誰がどこにいるかを常に把握できるようにする必要がある。
  • Firewallのポートはincomingな通信のために開けておきたいが、カフェやホテルなどの公共ネットワークでも安全に通信するためには、容易に全開けは難しい。
  • 会社はコンプライアンスのために、各ノードの通信監査ログを残しておく必要がある。

Tailscaleはこれらを解決する。

mactkgmactkg

鍵のやりとり

WireGuardの通信が作れたとして、鍵のやりとりをどうするか。TailscaleのCoordination Serverでやりとりをする。 login.tailscale.com 公開鍵の共有Dropboxみたいなもん。

ちょいまち、hub-and-spokeに戻ったの?いや違う。ただの暗号化キーの交換と、ポリシー設定だけ。(me: microserviceにとても似ているような気がする。)

  1. 各ノードはランダムな鍵のペアを生成し、公開鍵とIDを関連づける。
  2. ノードはCoordination Serverに接続して、公開鍵と、ノードがどこにあるか、どのドメインにあるかをメモる。
  3. ノードは公開鍵とノードのある場所のリストをダウンロードする。
  4. ノードは公開鍵のセットを使ってWireGuardのインスタンスを作る。

秘密鍵は各ノードが持っていて、暗号化に使う。(zero trust networkingと呼ばれる概念。(me: これがzero trustなの?あまりよく知らないけど・・・。))

Tailscaleはincremental deploymentをサポートしていて、新しいスタイルのメッシュ通信と、古いスタイルの「ハブ」を使ったハイブリットネットワークを作成できる。(me: 便利!よくできてる!)この時にだけは暗号化されていないパケットを送ったり、hubが通信を見れるような状況になる。

mactkgmactkg

DERP: Designated Encrypted Relay for Packets

UDPがブロックされているネットワークでは、STUNやICEが使えないので、HTTPSを使ってICE標準のTURNサーバーと同じ役割を実装していて、それがDERP。通信はEnd-to-Endで暗号化されているため、途中のリレーサーバーが通信を見ることはできない。

mactkgmactkg

ACLとセキュリティ

VPNは「セキュリティ」のソフトウェアと思われているが、実は「接続性」のソフトウェアである。むしろ、ネットワークに入ることのできるデバイスを増やしている。

結果として、VPNの設備はファイアウォールと一緒に売られている。IPアドレスをベースにアクセス制御を行う。ユーザーはロールではなくIPに基づいているため、やりたいことができない必要がある。その結果、トランスポート層やアプリケーション層で認証をおこなっている。また、ファイアウォールは組織全体に分散していて、個別に設定されている。それらを正しく設定しなきゃならない。

また、VPN/ファイアウォールデバイスを他社のベンダーのIDシステムと混ぜて使うのはめちゃめちゃ大変で、VPNベンダーはIDシステムを売り、IDベンダーはVPNシステムを販売している。

メッシュネットワークにするとこれはもっと大変なことになる。中心となるポイントがないので、一体どこでファイアウォール相当のことをしたら良いのだろう?Tailscaleでは、それぞれのノードで設定を行なっている。各ノードは復号するときに許可されていない通信をブロックする責任がある。

TailscaleのCorrdination ServerでACLポリシーは設定されていて、各ノードに配布される。(me: この情報の配布スピードはどれくらいなのだろう) 実際は、ACLポリシーを元に、許可されていない通信の公開鍵さえ配布しないようになっている。これにより、あらゆるプロトコルの攻撃を防いでいる。

監査ログ

監査ログはネットワーク内部にある中央ログサービスに送られるようになっている。(me: これはTailscaleのappがやっているのかな...)

mactkgmactkg

mkcertを使って証明書をつくり、AndroidやiOSでもHTTPSでアクセスするようにするのは簡単にできた。

https://github.com/FiloSottile/mkcert

next.jsの場合は、カスタムサーバーを立ち上げる必要があって手間がかかる。nginxを前段に置いて、そこでSSL終端してしまう方がいいのかもしれない...。

それと、オレオレCA証明書をモバイル端末にインストールするのは問題ないのかが少し不安。(多分、ローカルの証明書鍵を盗まれない限り大丈夫かな。これをみんなが使うとなると、面倒なことになる)

jxckさんが記事を書いているが、自分の持っているドメインの一つのサブドメインをlocalhostに向ける方法がありそう。これは便利そうで、そのサブドメインをLet's Encryptしてしまえばよい。ただ、モバイル端末から行く経路はどうしようかな・・・。

https://blog.jxck.io/entries/2020-06-29/https-for-localhost.html

mactkgmactkg

例えば、Magic DNSで mba と設定していたとき、mba でもアクセスできるけど、内部的には mba.mactkg.gmail.com.beta.tailscale.net が正しいアドレスになっている。そこで、 mba.makerbox.net をCNAMEなどで mba.mactkg.gmail.com.beta.tailscale.net に向ければ、やりたいことができるようになるのかもしれない。

https://tailscale.com/kb/1081/magic-dns