SagerNet / SagerNet/sing-box

[Feature Request] tailscale: add control_websocket option for coordination servers behind CDNs / Cloudflare

Open
#4,504 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
38.2k
Forks
4.6k
Avg merge
19d 15h
Merged PRs (30d)
1

Description

Background & Problem

Tailscale clients establish their coordination control plane session (TS2021) by making an HTTP POST /ts2021 request with non-standard upgrade
headers:

POST /ts2021 HTTP/1.1
Upgrade: tailscale-control-protocol
Connection: upgrade
X-Tailscale-Handshake: <base64>

When self-hosting a coordination server (e.g. Headscale) behind CDNs or restrictive reverse proxies (such as Cloudflare Tunnel / Cloudflare Proxy):

  1. RFC 6455 Violation: RFC 6455 Section 4.1 (https://datatracker.ietf.org/doc/html/rfc6455#section-4.1) mandates that the WebSocket upgrade
    handshake must use the GET method.
  2. Upgrade Header Filtering: Cloudflare and similar edge proxies strictly filter WebSocket upgrade requests. They drop non-GET upgrades and only
    accept standard Upgrade: websocket. Any non-standard Upgrade: tailscale-control-protocol sent with POST is immediately rejected with an HTTP
    error (e.g. 500 Internal Server Error or 405 Method Not Allowed).

This limitation is well documented across the community:

Tailscale's repository actually already contains native WebSocket tunneling implementations (control/controlhttp/client_js.go, net/wsconn, and
controlhttpserver.acceptWebsocket), but it is only compiled in for js/wasm targets.

Proposed Solution

Add a control_websocket boolean option to TailscaleEndpointOptions:

{
 "type": "tailscale",
 "tag": "ts-ep",
 "control_url": "https://headscale.example.com",
 "control_websocket": true
}
Reference Implementation

A fully verified and tested implementation is available on my fork:

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with TailscaleEndpointOptions and the existing control/controlhttp/client_js.go, net/wsconn, and controlhttpserver.acceptWebsocket implementations. Compare the proposed behavior with the tailscale-wss branch and commit linked in the issue. Done means the tailscale endpoint accepts control_websocket in its configuration and can use the WebSocket path for coordination servers behind restrictive proxies.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
networking
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.