
Tailscale Subnet RoutersのHA構成での拠点間VPN下り通信にAmazon VPC Route Serverを利用する
ども、大瀧です。
Tailscaleには拠点間VPN機能としてSubnet routersという機能があります。Subnet routersには標準でHA機能があり、Subnet routerノードの障害検知およびフェイルオーバーが自動で構成されます。一方で拠点ネットワークにおいてSubnet routerノードに向けるルーティングには、個別のフェイルオーバー実装が必要です。本ブログでは拠点ネットワークとしてAmazon VPCを利用する構成において、Amazon VPC Route Serverを利用するHA構成をご紹介します。
Tailscale Subnet routersの一般的な冗長構成との違い
Tailscale Subnet routersの一般的な冗長構成ではSubnet router→拠点ネットワークに向けてIPマスカレード(SNATと呼ぶこともあります)をセットするため、拠点ネットワークからTailscale網へのルーティングを考慮する必要はありません。Amazon VPCを組み合わせる多くのSubnet router構成はAmazon VPC側をセンターネットワークとして位置づけるため上記のIPマスカレードで充足できるケースがほとんどでしょう。
今回ご紹介するのは、なんらか目的があってAmazon VPC→Tailscale網(もしくはその先のネットワーク)下り方向の通信が要件として含まれるレアケースの場合です。
Amazon VPC Route Serverの構成
まずはAmazon VPCのRoute Serverを構成していきましょう。Route Serverはその名の通り、VPCの経路情報を管理するマネージドサービスです。今回の構成では、Tailscale Subnet routerから広告されるTailscaleのルーティングをVPCに反映するために利用します。
Amazon VPC管理画面のメニューから[ルートサーバー]を選択、右上の[ルートサーバーを作成]ボタンをクリックし作成画面に遷移します。
[ルートサーバーを作成]画面では、任意の名前(今回はrouteserver01)を記入、[Amazon側のASN]はプライベートASNの 65000
を入力、[ルートを保持]は検証目的のため「無効化」、[SNS通知を有効にする]は通知の様子を見てみたいのでオンにし、「ルートサーバーを作成」ボタンをクリックするとルートサーバーの作成が進行していきます。
ルートサーバーのプロパティ画面に遷移し、しばらく待って[状態]が「使用可能」になったら作成完了です。
続いて、ルーティングを管理するVPCおよびルートテーブルを関連付けていきます。[関連付け]タブの「ルートサーバーを関連付ける」ボタンをクリックします。
一覧からルーティングを設定するVPCを選択し、「ルートサーバーを関連付ける」ボタンをクリックして完了です。
次に[伝播]タブを選択、「伝播を有効にする」をクリックします。
ドロップダウンから、ルーティングを追加したいルートテーブルを選択し、「伝播を有効にする」ボタンをクリックします。
これでルーティングの管理対象の設定は完了です。
ここからはVPC Route ServerとTailscale Subnet routerとの経路情報交換のための構成をしていきます。前後半になっていて、前半は経路情報をルートサーバーで受け取るためのルートサーバーエンドポイントの構成です。[ルートサーバーエンドポイント]タブの「ルートサーバーエンドポイントを作成」をクリックします。
任意の名前(今回はendpoint01)、[ルートサーバー]は先ほど作成したルートサーバーのID(rs-XXXXXXXXXXXX
の形式)、[サブネット]はルートサーバーエンドポイントを配置するVPCサブネットを選択し、「ルートサーバーエンドポイントを作成」ボタンをクリックします。
[状態]列が[使用可能]になったら作成完了です。
[ENI アドレス]がエンドポイントのIPv4アドレスなので、次のステップで利用するためメモしておきます。
Tailscale Subnet routerの構成
ここからはTailscaleのVPN網とAmazon VPCを相互接続するSubnet routerを構成します。今回はHA冗長構成が目的なので、Subnet routerとなるEC2インスタンスを2台作成し、操作していきます。
- 動作確認環境
- AMI:
ami-038e94aea55c0f480
(ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-arm64-server-20250305) - BIRDバージョン: 2.14
- Tailscaleバージョン: 1.82.0
- AMI:
インスタンスを作成したら、それぞれEC2インスタンスの送信元/送信先チェックを停止します。EC2インスタンスを1台ずる選択、右クリックし[ネットワーキング] - [ソース/宛先チェックを変更]を選択して「停止」チェックをオンにします。
続いてEC2のターミナルにアクセスし、経路交換のためのソフトウェアBIRDをインストール、構成します。BIRDの最新バージョンは3.x系ですが、Ubuntu Server 24.04LTSのパッケージリポジトリは2.x系のため、今回は2.x系の bird2
パッケージを利用します。以下のコマンドでインストールします。
$ sudo apt update
$ sudo apt install bird2
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
libssh-gcrypt-4
Suggested packages:
bird2-doc
The following NEW packages will be installed:
bird2 libssh-gcrypt-4
0 upgraded, 2 newly installed, 0 to remove and 39 not upgraded.
Need to get 701 kB of archives.
After this operation, 2169 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
$
続いてBIRDの構成ファイルを作成していきます。Tailscaleの下記ドキュメントを真似してみました。
neighbor
に先ほどメモしたRoute ServerのIPv4アドレスとASN65000
を入れます。今回Tailscale Subnet routerのASNは2台とも65001
にしました。
log syslog all;
protocol device {
scan time 10;
}
protocol bgp {
local as 65001;
neighbor <YOUR ENDPOINT IP> as 65000;
ipv4 {
import none;
export filter{
bgp_med = 0;
accept;
};
};
}
include "tailscale_bird.conf";
tailscale_bird.conf
ファイルの中身はドキュメントで参照しているGitHubのものを以下の通りコピペしています。
protocol static tailscale {
ipv4;
route 100.64.0.0/10 via "tailscale0";
}
また、VPC Router Serverではフェイルオーバーのプライマリ/セカンダリをBGPで通知するMED値で判断します。数値が小さい方がプライマリになるので、1台目のSubnet router(ノード1)はMED値0
、2台目のSubnet router(ノード2)はMED値100
にしてみました。
bgp_med = 100;
それぞれのノードでBIRDの構成ができたら、一度BIRDを再起動しておきましょう。
$ sudo service bird2 restart
Tailscale Subnet routersのHAでは先にSubnet Routerを有効にしたノードがプライマリになるので、この後のTailscaleエージェントのセットアップをノード1、ノード2の順に実行する点に注意しましょう。
というわけで、以下の手順でTailscaleのVPNエージェントを構成します。Amazon VPCのCIDRは今回172.31.0.0/16
を想定しているので、手元で試す場合は検証する環境のCIDRに読み替えてください。
$ curl -fsSL https://tailscale.com/install.sh | sudo sh
$ echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
$ echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
$ sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
$ sudo tailscale up --advertise-routes=172.31.0.0/16
Warning: UDP GRO forwarding is suboptimally configured on ens5, UDP forwarding throughput capability will increase with a configuration change.
See https://tailscale.com/s/ethtool-config-udp-gro
To authenticate, visit:
https://login.tailscale.com/a/XXXXXXXXXXXXXX (Webブラウザからアクセスして認証する)
Success.
TailscaleエージェントからBIRDを参照するために、エージェントの起動オプションを /etc/default/tailscaled
ファイルの最終行に追加します。Ubuntu Server 24.04LTSでは上記Tailscaleドキュメントとソケットファイル名が微妙に異なっていて、検証時の引っかかりポイントだったのでお気を付けください。
# Set the port to listen on for incoming VPN packets.
# Remote nodes will automatically be informed about the new port number,
# but you might want to configure this in order to set external firewall
# settings.
PORT="41641"
# Extra flags you might want to pass to tailscaled.
FLAGS="--bird-socket=/var/run/bird/bird.ctl"
続いてSubnet routerが広告するVPCのCIDRをTailscaleのVPN網で扱う許可設定を行います。TailscaleのMachines管理画面で2台のSubnet routerをそれぞれを選択し、メニューの[Edit route settings...]をクリック、VPCのCIDRのチェックボックスをオンにします。
これでTailscaleの構成は完了です。最後にVPC Router ServerにTailscale Subnet routerをピアとして登録します。ここまで構成してきたEC2インスタンス2台のプライベートIPアドレスをメモしておきましょう。
VPCのルートサーバーエンドポイント管理画面で「ルートサーバーピアを作成」ボタンをクリック、登録画面を開きます。任意の名前(ここではtailscale01
)を入力、ルートサーバーエンドポイントIDは作成したエンドポイントのrse-
から始まるID、ピアアドレスには先ほどメモしたノード1のプライベートIPアドレスとBIRD2で設定したピアASN65001
を入力、[ピアライブネス検出]は「BGPキープアライブ」を選択しました。
ノード2も同様にルートサーバーピアとして登録します。ルートサーバーピアの[BGPステータス]プロパティの[アップ]の表示や、Subnet routerのターミナルでのbirdc
コマンドのshow protocols all
サブコマンドでBGPセッションの状態が確認できます。正常に経路が広告されれば、Route Serverを関連付けているVPCルートテーブルにTailscale既定のIPアドレス帯域100.64.0.0/10
が追加されます。
良さそうですね。試しに、上記ルートテーブルが関連付けられたVPCサブネットに接続するEC2インスタンスからTailscaleのノードであるクアッド100にPingを送出してみます。
$ ping 100.100.100.100
64 bytes from 100.100.100.100: icmp_seq=76 ttl=63 time=0.674 ms
64 bytes from 100.100.100.100: icmp_seq=77 ttl=63 time=0.760 ms
64 bytes from 100.100.100.100: icmp_seq=79 ttl=63 time=1.58 ms
64 bytes from 100.100.100.100: icmp_seq=80 ttl=63 time=0.760 ms
64 bytes from 100.100.100.100: icmp_seq=81 ttl=63 time=0.782 ms
$
Pingのレスポンスが返ってきました、Amazon VPCからTailscaleの方向に疎通できていますね。
どちらのSubnet routerの経路がルートテーブルに採用されているのかは、ルートテーブルの画面のほかにRoute Serverの[ルート]タブで確認することもできます。
[プレフィックス]列は2行とも同じ100.64.0.0/10
なのに対して[ネクストホップIP]や[ルートサーバーピアID]がノード1と2のとで異なるのと、[ルートインストールの詳細]列でルートテーブルにセットされている方とそうでない方の様子がわかりますね。
試しにプライマリのSubnet routerノードのEC2インスタンスを停止し、フェイルオーバーの様子を見てみました。
スクリーンショットを撮り忘れてしまったのですが、上記の[ルート]タブでセカンダリのルートサーバーピアに切り替わっていることが確認できました。また、フェイルオーバーの前後でEC2インスタンスからのPing送出を続けていたのですが、下記の結果の通りICMPレスポンスが途絶えることはなくRTTが1.3msほど少し長くなる程度でスムーズに切り替えられた様子がわかりました。
$ ping 100.100.100.100
64 bytes from 100.100.100.100: icmp_seq=510 ttl=63 time=0.754 ms
64 bytes from 100.100.100.100: icmp_seq=511 ttl=63 time=0.767 ms
64 bytes from 100.100.100.100: icmp_seq=512 ttl=63 time=1.36 ms
64 bytes from 100.100.100.100: icmp_seq=513 ttl=63 time=0.266 ms
64 bytes from 100.100.100.100: icmp_seq=514 ttl=63 time=0.250 ms
$
VPC設計の考慮点
今回の構成にあたり、アベイラビリティーゾーンとVPCサブネット、ルートサーバーエンドポイントの考慮点を示します。複数のアベイラビリティーゾーン構成のためにはルートサーバーエンドポイントを複数作成するわけですが、VPCルートサーバーはルートサーバーエンドポイントあたりで課金されるため、エンドポイントを2つ作成すると1つの場合の倍の料金がかかります。エンドポイントの利用料金はUSリージョンで月額500ドル超、東京リージョンは3割増しでの700ドル超となかなかのお値段なので、エンドポイントを複数利用するかは費用面に留意して設計しましょう。
また、Tailscale Subnet routerを配置するVPCサブネットは以下2点を考慮します。
- ルートサーバーによって追加されるルーティング(=Subnet router自身が広告するルーティング)の影響を受けないように、ルートサーバーを関連付けるルートテーブルをセットしない専用のサブネットに配置する
- BIRDのeBGPは既定で同一サブネットのネイバーとBGPセッションを確立するため、ルートサーバーエンドポイントと同じVPCサブネットに配置する
direct
ディレクティブ
図にすると以下のようになります。
VPCサブネットはPublic/Privateは特に問いません。TailscaleエージェントからインターネットのDERPへの接続性が確保できていればOKです。
まとめ
Tailscale Subnet routersの冗長構成においてVPCからTailscale方向のルーティングを管理するためにVPCルートサーバーを利用する構成をご紹介しました。レアな構成ではありますが、なにかの役に立てば幸いです。
参考URL