セキュリティ

headscaleの使い方:Tailscale互換サーバーの構築手順と0.29系の変更点・採用判断

headscaleの使い方:Tailscale互換サーバーの構築手順と0.29系の変更点・採用判断

headscaleは、Tailscaleの制御サーバー(コーディネーションサーバー)を自社のサーバーで動かすためのオープンソース実装です。端末側は公式のTailscaleクライアントをそのまま使い、接続先だけを自前のheadscaleに向けます。2026年10月時点の安定版0.29系を前提に、debパッケージでの導入、config.yamlの初期設定、端末の登録、Grants形式のポリシー、旧版の手順が通らなくなった破壊的変更、そしてTailscaleの有料プランと比べた採用判断までをコマンド付きで扱います。

まとめ:headscaleは小規模tailnet向けの自前制御サーバーで業務採用は条件付き

headscaleを入れると、WireGuardの鍵交換やIPアドレスの割り当てを担う制御サーバーが自社管理になります。通信の中身は従来どおり端末間のWireGuardで暗号化され、制御サーバーを通りません。構築自体はdebパッケージ1つとsystemdで終わり、最初の端末がつながるまでの作業は短時間で済みます。

業務で採用してよいのは、端末数が数十台規模で、制御サーバーを外部SaaSに置けない理由があり、OSSの更新を追える担当者がいる場合です。IdPのグループで通信を制御したい、端末の状態検査や通信ログの保管が監査要件にある、といった場合はTailscaleの有料プランを選んでください。0.29系では登録コマンドとポリシーの解釈が変わったため、2025年以前の解説記事の手順は読み替えが必要です。

headscaleとは:Tailscaleの制御サーバーだけを自前で動かすOSS実装

headscaleのGitHubリポジトリは、プロジェクトの目的を「セルフホスター向けに、単一のtailnetを実装する」と明記しています。Tailscale社とは別のプロジェクトで、ライセンスはBSD 3-Clauseです。ただしメンテナーの1人はTailscale社に雇用されており、業務時間での貢献が認められている、とREADMEに記載があります。

制御サーバーの役割はWireGuard公開鍵の交換とIPアドレスの割り当て

Tailscaleは、端末同士がWireGuardで直接つながるメッシュ型のVPNです。Tailscale公式の仕組み解説によると、制御サーバーは各端末の公開鍵と接続先の情報を配るだけで、データ通信そのものは中継しません。直接つながらないNAT環境では、DERPと呼ばれる中継サーバーが暗号化されたままのパケットを運びます。

headscaleが置き換えるのは、この制御サーバーの部分だけです。端末のIPアドレス割り当て、ユーザーごとの境界、サブネットルートの公開もheadscaleが担当します。WireGuard自体の仕組みはWireGuardの仕組みとOpenVPNとの違いで、SaaS版Tailscaleの暗号化や料金はTailscaleの安全性と料金プランの解説で整理しています。

Tailscale SaaSとの機能差と未対応のFunnel・Serve・フローログ

headscaleの機能一覧では、MagicDNS、サブネットルーター、Exit Node、Tailscale SSH、ACLとGrants、OIDCによるログインに対応済みです。業務利用で差が出るのは、未対応として明記されている項目のほうです。Tailscale SSHのポリシーの書き方はTailscale SSHの設定手順で解説しています。

機能 headscale 0.29系 Tailscale SaaS
ACL・Grants・タグ 対応 対応
OIDCでの端末登録 対応(IdPのグループはACLで使えない) 対応
端末の状態検査(デバイスポスチャ) 未対応 Premium以上でMDM・EDR連携
ネットワークフローログ 未対応 Premium以上
Funnel・Serve 未対応 対応
Web管理画面 本体に無し(コミュニティ製を併用) 標準提供

ポリシー面の制限はポリシーの公式解説にあり、デバイスポスチャとIPセットは使えません。社外からのアクセスを端末の状態で絞る設計は、headscaleでは組めないと考えてください。

構築前に決めるサーバー要件:公開IP・443番ポート・TLS証明書とDB

headscaleはインターネットから到達できる場所に置く必要があります。社内LANの中に置くと、社外の端末が登録できません。

