Tailscale の exit node と subnet router

想定する構成
TailscaleNode は、routerd ホストを tailnet に参加させ、次の経路を広告したい場合に使います。
- exit node(
0.0.0.0/0と::/0) - 1 つ以上の subnet route
- exit node と subnet route の両方
routerd は tailscaled を置き換えません。
tailscale up を実行する systemd ユニットを生成し、ノードの広告設定を管理します。
Tailscale のアカウント、制御プレーン、経路承認は Tailscale 側に残します。
tailscale の導入
依存パッケージを Package で宣言します。
apiVersion: system.routerd.net/v1alpha1
kind: Package
metadata:
name: router-service-dependencies
spec:
packages:
- os: ubuntu
manager: apt
names:
- tailscale
- tailscale-archive-keyring
- os: freebsd
manager: pkg
names:
- tailscale
optional: true
Ubuntu では、Package が tailscale を導入する前に Tailscale の apt リポジトリが必要です。
リポジトリの追加は、通常の初期構築手順で済ませてください。
秘密値を Git に残さない
本番設定では authKeyEnv と authKeyFile を推奨します。
apiVersion: net.routerd.net/v1alpha1
kind: TailscaleNode
metadata:
name: edge
spec:
hostname: edge
advertiseExitNode: true
advertiseRoutes:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
acceptDNS: false
acceptRoutes: false
authKeyEnv: TS_AUTHKEY
authKeyFile: /usr/local/etc/routerd/secrets/tailscale.env
環境ファイルは routerd の YAML の外に置きます。
sudo install -d -m 0700 /usr/local/etc/routerd/secrets
sudo sh -c 'printf "%s\n" "TS_AUTHKEY=REDACTED" > /usr/local/etc/routerd/secrets/tailscale.env'
sudo chmod 0600 /usr/local/etc/routerd/secrets/tailscale.env
既にログイン済みのノードでは、authKey、authKeyEnv、authKeyFile を省略できます。
その場合、routerd は秘密値を systemd ユニットに埋め込まず、広告設定だけを再適用します。
Tailscale は既定で UDP/41641 を使います。
routerd は TailscaleNode がある場合にこのポートを予約済みとして扱います。
WireGuardInterface が同じポートを使う設定は検証で拒否します。
プライベートアドレスをまとめて広告する
ルーターを自宅や拠点ネットワークへの入口にする場合は、RFC 1918 のプライベートアドレス全体を広告できます。
apiVersion: net.routerd.net/v1alpha1
kind: TailscaleNode
metadata:
name: edge
spec:
hostname: edge
advertiseExitNode: true
advertiseRoutes:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
acceptDNS: false
acceptRoutes: false
この設定を反映したあと、Tailscale の管理画面で広告された経路を承認します。
承認前でも tailscale debug prefs では要求した経路が見えますが、tailscale status --self --json の Self.AllowedIPs にはまだ出ないことがあります。
ファイアウォールゾーンの配置
tailscale0 を Interface として宣言すると、状態と Web 管理画面の Interfaces に表示できます。
apiVersion: net.routerd.net/v1alpha1
kind: Interface
metadata:
name: tailscale
spec:
ifname: tailscale0
mtu: 1280
managed: false
mtu: 1280 を指定すると、派生する TCP MSS clamp が Tailscale 経由の経路を考慮します。
無関係な LAN から WAN への経路まで低い MTU に下げることはありません。
家庭ルーターでは、tailscale0 は mgmt ではなく trust ゾーンに置くのが自然です。
apiVersion: firewall.routerd.net/v1alpha1
kind: FirewallZone
metadata:
name: lan
spec:
role: trust
interfaces:
- Interface/lan
- Interface/tailscale
---
apiVersion: firewall.routerd.net/v1alpha1
kind: FirewallZone
metadata:
name: management
spec:
role: mgmt
interfaces:
- Interface/mgmt
この構成では、tailnet のクライアントは trust -> self の経路で routerd の Web 管理画面などに到達できます。
一方で、ファイアウォールが trust -> mgmt の転送を拒否していれば、tailnet から管理 VLAN 全体へ広く入ることはできません。
tailnet 全体を管理ネットワークとして扱いたい場合だけ、tailscale0 を mgmt に置きます。
反映と確認
設定を検証してから routerd を再起動します。
routerctl validate -f /usr/local/etc/routerd/router.yaml --replace
systemctl restart routerd.service
生成された systemd ユニットを確認します。
systemctl cat routerd-tailscale-edge.service
Tailscale 側の状態を確認します。
tailscale status --self --json | jq '.BackendState, .Self.AllowedIPs'
tailscale debug prefs | jq '.AdvertiseRoutes'
routerd 側の状態を確認します。
routerctl status --json
routerctl get TailscaleNode/edge -o yaml
routerctl tailscale peers
routerctl tailscale peers -o json は tailscale status --json を読み、ピア一覧を routerd の CLI 形式で表示します。Web 管理画面のリソース画面でも、TailscaleNode にピアのオンライン状態、relay、last seen、許可された経路を表示します。
Web 管理画面を Tailscale 経由で見たい場合は、ルーターの Tailscale アドレス、または承認済みの経路上のアドレスで確認します。
curl -f http://100.64.0.1:8080/
上のアドレスは例です。 実際のルーターの Tailscale IP に置き換えてください。
補足
acceptDNS: falseにすると、Tailscale がルーター自身の DNS 設定を置き換えません。routerd は LAN の DNS を優先します。DNSResolver、ローカルゾーン、DHCP 由来のレコード、条件付き転送を LAN 側の権威として維持し、MagicDNS にホストのリゾルバーを乗っ取らせません。acceptRoutes: falseにすると、ルーターはほかのノードが広告する経路を取り込みません。経路を外へ広告するルーターでは自然な設定です。- routerd は Tailscale ピアのメトリクスとして
routerd.tailscale.peer.countとrouterd.tailscale.last_handshake.secondsを出力します。運用上のハンドシェイク経過時間としては Tailscale status のLastSeenを使います。 - exit node と subnet route の承認は Tailscale 側で行います。
- auth key は examples や Git 履歴に残さず、実機では
authKeyFileを使います。