homelab notes ポート開放できない家の自宅サーバー

tailnet 名とノード名を変えたら全サービスが落ちた

URL の見た目を良くするために名前を変えたら、11サービスが一斉に到達不可になった。 待てば戻るのだが、知らないと焦る。あと funnel --off が効かなくなる。

何を変えられるか

https://myhost.tailXXXXX.ts.net/
        ~~~~~~ ~~~~~~~~~
          A        B
変更方法影響
A ノード名tailscale set --hostname=<名前>そのホスト1台だけ
B tailnet 名管理コンソールの DNS 設定tailnet の全デバイス

tailnet 名は自分で決められない

ここは誤解していた。任意の文字列は入れられず、 cat-crocodile のようなランダムな単語ペアの候補から選ぶ方式。 気に入らなければ Re-roll で引き直せる。既定の tailXXXXX にはいつでも戻せる。

落ちる

改名した直後、リバースプロキシ配下の11サービスが全部到達不可になった。ログを見ると、

http: TLS handshake error from 100.x.y.z:45504:
  Get "http://local-tailscaled.sock/localapi/v0/cert/chat.<新tailnet>.ts.net
       ?type=pair&min_validity=0s": context deadline exceeded

全ノードが新しいドメイン名で証明書を取り直している。 ACME の dns-01 は1件あたり数十秒かかるので、その間のリクエストはタイムアウトする。

これは待てば直る。順に発行が終わって、10分ほどで全部復旧した。 確認用スクリプトのタイムアウトが短いと「壊れた」ように見えるだけなので、 慌てて設定をいじらないほうがいい。

発行が終わったかは、状態ディレクトリを見れば分かる。新旧のファイルが並ぶ。

$ ls data/default/chat/certs/
acme-account.key.pem
chat.<新tailnet>.ts.net.crt      ← これが出れば取れている
chat.<新tailnet>.ts.net.key
chat.<旧tailnet>.ts.net.crt      ← 古いほうも残る
chat.<旧tailnet>.ts.net.key

古い証明書が残るので、tailnet 名を元に戻せば即座に復旧する。 気軽に試して大丈夫、という判断材料になる。

Funnel の設定が旧名のまま残る

公開を張り直そうとして、こうなった。

$ tailscale funnel --https=443 off
error: failed to remove web serve: handler does not exist

状態を見ると理由が分かる。

$ tailscale serve status
https://myhost.<旧tailnet>.ts.net (Funnel on)     ← 旧名で登録されたまま
|-- / proxy http://127.0.0.1:8082
serve の設定は、設定した時点のホスト名を持ち続ける。 off は「現在の名前」のハンドラを探すので、改名後は一致せず失敗する。 消すのではなくリセットしてから張り直す。
tailscale serve reset
tailscale funnel --bg --https=443 http://127.0.0.1:8082

なお旧ノード名の DNS レコードはしばらく残るが、証明書が無いので TLS が張れない。 意図しない公開経路にはならない(no peer certificate available で確認した)。

参照の一括書き換え

URL を書いてある場所は思ったより多い。実測で8ファイル24箇所と、 ダッシュボードの SQLite に11件あった。

置換パターンで一度取りこぼした。ドメインの書かれ方が2通りあったため。

https://grafana.<tailnet>.ts.net       ← 先頭にドットあり
TS_SUFFIX="${TS_SUFFIX:-<tailnet>.ts.net}"   ← ドットなし(拾えていなかった)

.<tailnet>.ts.net ではなく <tailnet>.ts.net で置換する。

それと、置換スクリプト自身を対象から外すのを忘れずに。 旧名を変数に持っているので、自分を書き換えて壊れる。

mapfile -t FILES < <(grep -rl "$OLD_NET" . --include='*.sh' --include='*.md' \
  | grep -v '\.bak-\|\.pre-' \
  | grep -v '^\./rename-tailnet\.sh$')   # 自分自身は除外

変えなくていいもの

Tailscale IP(100.x.y.z)は改名しても変わらない。 ACL で IP を指定していれば、そこは無変更で済む。