公開するポートはtcp443を軸に、Let’s EncryptとDERP利用時だけ追加

公式の要件ページは、公開IPを持つサーバーと、HTTPSの443番での待ち受けを求めています。HTTPや443番以外のポートでも動きますが、Tailscaleクライアントが443番を前提にする場面があるため、本番では443番が強く推奨されています。

  • tcp/443:公開。クライアントの接続先。組み込みDERPを有効にする場合も使う
  • tcp/80:公開。組み込みのLet’s EncryptでHTTP-01認証を使う場合だけ必要
  • udp/3478:公開。組み込みDERPのSTUN用
  • tcp/9090:非公開。メトリクスとデバッグ用

DERPはTailscale社の公開中継網をそのまま使えるため、最初は組み込みDERPを無効のまま始めてかまいません。中継も自社で持つ必要がある場合だけ、3478番を開けて有効にします。

SQLiteを推奨しPostgreSQLは保守モード、Docker運用は公式サポート外

公式FAQがデータベースとして推奨しているのはSQLiteです。PostgreSQLは引き続き動くものの「保守モード」の扱いで、開発とテストは主にSQLiteで行われています。DBの選択は性能にほとんど影響しない、とも書かれています。

コンテナイメージは配布されていますが、Dockerでの運用は公式サポートの対象外です。READMEはリバースプロキシとコンテナの利用を「サポートも推奨もしない」と明記しています。業務で使うなら、公式がサポートするdebパッケージかバイナリで、専用のVMに直接入れる構成を選んでください。

Debian・Ubuntuにdebパッケージでheadscale 0.29系を入れる手順

公式のインストール手順が対象とするのは、Ubuntu 22.04以降とDebian 12以降です。debパッケージには、実行ユーザー、既定の設定ファイル、systemdのユニットが含まれます。

debパッケージの取得からsystemdでの起動確認までのコマンド

版番号はGitHub Releasesの0.29.4(2026年9月23日公開)に合わせています。新しいパッチ版が出ていれば、変数の値だけ差し替えてください。

HEADSCALE_VERSION="0.29.4"
HEADSCALE_ARCH="amd64"
wget --output-document=headscale.deb \
  "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
sudo apt install ./headscale.deb

# 設定を書き換えてから起動する
sudo nano /etc/headscale/config.yaml
sudo systemctl enable --now headscale
sudo systemctl status headscale

# 外部から到達できるかを確認する
curl https://headscale.example.com/health

CLIはUNIXソケット/var/run/headscale/headscale.sock経由でサーバーと通信します。既定でこのソケットに触れられるのはheadscaleユーザーとrootだけなので、以降のコマンドはsudoを付けるか、作業ユーザーをheadscaleグループに加えて実行します。

config.yamlの初期設定で確認する公開URL・待受先・DNSドメイン

最初に書き換える設定項目は、公開URLのserver_url、待受先のlisten_addr、DNSドメインのbase_domainです。0.29.4の設定例は、そのままだと127.0.0.1:8080で待ち受ける開発用の値です。READMEも、使う版と同じタグの設定例を見るよう注意しています。mainブランチには未リリースの変更が入るためです。

server_url: https://headscale.example.com:443
listen_addr: 0.0.0.0:443

# Let's Encryptで証明書を自動取得する場合
tls_letsencrypt_hostname: "headscale.example.com"
tls_letsencrypt_challenge_type: HTTP-01

prefixes:
  v4: 100.64.0.0/10
  v6: fd7a:115c:a1e0::/48

dns:
  magic_dns: true
  base_domain: tailnet.example.internal   # server_urlと別のドメインにする

policy:
  mode: file
  path: /etc/headscale/policy.hujson

base_domainはserver_urlと同じドメインにできません。prefixesはTailscaleの標準範囲の中で使う必要があり、範囲外のアドレスを設定するとクライアントが予測できない壊れ方をする、と設定例のコメントが警告しています。端末の鍵の有効期限はnode.expiryが既定で0(期限なし)です。SaaS版は180日なので、合わせたい場合は180dを指定します。

ユーザー作成とノード登録:auth registerと事前認証キーで端末をつなぐ

