別のネットワークにあるマシンへ「今だけ」つなぎたい。やりたいことはそれだけなのに、現実には VPN を敷く、ファイアウォールにポートを開ける、アカウントを発行して権限を割り当てる、といった恒久的な仕掛けの用意を求められることがあります。数十分で終わる作業のために、運用し続ける前提の設定が増えていく構図です。
この摩擦は、設定変更が難しい環境ほど大きくなります。CI ジョブのコンテナ、使い捨てのサンドボックス、検証用に借りているだけの機材、あるいは管理者権限を持っていない端末。どれも「ルーティングテーブルや DNS を書き換える」という前提そのものが成り立ちません。
こうした場面に向けて Tailscale が 2026 年 8 月に OSS 化したのが tailcat です。Tailscale の通信部分(データプレーン)だけを取り出し、アカウントの発行も root 権限も要求せずに、2 台のマシン間へ WireGuard 暗号化トンネルを張る CLI と Go ライブラリです。GitHub 上の説明文も「like netcat, but over Tailscale's data plane, without Tailscale's control plane」と、netcat との対比で位置づけを示しています。
一方で、この領域には croc や magic-wormhole のようなファイル転送ツール、iroh のような P2P ライブラリ、そして Tailscale 本体という先行プロダクトが並んでいます。初見では「自分の用途ではどれを選ぶべきか」がすぐには見えません。
本記事では、公式ドキュメント(README・公式サイト・公式ブログ)と gh api で取得したリポジトリメタデータをもとに、tailcat の仕組み・できること・類似 OSS との違い・採用前に確認したい制約を整理します。動作検証は行っておらず、内容はすべて公開ドキュメントに基づく整理です。
tailcatとは|Tailscaleの「データプレーンだけ」を取り出したOSS
netcatに似ているが通信路がまるごと違う
tailcat は、Tailscale のオープンソース部品を組み替えて netcat のように振る舞わせたツールです。ただし通信が流れる経路は netcat と根本的に異なります。素の netcat が「相手に到達できる IP アドレスとポートがすでにある」ことを前提にするのに対し、tailcat は Tailscale のデータプレーン(内部的には magicsock と呼ばれる層)の上を通り、NAT 越えと暗号化を自前で引き受けます。
もう一つの核心が、コントロールプレーンを使わないことです。Tailscale 本体では、どのマシンがネットワークに属し、誰と通信してよいかを管理基盤(コントロールプレーン)が決めます。tailcat はその管理基盤を持ちません。接続に必要なメタデータは「tailcat アドレス」という短い文字列にまとまっており、それを Slack でもメールでも好きな手段(帯域外チャネル)で相手に渡す、という設計です。
使い方の骨格はシンプルで、片側が tailcat サーバ(リスナー)として起動して tailcat アドレスを出力し、もう片側がそのアドレスを指定して接続します。通信はエンドツーエンドで WireGuard 暗号化され、最初の接続は DERP サーバ経由でブートストラップしたあと、magicsock が NAT 越えを試みて可能なら直接の P2P UDP 接続へ昇格します。Tailscale アカウントも root / 管理者権限も不要で、マシンのルーティングテーブルや DNS 設定を変更しない、ユーザースペースのライブラリと CLI であることが README に明記されています(出典: tailscale/tailcat README)。
リポジトリの基本情報とリリース状況
採用検討時にまず確認したいメンテナンス状況を、調査時点(2026 年 9 月)の値で整理します。
項目 | 値(調査時点: 2026 年 9 月) |
|---|---|
リポジトリ |
|
開発元 | Tailscale |
主要言語 | Go |
ライセンス | BSD-3-Clause |
スター数 | 6,801 |
フォーク数 | 268 |
最終 push | 2026-09-05 |
リポジトリ属性 |
|
出典は gh api /repos/tailscale/tailcat の取得値です。ライセンスは BSD-3-Clause が設定済みで、商用利用の観点で確認しやすい状態にあります。
リリースは v0.1.0(2026-08-30)から v0.6.0(2026-09-04)まで、1 週間足らずで 6 バージョンが公開されています。開発が活発である一方、バージョン番号が示すとおりまだ v0.x 系であり、後述する「安定性の約束がない」という公式の宣言とも整合します。開発者アカウント個人ではなく Tailscale 社そのものが公開元である点は、メンテナンス継続性を見るうえでの材料になります。
なお tailcat は 2026 年 8 月に突然生まれたものではありません。README の History によれば、原型は 2023 年 9 月に「derpcat」として書かれ、当初は tailscale.com リポジトリのフォーク内に置かれて何度か bitrot したのち、フォークではなく通常の Go モジュールクライアントとしてリファクタされ、2026 年 8 月の TailscaleUp カンファレンスで OSS 化されました。3 年近く社内で揉まれてきたコードが公開されたという経緯です。
tailcatが埋める空白|アカウント・tailnet・root権限なしでつながる
tailcat がどの空白を埋める道具なのかは、公式紹介ページの位置づけを読むと明確になります。公式ページは tailcat を「アカウントや tailnet のセットアップなしに、異なるネットワーク上のマシン同士を暗号化接続でつなぐ CLI」と説明し、想定ユースケースとしてリモート開発・SSH、マシン間のファイル転送、CI/CD ジョブ、AI エージェントから特定マシンへの接続、ゲーム、サンドボックス環境を挙げています。
これらに共通するのは「恒久的な仕掛けを作りたくない」という条件です。CI ジョブは終われば消えますし、サンドボックスは使い捨てが前提です。AI エージェントに特殊なハードウェアを触らせたいだけの場面で、そのために ID 管理やアクセスポリシーを設計するのは重すぎます。公式ブログも開発動機として、信頼していないシステム間の短命な接続や、素早いファイル転送、一時的なポート転送のように、システム設定の変更が現実的でない、あるいはリスクが高い場面で有用だったと述べています。
そして公式ページは、Tailscale 本体との使い分けを明言しています。統治可能(governable)なネットワークが必要なら Tailscale を、手早い接続が必要なら tailcat を使う、という切り分けです。Tailscale は継続的で監査可能な接続性と ID 管理・ポリシーを提供する一方、tailcat はアカウント・ガバナンス・恒常的なネットワークアクセスを意図的に持たない設計になっています。開発元が自らこう線を引いているため、判断の出発点として使いやすい基準です。
技術面で効いてくるのが、権限の要求水準の低さです。tailcat はカーネルの TUN/TAP デバイスを使わず、ルーティングやDNS の設定も変更しません。そのため root / 管理者権限を必要とせず、権限のない端末やコンテナ内でもそのまま起動できます。「環境を汚さずに、今だけつなぐ」という要件に対して、この性質が直接効きます。
tailcatでできること|パイプ・ポート転送・SSH・ファイル転送・exit node
tailcat のサブコマンドは多岐にわたりますが、用途で束ねると「netcat 代替」「リモート作業」「ファイル授受とネットワーク到達」の 3 グループに整理できます。以下のコード引用はすべて README からの抜粋で、改変は加えていません。
netcat代替としての基本動作
引数なしで tailcat を起動すると、サーバとしてエフェメラルなアドレスを出力して待機します。
$ tailcat
# Selected bootstrap relay region 302, San Francisco
# 🐈 Server listening with new address: tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
(hangs, waiting...)
クライアント側は、そのアドレスを引数に渡して標準入力を流し込みます。
$ echo hello | tailcat tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
$
サーバ側の待機が解けて hello が出力される、という netcat そのままの体験になります。違いは、この 1 本のパイプが WireGuard で暗号化され、NAT の内側同士でもつながるという点です。
疎通の質を確かめたい場合は ping が使えます。pong ごとに DERP リレー経由か直接経路かを表示し、--until-direct を付けると直接経路が確立するまで(既定 10 秒の --timeout まで)試行し、確立しなければ非ゼロ終了します。
$ tailcat ping --until-direct <tc-addr>
pong in 42.1ms via DERP(sfo)
pong in 1.2ms via 203.0.113.7:41641
自動化に組み込む場合、この「直接経路になったかどうか」を終了コードで判定できる点は、スループットが要件に絡むときに効いてきます。
ポート転送とSSHでリモート作業をつなぐ
ローカルの TCP ポートをトンネル越しに提供するには serve を使います。tailcat serve 8080,8443 のようにポートを列挙する形式で、tailcat serve all という指定も可能です。逆に、サーバが提供しているポートを手元の通常の TCP ポートとして使いたい場合は forward を使います。ブラウザやデータベースクライアントのように SOCKS や標準入出力に対応していないツールから接続する場合の受け皿です。
$ tailcat serve 8080,3306
# 🐈 Server listening with new address: tcXXXXXXXXX
$ tailcat forward tcXXXXXXXXX 18080:8080 3306
forward のリスナーは既定で 127.0.0.1 にバインドされ、他マシンから接続させたい場合のみ --bind=0.0.0.0 を明示する設計になっています。ローカルポートに 0 を指定すると OS が空きポートを割り当て、各リスナーは待ち受け開始時に自分のアドレスを表示します。
SSH は 2 系統あります。ひとつは公開鍵認証を要求する ssh サービスで、鍵のソースとしてローカルの authorized_keys ファイル、OpenSSH 形式の公開鍵行、GitHub アカウント(user@github 形式で https://github.com/user.keys を起動前に一度取得)を指定できます。
$ tailcat serve --ssh-authorized-keys=~/.ssh/authorized_keys ssh
# 🐈 Server listening with new address: tcXXXXXXXXX
指定したソースはすべて存在し、取得に成功し、有効な公開鍵行を含んでいなければ起動に失敗します。command= や from= といった authorized_keys のオプションは、内蔵サーバが実装していないため拒否されます。また --ssh-authorized-keys なしで tailcat serve ssh を実行することもできません。
もうひとつが認証なしの no-auth-ssh サービスで、トンネル自体をクライアントの身元証明として扱います。これは後述する鍵とアドレスの扱いに直結する、最も注意が必要な機能です。
接続ごとにコマンドを起動する exec サービス(inetd 相当)もあります。接続がそのままコマンドの標準入出力になり、コマンドにはピアのノード鍵が $TAILCAT_PEER_KEY、ピアの IP:ポートが $TAILCAT_REMOTE_ADDR として渡されます。
ファイルの受け渡しとネットワーク到達(exit node・SOCKS5)
ファイルを受け取る側は recv でドロップボックスを立て、表示された tailcat アドレスを共有します。送る側は cp を使います。
$ tailcat recv ~/inbox
# 🐈 Server listening with new address: tcXXXXXXXXX
$ tailcat cp report.pdf tcXXXXXXXXX:
tailcat cp はシステムの scp を tailcat 経由の接続で動かすため、通常どおりの進捗表示や -r によるディレクトリ転送が使えます。ドロップボックスは書き込み専用で、送信側はディレクトリの一覧取得・読み出し・既存ファイルへの変更ができません。
逆にファイルを提供する場合は tailcat serve files(カレントディレクトリを読み取り専用)や tailcat serve --files=/pub:rw files(指定ディレクトリを読み書き可)を使い、クライアントは tailcat ls -l <tc-addr> や tailcat cp <tc-addr>:report.pdf . で操作します。サーバは Go の os.Root によってすべてのパスを公開ディレクトリ内に閉じ込めるため、.. でもシンボリックリンクでも外へ出られません。tailcat ls は SFTP をネイティブに話すため、OpenSSH が入っていない環境でも動作します。
運用面で見落としやすいのが、転送が圧縮されないことです。README は、SFTP プロトコル自体に圧縮がなく、ここで使われている SSH トランスポートにも圧縮がない(Go の SSH スタックが省いており、トランスポート圧縮にはセキュリティ問題の歴史があって TLS も廃止した)と説明し、必要なら送る前に圧縮するよう案内しています。大容量データを頻繁に流す用途では、この点を前提に見積もる必要があります。
ネットワーク到達の手段も 2 つあります。ひとつは SOCKS5 プロキシで、tailcat socks <tc-addr> curl http://server.tailcat:8081/ のようにトンネル経由でコマンドを実行できます。もうひとつが exit node モード(tailcat serve exit-node)で、クライアントからサーバ側のネットワークへ到達できるようになります。forward と組み合わせれば、exit node の先にある別ホストのポートを手元のローカルポートに割り当てることもできます。
アドレス自体を扱うコマンドとして parse と resolve も用意されています。parse は接続せずにアドレスの中身(サーバの WireGuard 公開鍵と DERP 情報)を JSON で表示し、resolve は DERP リージョンを ID で参照している短いアドレスを、DERP サーバ情報を埋め込んだ自己完結型の長いアドレスへ変換します。後者はクライアントが DERP マップを取りに行く往復を省けるため、接続開始を速くしたい場合の選択肢になります。
配布形態
導入経路は幅広く用意されています。Releases ページには静的リンクされた Linux バイナリ(tar.gz)と、amd64 / arm64 / armv7 向けの Debian(.deb)・RPM(.rpm)パッケージ、amd64 / arm64 向けの Windows バイナリ(zip)が置かれています。加えてコンテナイメージ(ghcr.io/tailscale/tailcat)、Homebrew(brew install tailcat)、Nix(nixpkgs / flakes)、Arch AUR(tailcat / tailcat-bin)、conda-forge(pixi)が用意されており、Go ツールチェーンがあればソースからも導入できます。
$ go install github.com/tailscale/tailcat/cmd/tailcat@latest
なお公式バイナリは、使わない Tailscale 機能を落とすビルドタグのリスト(リポジトリ内の build-tags.txt)を使ってビルドされており、README はこれによりサイズが約 16% 小さくなると説明しています。パッケージャが同じ条件でビルドできるよう、このリストは CI テストで正確性が保たれています。
ライブラリとして組み込む場合は github.com/tailscale/tailcat を import します。API の詳細は pkg.go.dev のパッケージドキュメントで確認できます。README の例では、tailcat.Server はゼロ値のままでも新しいエフェメラル鍵・既定 DERP マップの最寄りリージョン・log.Printf ロギングという既定値で動き、OnTCP ハンドラを設定して Start() を呼び、TailcatAddr() でアドレスを取得する流れが示されています。クライアント側も tailcat.NewClient(tailcat.Addr(...)) と DialTCPPort で完結します。UDP は OnUDP / DialUDPPort を使い、ペイロードは tailcat.MaxUDPPayload(1232 バイト)以下に収めることが推奨され、非アクティブなサーバ側 UDP フローは tailcat.DefaultUDPIdleTimeout(2 分)で閉じられます。
tailcatの仕組み|WireGuard・magicsock・netstack・DERPの4要素
tailcatアドレスに何が入っているか
tailcat サーバを識別するのが「tailcat アドレス」です。tc というプレフィックスに、base64 エンコードされた CBOR が続く形式で、中身は次の 4 つです。
- サーバの WireGuard 公開鍵(Curve25519、32 バイト)
- 経路探索(path-discovery)用の別の公開鍵(Curve25519、32 バイト)
- 既定で含まれる独立した WireGuard 事前共有鍵(256 ビットの乱数)。ピアの公開鍵を観測できる DERP 運用者がトンネルに参加することを防ぎ、記録済みトラフィックに対するポスト量子的な保護を与える
- DERP 情報。既定の DERP サーバ群のいずれかを指す小さな整数、または DERP サーバのメタデータ一式
リージョン ID を整数で持つ通常のアドレスは約 140 バイトです。DERP ノードの詳細を埋め込むと長くなりますが、DERP マップを取りに行かずに済む自己完結型になります。
ここで押さえておきたいのは、既定のアドレスが事前共有鍵を含むため「秘密の資格情報(bearer capability)」だという点です。この性質は後述の鍵とアドレスの扱いに直結します。
4つの構成要素と役割分担
tailcat は Tailscale クライアントのネットワーク部品を、コントロールプレーンなしで再利用しています。README が挙げる 4 要素と役割は次のとおりです。
構成要素 | 役割 |
|---|---|
WireGuard(ユーザースペース実装) | トンネル通信の暗号化。カーネルの TUN/TAP を使わず、経路や DNS 設定も変更しないため root が不要 |
magicsock | 直接 UDP と DERP リレーへの通信を多重化する Tailscale のトランスポート層。STUN によるエンドポイント発見と、NAT 越えのための UDP ホールパンチングを担当 |
Netstack(gVisor) | プロセス内で TCP 接続を終端するユーザースペース TCP/IP スタック。OS 側のネットワーク設定なしに着信を受け、発信もできる理由 |
DERP リレー | Tailscale の暗号化リレープロトコル。ランデブーチャネルとして、また直接接続できない場合のフォールバック経路として機能 |
「アカウントなしで NAT 越えができる」という挙動は、この 4 要素の組み合わせから来ています。特別な発明というより、Tailscale が製品として使っている部品から管理基盤を外し、接続に必要な情報を 1 本の文字列に押し込んだ構成だと理解すると見通しが良くなります。同時に、DERP という外部依存がブートストラップに必ず絡むことも、この図から読み取れます。
接続確立の流れ(DERP経由から直接P2Pへの昇格まで)
README の Connection flow は 6 段階で説明されています。
- サーバ起動: WireGuard 鍵ペアと(既定では)事前共有鍵を生成または読み込み、DERP リレーへ接続し、tailcat アドレスを標準エラー出力へ表示してクライアントを待つ
- クライアントによるアドレス解析: サーバの公開鍵・経路探索鍵・事前共有鍵・DERP リージョンを読み取り、自身のエフェメラル鍵ペアを生成して同じ DERP リレーへ接続する。経路探索鍵は平文の disco フレームに現れても WireGuard 公開鍵を露出させない役割を持つ
- ディスカバリのハンドシェイク: クライアントが DERP 越しに「Meow」という ping メッセージを送る。サーバはクライアントを WireGuard のピアリストとネットワークマップに追加し、WireGuard エンジンを再構成して「Meowed」で応答する
- WireGuard トンネル確立: 双方がピアとして構成され、事前共有鍵がある場合はそれを用いて WireGuard ハンドシェイクが進む(初期は DERP 経由)。完了するとトンネルが立ち上がる
- NAT 越え: 並行して双方が UDP エンドポイント(STUN で学習した公開 IP:ポートとローカルインターフェースのアドレス)を DERP 経由の disco メッセージで広告し、ホールパンチングを試みる。成功すれば直接の P2P 経路へ昇格し、失敗しても DERP がフォールバックとして機能して接続自体は成立する(ただし公開ホスト型 DERP を使っている場合はレート制限付きのスループットになる)
- データ転送: クライアントがトンネル越しにサーバの TCP ポートへ接続し、双方の gVisor TCP/IP スタックが接続処理を行う。サーバ側ではポートに応じたハンドラ(localhost への転送、標準出力へのパイプ、SSH セッションなど)へ振り分けられる
なお各ピアは WireGuard 公開鍵から決定論的な IPv6 アドレスを導出していますが、README はこれを「エンドユーザーに露出しない実装詳細であり、変わる可能性がある」と明記しています。この挙動に依存した実装を組まないほうが安全です。
鍵とアドレスの扱い|tailcatアドレスは「秘密の資格情報」
エフェメラル鍵と保存鍵の使い分け
tailcat アドレスには WireGuard 公開鍵と独立した事前共有鍵が入っているため、どの鍵材料を保存するかがそのまま「誰が自分に到達できるか」を決めます。README は 2 つのモードを説明しています。
エフェメラル鍵(既定)では、サーバを起動するたびにメモリ上で新しい鍵が生成され、誰も見たことのないアドレスが表示されます。プロセスが終了すると鍵は破棄され、そのアドレスは永久に無効になります。README はこれを安全な既定と位置づけており、共有したアドレスがその 1 回の起動だけを指すという性質が根拠です。
保存鍵は tailcat genkey でディスクに保存する方式で、再起動をまたいでアドレスが安定します。裏返しとして、過去にそのアドレスを共有した相手は、その鍵を使う将来のサーバにも接続できます。この範囲を絞りたい場合は tailcat serve --allow でクライアントを制限します。
$ tailcat genkey --key=default --region=nyc
# prints the tailcat address; key saved to ~/.config/tailcat/keys/default.private.json
# later; the key named "default" is used automatically once it exists:
$ tailcat serve 8080
# 🐈 Server listening with saved key "default": tcXXXXXXXXX
# ... unless you force a one-off ephemeral key:
$ tailcat serve --key=new 8080
# 🐈 Server listening with new address: tcXXXXXXXXX
ここで注意したいのが default という特別な鍵名です。この名前の鍵がいったん存在すると、引数なしの tailcat はエフェメラル鍵を生成せず、黙って保存鍵を使います。どちらが使われたかは起動時の表示行(with new address か with saved key "default" か)で判別する設計です。エフェメラル鍵を強制したい場合は --key=new、別の保存鍵を使う場合は --key=<name> を指定し、保存済みの既定鍵を消したい場合は tailcat genkey --delete --key=default を使います。保存鍵の一覧は tailcat genkey --list で確認できます。
事前共有鍵(PSK)は既定で有効で、README は強く推奨しています。v0.5.0 以前のクライアントとの互換のために --psk=false を指定するとアドレスは短くなりますが、ポスト量子的な保護と、ピアの公開鍵を観測できる公開 DERP 運用者からの保護を失います。短さのためにこれを外す判断は、影響範囲を理解したうえで行う必要があります。
アドレスを公開してよい場面・いけない場面
tailcat アドレスは DNS の TXT レコードとして公開し、名前で参照することもできます。TXT レコードに tailcat=tc... を置けば、tailcat example.com 8080 や tailcat ssh example.com のように、CLI が tailcat アドレスを受け取るあらゆる場所で DNS 名を使えます。
ただし README はここに強い警告を置いています。tailcat アドレスは通常は秘密であり、それを知っていることがクライアントの接続資格そのものです。一方 DNS TXT レコードは秘密ではなく、公開されていて世界中から読め、常時スキャンの対象になっています。DNS への公開は、その資格をインターネット全体に配ることに等しくなります。したがって公開する場合、サーバ側は「アドレスを知っていること」以外の方法でクライアントを認証しなければなりません。具体的には、トンネル層で tailcat serve --allow=... によりクライアントのノード鍵を限定するか、SSH であれば tailcat serve --ssh-authorized-keys=... ssh で公開鍵を要求するか、その両方です。
特に強い警告が向けられているのが no-auth-ssh です。この構成ではアドレスがそのまま資格情報になり、それを知った者はサーバを実行しているユーザーとしてシェルを取得できます。README は、共有はプライベートなチャネルに限り、DNS TXT レコードを含むいかなる公開の場にも掲載してはならないと明記しています。DNS 名で到達できる SSH サーバが欲しいのであれば、クライアント認証を必須にする構成を選ぶ必要があります。
この種の設定ミスに対する安全網も用意されています。tailcat ssh は DNS 名の宛先へ接続する前に、新しく生成したクライアント鍵と SSH 資格情報なしの状態で「よそ者としてログインできるか」をプローブします。もしログインできてしまう場合、TXT レコードを読んだ誰もが同じことをできる状態だと判断し、tailcat は接続を拒否して理由を伝えます。このチェックは --skip-dns-safety-check で無効化できますが、意図的に公開サーバを運用している場合を除いて、外す理由は多くありません。
DNS 公開を伴う構成では、DERP リージョンの固定も併せて検討することになります。tailcat genkey --fixed-region は genkey の時点で最寄りの DERP リージョンを確定し、その ID を tailcat アドレスと鍵ファイルの双方に焼き込むため、サーバを再起動しても同じリージョンに束縛され、公開済みのアドレスが有効なまま保たれます。既定の --region=auto は「起動時に選ぶ」という意味になるため、単発利用には向く一方、DNS に載せるアドレスには固定リージョンのほうが適します。
類似OSSとの違い|croc・magic-wormhole・Tailscale本体と比べる
tailcat の立ち位置は、隣接する OSS と並べると判断しやすくなります。以下はいずれも調査時点(2026 年 9 月)に gh api で取得した値です。
リポジトリ | 言語 / スター / ライセンス | tailcat との差分 |
|---|---|---|
| Go / 40,280 / MIT | ファイル・データの受け渡しに特化。共有単位は人が読める合言葉(PAKE)で、公開鍵を含むアドレスではない。SSH・ポート転送・exit node のような汎用トンネル機能は持たない |
| Python / 22,919 / MIT | croc と同様にファイル受け渡し用途。Python 実装のため単一バイナリ配布ではなく、Go の単一バイナリ+ライブラリという tailcat とは配布・組み込みの前提が異なる |
| Rust / 12,467 / Apache-2.0 | アプリに QUIC と NAT 越えを足すライブラリ。トランスポートが QUIC で(tailcat は WireGuard + gVisor netstack)、CLI 単体で完結する道具ではなく組み込みが前提 |
| Go / 36,259 / BSD-3-Clause | tailcat と同じデータプレーンを持つが、アカウント・ID 連携・アクセスポリシーというコントロールプレーンを備えた恒常的なオーバーレイネットワーク |
| Go / 43,668 / BSD-3-Clause | Tailscale のコントロールサーバを自前運用する実装。tailcat が「コントロールプレーンを捨てる」方向なのに対し、こちらは「自分で持つ」方向で目的が正反対 |
比較を整理すると、判断に効く軸は 4 つに集約できます。
- 目的の粒度: 汎用トンネル(tailcat)か、ファイル転送に特化(croc / magic-wormhole)か、アプリ組み込み用ライブラリ(iroh)か、恒常的なネットワーク(Tailscale / headscale)か
- 共有する資格情報の形: tailcat アドレス(公開鍵 + 事前共有鍵 + DERP 情報)か、人が読める合言葉か、公開鍵によるダイヤルか、アカウントとポリシーか
- コントロールプレーンの有無: tailcat・croc・magic-wormhole・iroh は持たず(リレーやランデブーサーバは存在する)、Tailscale と headscale は持つ
- 想定する接続の寿命: tailcat は既定がエフェメラル鍵で短命前提、croc / magic-wormhole は単発の転送、iroh はアプリの寿命に従い、Tailscale は恒常的
この軸に沿えば、選び分けはおおむね次のようになります。ファイルを 1 回渡したいだけなら croc や magic-wormhole のほうが手順が短く、合言葉を口頭で伝えられる分だけ運用も軽くなります(croc は単一の Go バイナリで再開機能を持ち、magic-wormhole は Python 実装でセキュリティレビューの蓄積が厚い、と語られることが多い領域です。出典: Hacker News のスレッド、Magic Wormhole - Wikipedia)。自作アプリケーションに P2P 接続を組み込みたいのであれば iroh のようなライブラリが素直です。恒常的で監査可能なネットワークが必要なら Tailscale 本体、あるいは自前でコントロールサーバを持つ headscale が対象になります。
そのうえで tailcat が独自に埋めるのは、「ファイル転送だけでは足りないが、ネットワークを作るほどでもない」帯域です。SSH・ポート転送・exit node・SOCKS5・ファイル授受を 1 本の暗号化トンネルの上でまとめて扱えて、なおかつアカウントもコントロールプレーンも増やさない、という組み合わせは他の選択肢では代替しにくいところです。なお、いずれのツールも優劣ではなく設計目的が異なるため、比較は用途との相性で読むのが適切です。
採用前に確認したい3つの制約
tailcat を検討する際、公式が自ら明示している制約が 3 つあります。いずれも採用可否の判断に直結します。
1. API・CLI の安定性が約束されていない
README の Stability セクションは、tailcat が無料で使える一方で API や CLI の安定性を約束しないと明言しています。Go API、CLI のフラグと出力、そしてワイヤフォーマットのいずれもが変わりうる、という宣言です。前述のとおりリリースは v0.1.0 から v0.6.0 まで 1 週間足らずで進んでおり、この宣言と実際の開発ペースは整合しています。自動化スクリプトや CI パイプラインに組み込むのであれば、バージョンを固定し、更新時に出力フォーマットの変化を検証する運用が前提になります。Go ライブラリとして組み込む場合も同様で、破壊的変更への追従コストを見込んでおく必要があります。
2. 公開 DERP リレーに SLA がなく、アクセスを取り消されうる
同じく Stability セクションは、公開されているレート制限付きの tailcat DERP リレーについて、稼働率 SLA もスループット目標もなく、理由を問わずいつでもアクセスを取り消しうると述べています。すべてがベストエフォート提供であり、契約関係がない以上それ以上の保証はない、という位置づけです。
継続的な利用や一定の帯域が必要な場合、選択肢は自前 DERP リレーの運用になります。README は Tailscale のリレーを使う必然性はないとしたうえで、自前 DERP サーバの運用手順を案内しています(derper は Let's Encrypt で証明書を取得できるため、TLS 証明書付きのホスト名が用意できれば運用できます)。リレーのホスト名をリージョンとして指定して鍵を生成すれば、そのホスト名がアドレスに埋め込まれるため、クライアント側は追加フラグなしで接続でき、Tailscale の DERP マップサーバにもリレーにも接続しません。複数台を運用する場合は、自前の DERP マップ JSON を用意して --derpmap-url で双方に指す構成が示されています。
なお、NAT 越えに成功して直接 P2P 経路へ昇格すればデータは DERP を経由しませんが、ブートストラップとランデブーには DERP が必ず関与します。「DERP に一切依存しない構成」は存在しないため、この依存を自前に寄せるかどうかが運用設計の分岐点になります。
3. ライセンスは緩いが、サポートは別枠
ライセンスは BSD-3-Clause で、商用利用・改変・再配布の観点では扱いやすい部類です。一方で、前述のとおり運用の保証は付きません。README は、自前で運用・サポートしたくない場合や支援が必要な場合の窓口として Tailscale のセールスを案内しており、専用 DERP リレーやサポートは契約の話として切り分けられています。OSS としての利用と、業務要件としての可用性確保は別のレイヤーで検討する必要があります。
あわせて、実験的な位置づけの機能にも触れておきます。tailcat を WebAssembly にビルドしたブラウザデモが公開されており、CLI と相互運用しながらファイルやテキストを送受信できますが、ブラウザ側の通信は DERP 経由のみで、WebRTC 対応(Issue #4)が入るまで直接接続は行われません。ブラウザからの利用を前提に据える計画であれば、この制約を織り込む必要があります。
まとめ|tailcatを選ぶ判断基準
本記事では、公式ドキュメント(README・公式サイト・公式ブログ)と gh api で取得したリポジトリメタデータの範囲で、tailcat を次の観点から整理しました。
- 位置づけ: Tailscale のデータプレーン(WireGuard・magicsock・gVisor netstack・DERP)だけを取り出し、コントロールプレーンなしで動く CLI と Go ライブラリ。アカウントも root 権限も不要で、ルーティングテーブルや DNS を変更しない
- できること: 標準入出力のパイプ、ポート公開と転送、公開鍵認証 SSH と認証なし SSH、接続ごとのコマンド実行、ファイルの受信・提供、exit node、SOCKS5 まで、汎用トンネルとして一通りをカバーする
- 類似 OSS との違い: ファイル転送特化(croc / magic-wormhole)、組み込みライブラリ(iroh)、恒常ネットワーク(Tailscale / headscale)のいずれとも目的の粒度が異なり、「短命な汎用トンネル」という帯域を埋める
- 制約: API・CLI の安定性は約束されておらず、公開 DERP リレーに SLA はない。tailcat アドレスは秘密の資格情報であり、DNS 公開時は
--allowや--ssh-authorized-keysによるクライアント認証が必須
採用判断の目安としては、「接続が短命であること」「一時的な用途であること」「アカウントを増やしたくないこと」「対象マシンの設定を変えたくない(変えられない)こと」の 4 条件がそろう場面で検討する価値が高い道具です。逆に、恒常的な接続性・監査ログ・アクセスポリシーといったガバナンス要件が絡む場合は、開発元自身が示すとおり Tailscale 本体(あるいは自前でコントロールサーバを持つ headscale)側に寄せる判断になります。
メンテナンス状況の観点では、開発元が Tailscale 社であること、調査時点でリポジトリが archived=false / fork=false / disabled=false の稼働状態にあること、最終 push が 2026-09-05 と直近であることから、当面の継続性は見込める状態です。一方でバージョンは v0.x 系であり、破壊的変更への追従コストを織り込んだうえで、まずは影響範囲の小さい用途から検証していくのが現実的な進め方になります。
関連情報
開発環境の接続基盤や技術選定についてのご相談を検討中の方は、お問い合わせフォーム からご相談ください。要件の整理段階からご相談いただけます。



