プログラミング

自宅サーバーが落ちた?と思ったらTailscaleのキー期限切れだった話

外出先から自宅サーバーに突然つながらなくなり、サーバー本体の故障を疑ったら、原因はTailscaleのノードキーの有効期限切れでした。サーバー本体とTailscaleを切り分ける手順、再ログインでの復旧、キーの有効期限をサーバーだけ無効化する恒久対策(Disable key expiry)までを、実際のコマンド出力つきでまとめた障害記録です。

目次

はじめに

外出先から自宅サーバーにつながらなくなって、「サーバーが落ちたのでは」と焦ったことはありませんか。

私はまさに今日、これをやりました。
スマホから自宅サーバーのサービスが開けなくなり、「落ちてる?なんか遅い?」と慌てたのですが、結論として、サーバー本体は元気に動いていました。
原因はTailscaleの「ノードキーの有効期限切れ」です。

白状すると、この期限切れは以前のTailscale導入記事の中で「サーバーはキーの有効期限を切っておくと安心です」と自分で書いていた、まさにそのトラブルです。
書いておきながら、自分のサーバーには設定していませんでした。

この記事では、「サーバーが落ちたのか、Tailscaleが切れただけなのか」を切り分ける手順から、復旧、二度と起きなくする設定までを、実際のコマンド出力つきで紹介します。
同じ状況で慌てている方は、上から順に確認してみてください。

症状:外から全部つながらない

起きたことはシンプルで、外出先のスマホから、自宅サーバーで動かしているサービスがどれも開けなくなりました。

私の自宅サーバーは、ルーターのポート開放をせず、Tailscaleのネットワーク(テールネット)経由でだけ外からアクセスできる構成にしています。
つまり外から見ると、Tailscaleが死ぬと「サーバー全体が死んだ」ように見えます。
ここがこの構成の弱点というか、切り分けを知らないと慌てるところです。

切り分け1:サーバー本体は生きているか

まず確認すべきは、サーバー本体の生死です。
私はサーバーに入れてあるClaude Codeに「自宅サーバー落ちてる?」と聞いて調べてもらったのですが、やっていることは次の1コマンドです。

uptime

家の中にいるならLANから、外にいるなら別経路(後述)でサーバーに入って実行します。
私の環境ではこうなりました。

09:36:22 up 134 days, 15:33, ... load average: 0.08, 0.11, 0.09

「up 134 days」は、サーバーが134日間再起動もせず動き続けているという意味です。
load average(サーバーの混み具合の指標)も0.1前後で、ほぼ何もしていない状態です。
つまり、サーバーは落ちてもいないし、重くもなっていませんでした。

この時点で、疑いは「サーバー」から「経路(Tailscale)」に移ります。

切り分け2:Tailscaleの状態を見る

次に、サーバー側でTailscaleの状態を確認します。

tailscale status

すると、見慣れない返事が返ってきました。

Logged out.
Log in at: https://login.tailscale.com/a/xxxxxxxxxxx

「Logged out.」、つまりこのサーバーはテールネットからログアウトした状態になっていました。
これなら外からつながらないのも当然です。

ちなみに、Tailscaleのサービス(tailscaled)自体が死んでいるわけではありません。
systemdで確認すると、プロセスは動いたまま「ログインが必要」と言っています。

systemctl status tailscaled
● tailscaled.service - Tailscale node agent
     Active: active (running) since Mon 2026-08-24 19:58:41 JST; 13h ago
     Status: "Needs login: https://login.tailscale.com/a/xxxxxxxxxxx"

「active (running)なのにNeeds login」という、ちょっと不思議な状態です。
サービスの再起動をしても直らないタイプの症状なので、ここで再起動を試して時間を溶かさないようにしてください(私は危うくやりかけました)。

原因:ノードキーの有効期限切れ

原因は、Tailscaleの「ノードキーの有効期限」です。

Tailscaleは、テールネットに参加する端末ごとに「ノードキー」という鍵を発行して、端末同士の暗号化通信に使っています。
そして安全のため、このキーには既定で有効期限が設けられています。
私の環境で確認したところ、期限は「ログインした日から180日」でした。