headscaleでは、人が使う端末は「headscaleユーザー」に属し、サーバーなどはタグに属します。登録方法の公式解説は、この区別をTailscaleと同じ識別モデルとして説明しています。

Web認証とheadscale auth registerで個人の端末を承認する流れ

ノートPCのように人が操作する端末は、Web認証で登録します。端末側で--login-serverを指定すると、ブラウザに承認用のAuth IDが表示されます。

# サーバー側:ユーザーを作る
sudo headscale users create alice
sudo headscale users list

# 端末側:接続先を自前のheadscaleに向ける
sudo tailscale up --login-server https://headscale.example.com

# サーバー側:ブラウザに出たAuth IDで承認する
sudo headscale auth register --user alice --auth-id <AUTH_ID>
sudo headscale nodes list

WindowsやmacOS、iOS、Androidの公式アプリも接続できます。クライアント対応表によれば、headscaleが対応するのはTailscaleクライアントの直近10リリースです。0.29系では最小対応版がv1.80.0なので、古いクライアントを残した端末は先に更新してください。

事前認証キーとタグでサーバーを非対話で登録する自動化の書き方

ブラウザを開けないサーバーやCIの実行環境は、事前認証キーで登録します。キーは既定で1時間有効・1回限りです。タグ付きで登録する場合は、ポリシーのtagOwnersにタグを定義しておきます。

# 個人端末用:ユーザーIDを確認してからキーを作る
sudo headscale users list
sudo headscale preauthkeys create --user 1

# サーバー用:タグを付けたキーを作る(ユーザー指定は不要)
sudo headscale preauthkeys create --tags tag:server

# 登録される側
sudo tailscale up --login-server https://headscale.example.com --authkey <YOUR_AUTH_KEY>

タグ付きキーで登録した端末は、特別なユーザーtagged-devicesの所有になります。タグ付き端末は鍵の期限切れの対象外です。サーバーを個人ユーザーに属させると、その担当者の退職時に端末の扱いが宙に浮くため、サーバーは最初からタグで登録しておくほうが運用は楽になります。

Grants形式のポリシーで端末間の通信を絞るアクセス制御の書き方

ポリシーを読み込まない状態のheadscaleは、全端末間の通信を許可します。業務で使う前に、必ずポリシーファイルを用意してください。

policy.pathにHuJSONを置きsystemctl reloadで反映する手順

公式は、新しく書くならACLではなくGrantsを勧めています。ACLはTailscale側で新機能が追加されない旧形式の扱いです。書式はTailscaleのGrants解説と共通で、ファイルはコメントを書けるHuJSONです。

{
  "groups": {
    "group:dev": ["alice@", "bob@"]
  },
  "tagOwners": {
    "tag:server": ["alice@"]
  },
  "grants": [
    // 開発者はサーバーのSSHとHTTPSにだけ届く
    { "src": ["group:dev"], "dst": ["tag:server"], "ip": ["22", "443"] },
    // 各自の端末同士は自由に通信できる
    { "src": ["autogroup:member"], "dst": ["autogroup:self"], "ip": ["*"] }
  ]
}
# 書式を検査してから反映する
sudo headscale policy check --file /etc/headscale/policy.hujson
sudo systemctl reload headscale

ユーザー名の末尾の@は、ポリシー内でユーザーを指す書き方です。そのためheadscaleのユーザー名自体は@で終わらせてはいけません。"grants": []と空配列にすれば全遮断になります。0.29.0からはポリシー内のtestsブロックも評価され、到達性のテストに失敗した変更は適用前に拒否されます。この機能は現時点でベータです。

0.29.0のワイルドカード範囲とautogroup:danger-allの扱い

CHANGELOGによると、0.29.0からACLの*はtailnet内のアドレス範囲(100.64.0.0/10とfd7a:115c:a1e0::/48)だけを指します。以前は全IPアドレスを意味していました。Exit Node経由のインターネット通信や、サブネットルーター配下の社内ネットワークを*に頼って許可していた場合、更新後に通信が止まります。

