Closed4

Tailscale Funnelの検証メモ

takiponetakipone

ホスト名変更の追随作業

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の無効化とプロキシ設定を削除しておくのが今のところ正しい手順みたい。リリースステージが進んだらこの辺りはこなれていく気がする。

takiponetakipone

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.xISP 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
  :
takiponetakipone

TLS証明書はノードに保持する

Tailscale Funnelのドキュメントでは、Funnelの利用にはHTTPS機能の有効化が必要項目として示されている。

https://tailscale.com/kb/1223/tailscale-funnel/#https-required

実際にノードのホスト名変更時には手作業でTLS証明書の取得を行わなければFunnelで接続できなかったので、ノードのローカルディスクにTLS証明書を保持しFunnelの接続時に利用しているようだ。

言い方を変えると、DERPはHTTPS通信を終端しておらず、SNIでホスト名だけ確認してTCPフォワードでノードに回していると言える。

takiponetakipone

FunnelはリバースプロキシとしてX-Forwarded-ForヘッダにIPアドレスを付与する

Google BotからのアクセスのX-Forwarded-Forヘッダはこんな感じ。

66.249.72.211, fd7a:115c:a1e0:ab12:4843:cd96:6268:d02b

一応、ドキュメントにあるTailscaleのIPv6 ULAではある。

https://tailscale.com/kb/1033/ip-and-dns-addresses/#tailscale-ipv6-local-address-prefix

あと、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でキャプチャできると謎が解けそうなんだけど。

このスクラップは2023/03/02にクローズされました