Tailscale DERP 中継サーバーの自前構築
国内で Tailscale 公式 DERP 中継サーバーを使用すると、遅延が高く接続が不安定になることがあります。公衆 IP を持つ VPS で DERP サーバーを自前構築すると、ノード間の通信遅延と打洞成功率が大幅に改善します。以下に Docker ベースの2つのデプロイ方法を紹介します:ドメインリバースプロキシモードと純粋 IP モード。
前置条件
- 公衆 IP を持つ VPS(低遅延の地域を推奨)
- Docker と Docker Compose がインストール済み
- ドメインと DNS 解析の設定済み(方案一が必要、方案二は不要)
- Nginx(または他のリバースプロキシ)で SSL を処理(方案一が必要、方案二は不要)
方案一:ドメイン展開 DERP(リバースプロキシモード)
Docker Compose 設定
docker-compose.yml を作成:
主要設定の説明
| 設定項目 | 説明 |
|---|---|
| network_mode: host | 必須。ホストマシンのネットワークスタックを使用、IPv6 と STUN をサポート |
| DERP_DOMAIN | あなたの DERP サーバードメイン |
| DERP_ADDR | 監視アドレスとポート |
| DERPVERIFYCLIENTS | true に設定してクライアント認証、悪用を防止 |
| tailscaled.sock | Tailscale ソケットをマウント、クライアント認証に使用 |
⚠️ 注意:
DERP_VERIFY_CLIENTS=trueの場合、サーバーで Tailscale クライアントを実行し、ソケットファイルをマウントする必要があります。
サービス起動
Nginx リバースプロキシ設定
DERP は WebSocket で通信するため、リバースプロキシを正しく設定する必要があります。
重要な設定の説明
- WebSocket ヘッダーの強制:
proxy_set_header Upgrade "websocket"とConnection "upgrade"は必須。そうでないと HTTP/2 で 426 エラーが発生 - HTTP/1.1 の使用:
proxy_http_version 1.1で WebSocket が正常動作 - バッファリング無効:
proxy_buffering offで中継データをキャッシュしない - 長タイムアウト:86400 秒(24 時間)で接続を切断しない
Nginx を再読み込み:
Tailscale ACL 設定
Tailscale Admin Console にログインし、Access Controls に入り、derpMap 設定を追加:
設定の説明
| 設定項目 | 説明 |
|---|---|
| OmitDefaultRegions | true に設定して公式 DERP を無効、自前のみ使用 |
| RegionID | カスタム地域 ID、900+ を推奨して競合回避 |
| RegionCode | 地域コード、例:hkg、sgp、tyo |
| HostName | DERP サーバードメイン |
| DERPPort | DERP ポート、Nginx リバースプロキシ後 443 |
| STUNPort | STUN ポート、3478 を維持 |
オプション:IP アドレス指定
DNS 解析を避けたい場合、直接 IP を指定:
方案二:ドメインなし展開 DERP(純粋 IP モード)
ドメインがない、または DNS と SSL 証明書を面倒にしたくない場合、IP アドレスで直接 DERP サーバーを展開できます。この方法は ip_derper イメージを使用し、自動で自己署名証明書を生成、Nginx リバースプロキシ不要です。
Docker Compose 設定
docker-compose.yml を作成:
主要設定の説明
| 設定項目 | 説明 |
|---|---|
| ip_derper イメージ | 公式 derper ベースの修正版、純粋 IP 実行をサポート、自己署名証明書自動生成 |
| DERP_ADDR | 監視ポート、ここでは 13477 |
| DERP_CERTS | 自己署名証明書保存パス(コンテナ内で自動生成) |
| DERPVERIFYCLIENTS | true に設定してクライアント認証、悪用を防止 |
| network_mode: host | ホストマシンのネットワークスタックを使用、IPv6 と STUN をサポート |
💡 ドメイン版との違い:ドメインなし版は Nginx リバースプロキシ不要、DERP サーバーが直接ポートを公開、自己署名 TLS 証明書を使用。
サービス起動
ACL 設定
Tailscale Admin Console にログインし、Access Controls に入り、derpMap 設定を追加:
核心設定の説明
| 設定項目 | 説明 |
|---|---|
| OmitDefaultRegions | false で自前と公式 DERP を同時使用;true で自前のみ |
| IPv4 / IPv6 | サーバー IP アドレスを直接指定、DNS 解析不要 |
| InsecureForTests | 核心設定:true で TLS 証明書検証をスキップ(自己署名証明書のため) |
| DERPPort | DERP_ADDR と一致のポート、ここ 13477 |
| STUNPort | STUN ポート、デフォルト 3478;-1 でこのノードの STUN を無効 |
⚠️ 注意:
InsecureForTestsは名前が「ForTests」を含みますが、Tailscale 公式の TLS 検証スキップ正式設定項目で、純粋 IP ドメインなしシーンでは必須です。
サーバー防火壁設定
いずれの展開方案でも、システム防火壁とクラウドプロバイダのセキュリティグループ(阿里雲、腾讯雲 など)で対応ポートを開放する必要があります:
| 方案 | ポート | プロトコル | 役割 |
|---|---|---|---|
| 方案一 (リバースプロキシ) | 443 | TCP | Nginx が受信する HTTPS/DERP トラフィック |
| 方案二 (純粋 IP) | 13477 | TCP | DERP Docker ネイティブ中継監視 |
| 全方案 | 3478 | UDP | STUN プロトコル、NAT 打洞貫通用 |
DERP サーバーの検証
DERP 状態の確認
任意の Tailscale クライアントで実行:
出力にカスタム DERP 地域とその遅延が表示されるはず:
接続方式の確認
relay "hkg" や類似内容が表示されれば、あなたの DERP 中継を使用中です。
よくある問題
Q: 状態に IPv6: No と表示
以下の点をチェック:
- サーバーに IPv6 アドレスがあるか
- DNS に AAAA レコードが設定されているか
- Docker が
network_mode: hostを使用しているか - 防火壁が IPv6 を開放しているか
Q: 426 Upgrade Required エラー
Nginx 設定の問題、以下を確認:
proxy_set_header Upgrade "websocket"が設定されているproxy_set_header Connection "upgrade"が設定されているproxy_http_version 1.1を使用
Q: クライアント認証失敗
以下を確認:
- サーバーで Tailscale クライアントを実行中
/var/run/tailscale/tailscaled.sockを正しくマウント- コンテナがそのソケットにアクセス権限がある
まとめ
Tailscale DERP サーバーの自前構築の主な役割:
- プライベートノードへのアクセス、遠隔通信遅延を低減。
- トラフィックが公式サーバーを経由しない。
- 国内クラウドサーバーなど特定地域にオプションでノード展開。
- IPv6 をサポート、P2P 打洞成功確率向上。
設定の重点:
- Docker の
network_modeをhostに設定。 - ドメインリバースプロキシモードでは、Nginx に WebSocket ヘッダー(
Upgrade "websocket"など)を追加、426 エラーを回避。 - 純粋 IP モードでは、ACL 設定に
"InsecureForTests": trueを必須。 - ACL の
OmitDefaultRegionsで公式 DERP ノードの使用を制御。