Tailscale Funnelの検証メモ
ホスト名変更の追随作業
Tailscaleのノード名変更は、ホスト名に連動する設定にしていると自動で追随してくれる。
一方でFunnelのホスト名変更は手作業で行わなければならない。まずはTLS証明書の発行から。
# tailscale cert <newhostname>.tailnet-xxxx.ts.net
Public cert unchanged at <newhostname>.tailnet-xxxx.ts.net.crt
Private key unchanged at <newhostname>.tailnet-xxxx.ts.net.key
# ls /etc/tailscale/certs/
acme-account.key.pem <newhostname>.tailnet-xxxx.ts.net.crt <newhostname>.tailnet-xxxx.ts.net.key
<oldhostname>.tailnet-xxxx.ts.net.crt <oldhostname>.tailnet-xxxx.ts.net.key
そしてプロキシとFunnel有効化
# tailscale serve / proxy 2367
# tailscale serve funnel on
# tailscale serve status
https://<newhostname>.tailnet-xxxx.ts.net (Funnel on)
|-- / proxy http://127.0.0.1:2367
https://<oldhostname>.tailnet-xxxx.ts.net (Funnel on)
|-- / proxy http://127.0.0.1:2367
これで新しいホスト名のHTTPSリクエストを受け付けられる。
一方で古いホスト名のコンフィグと証明書が残るんだけど、その消し方は不明。tailscale serve --remove
でプロキシの設定は消せたみたいなんだけど、Funnelがオンのままだと以下の警告とstatus
の表示は残ってしまう。
WARNING: funnel=on for <oldhostname>.tailnet-xxxx.ts.net:443, but no serve config
ホスト名変更の事前にFunnelの無効化とプロキシ設定を削除しておくのが今のところ正しい手順みたい。リリースステージが進んだらこの辺りはこなれていく気がする。
tcpdumpの様子
Tailscale Funnelのトラフィックは、手元ではingress-tok-01.tailscale.com
からやってくる。恐らく、ノードからのレイテンシが小さいDERPを自動選択している。管理画面のRelaysと連動していそう。
# tcpdump not port 443 and not host 192.168.4.3 and not host derp7d.tailscale.
com
00:47:07.630286 IP ingress-tok-01.tailscale.com.41651 > 192.168.4.2.41641: UDP, length 112
00:47:07.630299 IP ingress-tok-01.tailscale.com.41651 > 192.168.4.2.41641: UDP, length 148
00:47:07.630301 IP ingress-tok-01.tailscale.com.41651 > 192.168.4.2.41641: UDP, length 124
00:47:07.630837 IP 192.168.4.2.41641 > ingress-tok-01.tailscale.com.41651: UDP, length 110
00:47:07.634508 IP 192.168.4.2.41641 > ingress-tok-01.tailscale.com.41651: UDP, length 92
00:47:07.636397 IP 192.168.4.2.41641 > ingress-tok-01.tailscale.com.41651: UDP, length 124
ingress-tok-01.tailscale.com
とは
Tailscale Funnel用エンドポイントの模様。FunnelエンドポイントのAレコードのIPアドレスを逆引きすると、このホスト名に向いているのがわかる。
% host xxxx.tailnet-xxxx.ts.net
xxxx.tailnet-xxxx.ts.net has address 103.84.155.153
xxxx.tailnet-xxxx.ts.net has IPv6 address 2403:2500:400:20::25a
% host 103.84.155.153
153.155.84.103.in-addr.arpa domain name pointer ingress-tok-01.tailscale.com.
%
IPアドレスはNetActuateの持ち物なので、Tailscaleがホスティングパートナーとして利用していると推測する。
tailscale0
インターフェースには載らない
Tailscaleを有効にすると、IPv4の場合100.x.x.x
のISP Shared Addressが払い出されVPNノード同士の通信のためにLinuxではtailscale0
インターフェースにそのアドレスが割り当てられる。しかし、Tailscale FunnelやTailscale SSHなどTailscale組み込みの通信はエージェントがWireguardトラフィックに直接込めてしまうようで、tcpdump -i tailscale0
ではキャプチャできない。デバッグしにくいので、今後のアップデートで改善して欲しいところ。
Funnelの場合はlo
インターフェース経由で指定のポートにトラフィックがやってくるので、tcpdump -i lo
でTLS暗号化を解かれたトラフィックが観測できる。
# tcpdump -i lo port 2367
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
01:12:59.354101 IP localhost.46924 > localhost.2367: Flags [S], seq 4278611943, win 65495, options [mss 65495,sackOK,TS val 4205671089 ecr 0,nop,wscale 7], length 0
01:12:59.354171 IP localhost.2367 > localhost.46924: Flags [S.], seq 668874999, ack 4278611944, win 65483, options [mss 65495,sackOK,TS val 4205671089 ecr 4205671089,nop,wscale 7], length 0
:
TLS証明書はノードに保持する
Tailscale Funnelのドキュメントでは、Funnelの利用にはHTTPS機能の有効化が必要項目として示されている。
実際にノードのホスト名変更時には手作業でTLS証明書の取得を行わなければFunnelで接続できなかったので、ノードのローカルディスクにTLS証明書を保持しFunnelの接続時に利用しているようだ。
言い方を変えると、DERPはHTTPS通信を終端しておらず、SNIでホスト名だけ確認してTCPフォワードでノードに回していると言える。
X-Forwarded-For
ヘッダにIPアドレスを付与する
FunnelはリバースプロキシとしてGoogle BotからのアクセスのX-Forwarded-For
ヘッダはこんな感じ。
66.249.72.211, fd7a:115c:a1e0:ab12:4843:cd96:6268:d02b
一応、ドキュメントにあるTailscaleのIPv6 ULAではある。
あと、TailscaleのIPv6 ULAはIPv4アドレスの下3オクテットとIPv6アドレスのヘキサデシマル下6桁が対応するのでこれからShared AddressなIPv4アドレスを類推できる。ただ、そのIPv4アドレスで逆引きしてもホスト名は返ってこなかった。
# host 100.104.208.43
Host 43.208.104.100.in-addr.arpa. not found: 3(NXDOMAIN)
#
tailscale0
でキャプチャできると謎が解けそうなんだけど。