iceBear67 ac27db76f9 fix: connectivity check fails on split-DNS destinations at startup
The diagnostics never got the split-DNS fix from 20097a0. That commit
  taught the dial path to resolve through the tailnet's own resolver
  (resolveDialAddr) but left getPeerFromRules on resolveAddr, so the two
  disagreed about how to look a destination up: connecting through a
  split-DNS name worked while the startup check called it unresolvable.

  Both paths now share resolveHostToIP, which honors MagicDNS, split-DNS
  routes and the DoH fallback.

  The check also resolved once at startup and cached the result for the
  process lifetime. tsnet reports Running before the netmap's DNS config
  reaches its resolver, and accept-routes is only applied after Up()
  returns, so a split-DNS name can fail for the first few seconds and
  resolve fine after. That transient failure dropped the peer permanently
  -- and when every rule failed, the goroutine returned and diagnostics
  never ran at all. Peers are re-resolved every round now, with a warm-up
  retry so the first report waits for DNS rather than racing it.

  Destinations outside the tailnet are no longer reported as failures.
  mc.lxns.net resolves fine but belongs to no peer, which is not an error,
  just not something to ping. errNotTailnetPeer separates "cannot resolve"
  from "resolved, not a peer"; only the former is retried or warned about.
  Unresolved rules now log their tag and dst, which the old message
  omitted entirely.

  Also fixed:

    * NormalizeDstAddrWithSuffix passed "host:port" to resolveAddr, so
      every existence check failed on the stray colon. Fixing that made
      the pass wait on cold-start DNS and delayed the listeners by ~5s,
      so it is now bounded by normalizeDNSBudget.

    * Peer lookup matched any AllowedIPs prefix containing the address.
      An exit node advertises 0.0.0.0/0, which contains everything, so a
      tailnet with an exit node picked the wrong peer at random depending
      on map iteration order. Default routes are skipped, the most
      specific route wins, ties break deterministically.

    * peer.AllowedIPs is a nillable pointer, dereferenced unguarded.
2026-07-26 14:52:14 +08:00
2026-07-26 14:14:03 +08:00
2026-07-26 14:14:03 +08:00
2026-05-17 18:56:39 +08:00
2026-05-25 00:50:08 +08:00
2026-05-25 00:21:49 +08:00
2026-07-26 14:14:03 +08:00
2026-06-10 15:32:12 +08:00
2026-07-26 14:14:03 +08:00

tslink

基于 Tailscale tsnet 的轻量双向流量转发工具,可将本机服务暴露到 Tailnet,也可将 Tailnet 服务通过本机端口对外暴露。

特性

  • 双向转发forwardTailscale → 本地)与 connect(本地 → Tailscale)两种模式
  • TCP / UDP 全支持:透明转发 TCP 流与 UDP 数据包
  • Minecraft 专用模式:支持局域网广播发现(MOTD),让本地设备发现 Tailnet 上的 Minecraft 服务器
  • MagicDNS 主机名补全dst_addr 支持按照 Tailscale 规则正确解析 Split DNS 和 Magic DNS
  • 连接类型识别:区分 direct 直连与 derp 中继,便于排查延迟问题
  • 对端连通性诊断:定期 ping 目标节点并报告延迟与连接路径(direct/DERP
  • Web 管理:内置 Tailscale Web Client(端口 5252),可在线管理节点配置
  • 多配置源:支持本地 TOML 文件、HTTP/HTTPS URL、构建时注入默认 URL

环境要求

  • Tailscale / Headscale 授权密钥

快速开始

  1. 前往 Releases 下载对应平台的二进制文件,赋予执行权限后放入 PATH

  2. 准备配置文件:

    cp config.example.toml config.toml
    vim config.toml  # 填入 auth_key 并配置转发规则
    
  3. 启动:

    tslink -c config.toml
    

容器部署

cp config.example.toml config.toml
# 编辑 config.toml,然后对照修改 docker-compose.yml 中的端口映射
docker compose up -d

详细配置与使用说明见 USAGE.md

工作原理

forward (你 -> 其他人):
  Tailscale Client ──TCP/UDP──> [本机 Tailscale IP:port] ──转发──> [本地服务 127.0.0.1:port]

connect (其他人 -> 你):
  本地/LAN 客户端 ──TCP/UDP──> [本机监听 port] ──转发──> [Tailscale 目标 host:port]
S
Description
No description provided
Readme MIT
449 KiB
Languages
Go 100%