当前位置:首页 > 动态 > 正文内容

Tailscale 自建 DERP 中继连接失败(Nginx 404)排查与解决记录

XTT50分钟前动态2


Tailscale 自建 DERP 中继连接失败(Nginx 404)排查与解决记录

本文记录一次自建 DERP 中继无法连接的完整排查过程。核心结论:后端 derper 未运行,导致 Nginx 返回 404,客户端无法完成 DERP 协议升级。已做脱敏处理,域名、IP、公钥等请替换为实际值。

一、问题现象

Tailscale 客户端(Windows)无法连接自建 DERP 中继,健康检查持续提示:

# Health check:
#     - Tailscale could not connect to the 'LLY' relay server. Your Internet connection might be down, or the server might be temporarily unavailable.

tailscale netcheck 显示到该中继延迟正常(约 30ms),UDP 可用,NAT 穿透成功,但实际无法建立 DERP 连接。

二、环境说明

  • 控制平面:Headscale 或类似自建方案(用户标识非标准邮箱)

  • 客户端:Windows,Tailscale 版本较新

  • 自建 DERP 服务器:Linux,使用 Nginx 作为 443 端口入口

  • DERP 区域配置:自定义区域 900(广州 / LLY),指向自有域名

  • 后端 DERP 服务:derper,监听本地端口(如 127.0.0.1:1234)

三、排查过程与关键发现

1. 基础网络检查

tailscale netcheck

输出显示 UDP 可用、IPv4 正常、NAT 类型为 UPnP/NAT-PMP/PCP,最近 DERP 为 LLY,延迟约 29.7ms。说明网络层可达,问题不在基础连通性。

2. 查看客户端实时日志

tailscale debug daemon-logs

日志中出现关键错误:

derphttp.Client.Recv: connecting to derp-900 (广州)
derphttp.Client.Recv connect to region 900 (广州): GET failed: <nil>: <html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
客户端成功连接到了 443 端口,但对方返回了 Nginx 的 404 页面,而不是 DERP 协议所需的 101 Switching Protocols。说明请求被 Nginx 的 HTTP 七层反向代理拦截,没有正确转发给后端的 derper 服务。

3. 直接测试 DERP 端点

使用 curl 模拟 DERP 的 HTTP Upgrade 请求:

curl.exe -v --noproxy "*" -H "Upgrade: websocket" -H "Connection: Upgrade" https://your-derp-domain.com/derp

修复前返回 404 Not Found(Nginx 页面)。
 修复后返回:

< HTTP/1.1 101 Switching Protocols
< Connection: upgrade
< Upgrade: DERP
< Derp-Version: 2
< Derp-Public-Key: <公钥>

这证明 DERP 握手成功。

4. 检查 Nginx 配置

原始 Nginx 配置片段(位于 http {} 块内):

location ^~ /
{
    proxy_pass http://127.0.0.1:1234;
    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 REMOTE-HOST $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_http_version 1.1;

    add_header X-Cache $upstream_cache_status;

    set $static_fileHlIrpUOR 0;
    if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
    {
        set $static_fileHlIrpUOR 1;
        expires 1m;
    }
    if ( $static_fileHlIrpUOR = 0 )
    {
        add_header Cache-Control no-cache;
    }
}

关键点:

  • proxy_http_version 1.1; 必须设置,HTTP/1.1 才支持协议升级。

  • proxy_set_header Upgrade $http_upgrade; 将客户端的 Upgrade 头传递给后端。

  • proxy_set_header Connection $connection_upgrade; 将 Connection 头传递给后端。

  • 后端 derper 必须实际监听 127.0.0.1:1234。

根本原因:最初后端 derper 服务未启动或未正确监听,导致 Nginx 转发失败并返回 404。启动 derper 并确保 Nginx 的 Upgrade 头配置正确后,连接恢复正常。

四、解决方案

1. 启动并配置 derper 服务

derper -a :1234 -c /path/to/cert -hostname your-derp-domain.com

建议使用 systemd 管理 derper,确保开机自启和自动重启。

2. 配置 Nginx 反向代理(HTTP 七层 + Upgrade)

在 http {} 块顶层定义 $connection_upgrade 变量:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

然后为 DERP 域名配置 location(见上文「原始 Nginx 配置片段」)。

3. 配置 Headscale 的 DERP 地图

{
  "derpMap": {
    "OmitDefaultRegions": true,
    "Regions": {
      "900": {
        "RegionID": 900,
        "RegionCode": "广州",
        "RegionName": "LLY",
        "Nodes": [{
          "Name": "1",
          "RegionID": 900,
          "HostName": "your-derp-domain.com",
          "DERPPort": 443
        }]
      }
    }
  }
}

注意:HostName 必须是可解析的域名,且证书有效。DERPPort 通常为 443。

4. 重启服务并刷新客户端

  • 重载 Nginx:nginx -s reload

  • 重启 Headscale 使 ACL 生效(如果修改了配置)

  • 在客户端执行:

tailscale down
tailscale up
 

五、验证方法

1. 测试 DERP 端点

curl.exe -v --noproxy "*" -H "Upgrade: websocket" -H "Connection: Upgrade" https://your-derp-domain.com/derp

期望输出:

< HTTP/1.1 101 Switching Protocols
< Connection: upgrade
< Upgrade: DERP
< Derp-Version: 2

2. 检查 TCP 端口

Test-NetConnection your-derp-domain.com -Port 443

期望:TcpTestSucceeded : True

3. 查看 Tailscale 状态

tailscale netcheck

应显示自定义 DERP 区域及延迟,例如:

Nearest DERP: LLY
DERP latency:
    - 广州: 29.7ms (LLY)
tailscale status

健康检查部分不再出现 could not connect to the 'LLY' relay server。

六、备份配置建议

文件 / 内容路径示例
Nginx 主配置及站点配置/etc/nginx/nginx.conf、conf.d/
derper systemd 单元文件/etc/systemd/system/derper.service
Headscale 配置及 ACL/etc/headscale/config.yaml、acl.hujson
TLS 证书与私钥/path/to/cert/
版本信息tailscale version、derper version

建议将上述配置纳入版本控制(如 Git),并定期备份。

七、注意事项

  • DERP 协议升级与 WebSocket 类似,因此 Nginx 的 HTTP 七层反代 + Upgrade/Connection 头可以工作。但必须确保 proxy_http_version 1.1 和正确的头传递。

  • 如果同一 443 端口还要服务其他网站,location ^~ / 会全部匹配,可能冲突。此时建议使用 Nginx stream {} 四层转发 + ssl_preread 按 SNI 分流。

  • 证书必须有效,且域名与 derper -hostname 一致,否则客户端会拒绝连接。

  • 防火墙需放行 TCP 443,如果启用 STUN,还需放行 UDP 3478。

  • 修改 Headscale ACL 后,客户端可能需要重新登录或重启 Tailscale 服务才能拉取新配置。

  • 不要将敏感信息(域名、IP、公钥、用户 ID)公开分享,本文档已做脱敏处理。

八、总结

本次问题的核心是:自建 DERP 中继的后端 derper 服务未正常运行,导致 Nginx 返回 404,客户端无法完成 DERP 协议升级。通过启动 derper 并确保 Nginx 正确传递 Upgrade 和 Connection 头,问题得以解决。

   排查时,直接使用 curl 模拟 DERP 握手是最快的验证手段。看到 101 Switching Protocols 和 Upgrade: DERP 即表示链路正常。

返回列表

上一篇:Strata-启动器

没有最新的文章了...

发表评论

◎欢迎参与讨论,请在这里发表您的看法和观点。