期限が切れると、その端末はテールネットから自動的にログアウトされます。
再起動も設定変更もしていないのに、ある日突然つながらなくなるのはこのためです。

実際、私のサーバーの登録日を確認すると2026年2月25日で、つながらなくなったのはちょうど180日後の8月24日ごろでした。
きれいに計算が合います。

持ち歩くノートパソコンやスマホなら、紛失・盗難のリスクがあるので定期的にログインし直させる意味があります。
ただ、家に置きっぱなしで動き続けるサーバーがある日黙ってログアウトするのは、正直困る挙動です。

復旧:再ログインする

復旧は簡単で、再ログインするだけです。

tailscale status が表示していた https://login.tailscale.com/a/... のリンクを、パソコンやスマホのブラウザで開いて、Tailscaleのアカウントで承認します。
もしそのリンクの有効期限が切れていたら、サーバーで次のコマンドを実行すると新しいリンクが表示されます。

sudo tailscale up

承認が終わったら、つながったかを確認します。

tailscale status
100.xx.xx.xx   homeserver  you@   linux    -
100.xx.xx.xx   my-phone    you@   android  active; direct ..., tx 35596 rx 8212

サーバーがオンラインに戻り、スマホと直接つながって通信量(tx/rx)が流れていれば復旧完了です。

なお、この作業には「サーバーに入る別経路」が必要です。
私はTailscale経由のSSHをメインにしているので、今回は家の中からLAN経由でサーバーに入りました。
外出中に切れた場合に備えて、家のネットワークからは直接入れる経路(LAN内SSHなど)を残しておくのが大事だと、今回あらためて思いました。

恒久対策:サーバーだけ「キーの有効期限」を無効にする

このままだと180日後にまた同じことが起きるので、恒久対策をします。
Tailscaleには、端末ごとにキーの有効期限を無効化する設定があります。

  1. ブラウザで管理コンソール(login.tailscale.com)を開く
  2. 「Machines」の一覧で、サーバーの行の右端のメニューを開く
  3. 「Disable key expiry」を選ぶ

これだけです。
この設定は管理コンソールからしか操作できず、サーバー側のコマンドでは設定できません。

設定できたかどうかは、サーバー側から次のコマンドで確認できます。

tailscale status --json --self --peers=false

JSON形式で自分の端末の詳細が出てきます。
設定前は Self の中に期限の日付が入っていました。

"KeyExpiry": "2027-02-21T00:40:54Z"

Disable key expiryを設定すると、この KeyExpiry の項目自体が出力から消えます。
「期限の日付が遠い未来になる」のではなく「項目ごと無くなる」ので、初見だと戸惑いますが、消えていれば成功です。

注意点としては、この設定を入れるのは置きっぱなしのサーバーだけにして、持ち歩くスマホやパソコンは有効期限を残しておくのがいいと思います。
期限は紛失・盗難のときに勝手にネットワークから追い出してくれる安全装置でもあるので、外に持ち出す端末では活きてきます。

まとめ

いかがでしたか。
今回は、自宅サーバーが「落ちたように見えた」障害の正体が、Tailscaleのノードキー期限切れだった話を紹介しました。

同じ症状が出たときの確認手順を振り返ると、

  1. サーバーに入って uptime で本体の生死と負荷を見る(LANなど別経路を確保しておく)
  2. tailscale status で「Logged out.」が出ていないか見る
  3. 出ていたら、表示されたリンクから再ログインする(リンク切れなら sudo tailscale up)
  4. 管理コンソールの「Disable key expiry」でサーバーだけ期限を無効化し、再発を防ぐ

という流れです。

Tailscale頼みの構成は便利な反面、Tailscaleが切れた日の見え方が「サーバー全滅」なので、この切り分けを知っているかどうかで慌て方が全然違います。
そして設定のおすすめを記事に書いたら、まず自分のサーバーに適用しましょう(自戒です)。

この記事が誰かの役に立てばうれしいです。

コメント

読み込んでいます…

この記事を書いた人

リットン

都内金融機関で経営企画とデータアナリストをしているアラサー。
文系の非エンジニアですが、独学で始めた Python と生成AIにすっかりはまりました。
プログラミング・サッカー・ミステリ紹介など、好きなことを好きに書いています。

プロフィールを見る →