自宅でTailscale DERPリレーサーバーを構築する
国内でTailscale公式のDERPリレーサーバーを使用すると、レイテンシが高く、接続が不安定になりがちです。パブリックIPを持つVPS上にDERPサーバーを構築することで、ノード間の通信レイテンシとNAT越えの成功率を大幅に改善できます。ここでは、Dockerベースの2つのデプロイ方法を紹介します。ドメインによるリバースプロキシモードと、IPのみのモードです。
前提条件
- パブリックIPを持つVPS(レイテンシの低いリージョンを推奨)
- DockerとDocker Composeがインストール済みであること
- ドメインとDNSの設定(方法1で必要、方法2では不要)
- Nginx(または他のリバースプロキシ)でSSLを処理(方法1で必要、方法2では不要)
方法1:ドメインでDERPをデプロイ(リバースプロキシモード)
Docker Composeの設定
docker-compose.ymlを作成します:
services:
derper:
container_name: derper
image: fredliang/derper
restart: always
network_mode: host # ホストネットワークを直接使用、IPv6対応
environment:
- DERP_DOMAIN=derp.example.com
- DERP_ADDR=:13477
- DERP_HTTP_PORT=13478
- DERP_VERIFY_CLIENTS=true
volumes:
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
主要な設定項目の説明
| 設定項目 | 説明 |
|---|---|
| network_mode: host | 必須。ホストのネットワークスタックを使用し、IPv6とSTUNをサポート |
| DERP_DOMAIN | DERPサーバーのドメイン名 |
| DERP_ADDR | リッスンするアドレスとポート |
| DERPVERIFYCLIENTS | trueに設定してクライアント認証を有効にし、不正利用を防止 |
| tailscaled.sock | Tailscaleソケットをマウントし、クライアント認証に使用 |
⚠️ 注意:
DERP_VERIFY_CLIENTS=trueを設定するには、サーバー上でTailscaleクライアントが実行されており、そのソケットファイルがマウントされている必要があります。
サービスの起動
docker compose up -d
Nginxリバースプロキシの設定
DERPはWebSocketを使用して通信するため、リバースプロキシを正しく設定する必要があります。
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name derp.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location ^~ / {
proxy_pass http://127.0.0.1:13477;
# 重要:WebSocketヘッダーを強制的に送信
# HTTP/2でヘッダーが失われ426エラーが発生する問題を解決
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "upgrade";
# 必須:プロトコルバージョンとキャッシュの無効化
proxy_http_version 1.1;
proxy_buffering off;
# 基本ヘッダー
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
# タイムアウト(長期間の接続を維持)
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
# セキュリティヘッダー
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
}
}
重要な設定の説明
- 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をリロード:
sudo nginx -t && sudo nginx -s reload
Tailscale ACLの設定
Tailscale Admin Consoleにログインし、Access Controlsに移動して、derpMap設定を追加します:
{
// カスタムDERPサーバー
"derpMap": {
// カスタムDERPのみを使用し、公式DERPを無効にする
"OmitDefaultRegions": true,
"Regions": {
"900": {
"RegionID": 900,
"RegionCode": "hk",
"RegionName": "DMIT Cloud Hong Kong",
"Nodes": [
{
"Name": "hk1",
"RegionID": 900,
"HostName": "derp.example.com",
"DERPPort": 443,
"STUNPort": 3478
}
]
}
}
},
"acls": [
{
"action": "accept",
"src": ["*"],
"dst": ["*:*"]
}
]
}
設定項目の説明
| 設定項目 | 説明 |
|---|---|
| OmitDefaultRegions | trueに設定すると公式DERPを無効にし、自前のものだけを使用 |
| RegionID | カスタムリージョンID。競合を避けるため900以上を推奨 |
| RegionCode | リージョンコード。例:hkg、sgp、tyo |
| HostName | DERPサーバーのドメイン名 |
| DERPPort | DERPポート。Nginxリバースプロキシ経由の場合は443 |
| STUNPort | STUNポート。3478のまま |
オプション:IPアドレスの指定
DNS解決を避けたい場合は、直接IPを指定できます:
{
"Name": "hk1",
"RegionID": 900,
"HostName": "derp.example.com",
"IPv4": "[IP_ADDRESS]",
"IPv6": "[IP_ADDRESS]",
"DERPPort": 443,
"STUNPort": 3478
}
方法2:ドメインなしでDERPをデプロイ(IPのみモード)
ドメインがなかったり、DNSやSSL証明書の手間をかけたくない場合は、IPアドレスだけでDERPサーバーをデプロイできます。この方法ではip_derperイメージを使用し、自己署名証明書を自動生成するため、Nginxリバースプロキシは不要です。
Docker Composeの設定
docker-compose.ymlを作成します:
services:
derper:
container_name: derper
image: ghcr.io/yangchuansheng/ip_derper:latest
restart: always
network_mode: host # ホストネットワークを直接使用、IPv6対応
environment:
- DERP_HOST=あなたのサーバーIP
- DERP_ADDR=:13477
- DERP_HTTP_PORT=13478
- DERP_CERTS=/app/certs
- DERP_STUN=true
- DERP_VERIFY_CLIENTS=true
volumes:
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock:ro
- ./certs:/app/certs
主要な設定項目の説明
| 設定項目 | 説明 |
|---|---|
| ip_derperイメージ | 公式derperをベースに改造。IPのみでの実行をサポートし、自己署名証明書を自動生成 |
| DERP_ADDR | リッスンポート。ここでは13477を使用 |
| DERP_CERTS | 自己署名証明書の保存パス(コンテナ内で自動生成) |
| DERPVERIFYCLIENTS | trueに設定してクライアント認証を有効にし、不正利用を防止 |
| network_mode: host | ホストのネットワークスタックを使用し、IPv6とSTUNをサポート |
💡 ドメインバージョンとの違い:ドメインなしバージョンではNginxリバースプロキシの設定が不要で、DERPサーバーが直接ポートを公開し、自己署名TLS証明書を使用します。
サービスの起動
docker compose up -d
ACLの設定
Tailscale Admin Consoleにログインし、Access Controlsに移動して、derpMap設定を追加します:
{
// カスタムDERPサーバー
"derpMap": {
// カスタムDERPのみを使用するか、公式DERPも併用するか。trueは自ノードのみ、falseは自ノード+公式ノード
"OmitDefaultRegions": false,
"Regions": {
"900": {
"RegionID": 900,
"RegionCode": "chn",
"RegionName": "China",
"Nodes": [
{
"Name": "server",
"RegionID": 900,
"IPv4": "[IP_ADDRESS]",
"IPv6": "[IP_ADDRESS]",
"InsecureForTests": true,
"DERPPort": 13477,
"STUNPort": 3478
}
]
}
}
}
}
主要な設定項目の説明
| 設定項目 | 説明 |
|---|---|
| OmitDefaultRegions | falseは自前と公式DERPの両方を使用、trueは自前のみ |
| IPv4 / IPv6 | サーバーのIPアドレスを直接指定。DNS解決は行わない |
| InsecureForTests | 重要:trueに設定するとTLS証明書の検証をスキップ(自己署名証明書を使用するため) |
| DERPPort | DERP_ADDRで設定したポートと一致。ここでは13477 |
| STUNPort | STUNポート。デフォルトは3478。-1に設定するとそのノードのSTUNを無効化 |
⚠️ 注意:
InsecureForTestsという名前ですが、これはTailscale公式が提供するTLS検証をスキップするための正式な設定項目であり、IPのみでドメインがないシナリオでは必須です。
サーバーファイアウォールの設定
どちらのデプロイ方法を選んでも、システムファイアウォールとクラウドプロバイダーのセキュリティグループ(Alibaba Cloud、Tencent Cloudなど)で該当するポートを開放する必要があります:
| 方法 | ポート | プロトコル | 役割 |
|---|---|---|---|
| 方法1 (リバースプロキシ) | 443 | TCP | Nginxが受け取るHTTPS/DERPトラフィック |
| 方法2 (IPのみ) | 13477 | TCP | DERP Dockerネイティブリレーリスナー |
| すべての方法 | 3478 | UDP | STUNプロトコル。NAT越えに使用 |
# UFWの例:方法1(リバースプロキシデプロイではHTTPSを開放)
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
# UFWの例:方法2(IPのみデプロイでは直接開放)
sudo ufw allow 13477/tcp
sudo ufw allow 3478/udp
DERPサーバーの検証
DERPの状態を確認
任意のTailscaleクライアントで以下を実行:
tailscale netcheck
出力にカスタムDERPリージョンとそのレイテンシが表示されるはずです:
Report:
* UDP: true
* IPv4: yes, ...
* IPv6: yes, ...
* DERP latency:
- hkg: 25.3ms (Tencent Cloud Hong Kong)
接続方法を確認
tailscale status
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 NAT越えの成功率を向上。
設定のポイント:
- Dockerの
network_modeはhostに設定する必要があります。 - ドメインリバースプロキシモードでは、NginxにWebSocketヘッダー(
Upgrade "websocket"など)を追加し、426エラーを回避します。 - IPのみモードでは、ACL設定に
"InsecureForTests": trueが必要です。 - ACLの
OmitDefaultRegionsで公式DERPノードを使用するかどうかを制御します。