全IPを送信元に指定したい場合はautogroup:danger-allを使います。名前のとおり、インターネット全体からの通信を受け入れる危険な設定であり、送信元にしか書けません。宛先に社内のセグメントを指定するなら、CIDRで明示してください。

古い解説記事のコマンドが動かない理由:0.29系の破壊的変更と更新手順

headscaleは1.0未満の版で、マイナー版ごとにCLIと設定の互換性が崩れます。検索上位の構築記事には0.28以前の手順で書かれたものも残っており、そのまま打つと警告やエラーになります。

nodes registerの非推奨化と事前認証キーのユーザーID指定

0.29系で読み替えが必要になった代表的な箇所を、旧手順と並べます。

項目 旧記事に多い書き方 0.29系での書き方
Web認証の承認 headscale nodes register headscale auth register
事前認証キーの発行 –user にユーザー名 –userにID、タグは–tags
ACLの * 全IPアドレス tailnet内の範囲のみ
proto:icmp ICMPv4とICMPv6 ICMPv4のみ(v6は別指定)
randomize_client_port サーバー設定に記述 randomizeClientPort

Web認証の承認では、headscale auth registerに--userと--auth-idを指定します。事前認証キーの--userにはユーザーIDを渡し、タグ付きでは--tagsを使う形式です。ICMPv6はproto:ipv6-icmpで指定します。randomizeClientPortの記述先はポリシーへ移動しています。

headscale nodes registerは当面動きますが、将来の版で削除される予定です。randomize_client_portを設定ファイルに残したままだと、0.29系のheadscaleは起動しません。ホスト名の重複時の付番も変わり、乱数の接尾辞からlaptop-1のような連番になったため、MagicDNS名が変わる端末が出ます。

マイナー版の飛ばし更新禁止とアップグレード前の設定・DBのバックアップ

公式のアップグレード手順は、0.26.0→0.27.1→0.28.0のように、マイナー版を1つずつ上げるよう求めています。0.29.0からはこれが強制され、0.27から0.29への直接更新や、前のマイナー版へのダウングレードはブロックされます。

sudo systemctl stop headscale
TIMESTAMP=$(date +%Y%m%d%H%M%S)
sudo cp -aR /etc/headscale /etc/headscale.backup-$TIMESTAMP
sudo cp -aR /var/lib/headscale /var/lib/headscale.backup-$TIMESTAMP
# 新しいdebを入れ、設定例との差分を確認してから起動する
sudo apt install ./headscale.deb
sudo systemctl start headscale

更新時にはDBのマイグレーションが走るため、バックアップを取らずに上げると戻せません。長く放置したheadscaleは、間のマイナー版を順に踏む必要があり、更新作業が数回分まとめて発生します。四半期に一度は版を確認する運用を最初から決めておきます。

headscaleを業務で採用する条件とTailscale有料プランを選ぶ場面

判断の軸は、制御サーバーを自社で持つ理由があるか、そしてその運用を誰が引き受けるかです。費用が安いという理由だけで選ぶと、運用の人件費で逆転します。

端末数と移動頻度で見るheadscaleの負荷特性と運用人員の目安

公式FAQは、headscaleを「エンタープライズ向けソフトウェアではない」と明言しています。端末の接続先が変わるたびに、全端末向けのネットワークマップを再計算する作りだからです。FAQでは、ほとんど動かないサーバー1,000台と、自宅とオフィスを行き来するノートPCやスマートフォン80台という2つの例を挙げています。そのうえで、端末が多く変化も多い環境では負荷が下がらなくなる、と説明しています。

目安として、社員のノートPCとスマートフォンで数十台、固定のサーバーを含めても100台前後までが無理のない範囲です。運用担当は最低1人を決め、版の更新・ポリシーの変更・障害時の切り分けを任せられる体制を前提にします。

Tailscale Standardの月額8ドルと自前運用コストの損益分岐

Tailscaleの料金ページでは、2026年10月3日時点でPersonalプランが6ユーザーまで0ドル、Standardが1ユーザーあたり月8ドル、Premiumが月18ドルです。社員20人でStandardを使うと月160ドルになります。

headscale側は、小さなVM1台の費用に加え、更新とポリシー変更で毎月数時間の作業が発生します。社内エンジニアの人件費を時給換算すると、20人規模ではSaaSのほうが安く収まる場合が多いはずです。headscaleが費用面で有利になるのは、ユーザー数が多いのに要件が単純な場合か、すでにLinuxサーバーを日常的に運用している部署が片手間で見られる場合に限られます。

headscaleを採用しない場面:IdPグループ制御・端末検査・通信ログが要件のとき

次の要件が1つでもあるなら、headscaleは選びません。OIDCのグループをACLに使えないので、Entra IDやGoogle Workspaceのグループ変更を通信制御へ自動で反映できません。端末の状態検査とネットワークフローログも未対応で、ISMSなどの監査でアクセス記録の提出を求められると説明がつきにくくなります。

逆に、閉域網の制御を外部SaaSに預けられない取引先要件がある、検証環境や工場の固定端末をつなぎたい、といった用途ではheadscaleが合います。headscaleとSaaS、従来型VPNのどれで組むかは、ネットワーク設計とサーバー構築を合わせて判断する必要があるため、両方を含めた検討が前提です。クラウドとネットワークのインフラ構築支援では、閉域網の方式選定から構築までを請け負っています。VPN全体の比較はVPNの種類と企業導入の判断基準が出発点になります。

headscaleの商用利用・端末接続・運用についてよくある質問

導入前の検討でよく出る疑問を、公式ドキュメントの記述に沿って回答します。

headscaleは無料で商用利用できますか?

できます。headscaleはBSD 3-Clauseライセンスで配布されており、著作権表示などの条件を守れば商用環境でも無償で使えます。ただし公式FAQのとおり、開発の主眼は個人や小規模組織で、性能や大規模運用は優先されていません。有償サポートの窓口も無いため、障害時は自社で切り分ける前提になります。

WindowsやiPhoneのTailscaleアプリからheadscaleに接続できますか?

接続できます。公式のクライアント対応表では、Linux・Windows・macOS・iOS・Android・tvOSのすべてが対応済みです。WindowsとApple製品は、アプリの設定で接続先のサーバーを変更する手順が必要で、headscaleの/windowsや/appleのページに案内が表示されます。0.29系ではクライアントがv1.80.0以上である必要があります。

headscaleにWeb管理画面はありますか?

本体には含まれていません。公式ドキュメントのWeb UI一覧には、Headplaneやheadscale-uiなど、コミュニティ製の管理画面が10件以上並んでいます。いずれもheadscaleの開発者による保守ではないため、業務で使う場合はheadscale本体の更新に追従しているかを確認してから選んでください。

headscaleを動かすサーバー自体をtailnetに参加させてもよいですか?

公式FAQでは非推奨です。headscaleと同じマシンでTailscaleクライアントを動かすと、サブネットルーター・中継・MagicDNSで問題が起きることがあり、動いたとしてもサポート対象外とされています。headscaleは専用のVMに置き、管理作業はSSHで行う構成にしておくのが安全です。

headscaleを使うとTailscale社に通信ログが送られますか?

既定では送られません。Tailscaleクライアントは本来、動作ログをTailscale社のログ基盤へ送りますが、headscaleは接続した端末にログ送信を無効にするよう指示します。設定項目はlogtail.enabledで、既定値はfalseです。接続前の起動時から止めたい場合は、端末側で環境変数TS_NO_LOGS_NO_SUPPORT=trueを設定します。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.09.05 コラム eKYCとは?方式の違いと2027年4月の犯収法改正で変わる本人確認要件
  2. 2026.10.03 テックブログ AWS Snowconeとは:サービス終了後の現状とDataSync・Greengrassへの移行手順【2026年版】
  3. 2026.10.03 テックブログ foliumとは:Pythonで地図を作る使い方・タイルの注意点・1.0候補版の変更点【2026年版】
  4. 2026.01.22 テックブログ Xアルゴリズム最新(2026年9月)|おすすめの仕組みと公開コードの重み一覧
  5. 2026.10.03 コラム ワークフローシステムの通知機能の設計:承認を止めないリマインド・催促と宛先の絞り方

RELATED POSTS 関連記事

目次