mirror of
https://github.com/juanfont/headscale.git
synced 2026-01-11 20:00:28 +01:00
Purpose of non-standard POST method in Websocket handshake? #513
Closed
opened 2025-12-29 02:19:22 +01:00 by adam
·
11 comments
No Branch/Tag Specified
main
update_flake_lock_action
gh-pages
kradalby/release-v0.27.2
dependabot/go_modules/golang.org/x/crypto-0.45.0
dependabot/go_modules/github.com/opencontainers/runc-1.3.3
copilot/investigate-headscale-issue-2788
copilot/investigate-visibility-issue-2788
copilot/investigate-issue-2833
copilot/debug-issue-2846
copilot/fix-issue-2847
dependabot/go_modules/github.com/go-viper/mapstructure/v2-2.4.0
dependabot/go_modules/github.com/docker/docker-28.3.3incompatible
kradalby/cli-experiement3
doc/0.26.1
doc/0.25.1
doc/0.25.0
doc/0.24.3
doc/0.24.2
doc/0.24.1
doc/0.24.0
kradalby/build-docker-on-pr
topic/docu-versioning
topic/docker-kos
juanfont/fix-crash-node-id
juanfont/better-disclaimer
update-contributors
topic/prettier
revert-1893-add-test-stage-to-docs
add-test-stage-to-docs
remove-node-check-interval
fix-empty-prefix
fix-ephemeral-reusable
bug_report-debuginfo
autogroups
logs-to-stderr
revert-1414-topic/fix_unix_socket
rename-machine-node
port-embedded-derp-tests-v2
port-derp-tests
duplicate-word-linter
update-tailscale-1.36
warn-against-apache
ko-fi-link
more-acl-tests
fix-typo-standalone
parallel-nolint
tparallel-fix
rerouting
ssh-changelog-docs
oidc-cleanup
web-auth-flow-tests
kradalby-gh-runner
fix-proto-lint
remove-funding-links
go-1.19
enable-1.30-in-tests
0.16.x
cosmetic-changes-integration
tmp-fix-integration-docker
fix-integration-docker
configurable-update-interval
show-nodes-online
hs2021
acl-syntax-fixes
ts2021-implementation
fix-spurious-updates
unstable-integration-tests
mandatory-stun
embedded-derp
prtemplate-fix
v0.28.0-beta.1
v0.27.2-rc.1
v0.27.1
v0.27.0
v0.27.0-beta.2
v0.27.0-beta.1
v0.26.1
v0.26.0
v0.26.0-beta.2
v0.26.0-beta.1
v0.25.1
v0.25.0
v0.25.0-beta.2
v0.24.3
v0.25.0-beta.1
v0.24.2
v0.24.1
v0.24.0
v0.24.0-beta.2
v0.24.0-beta.1
v0.23.0
v0.23.0-rc.1
v0.23.0-beta.5
v0.23.0-beta.4
v0.23.0-beta3
v0.23.0-beta2
v0.23.0-beta1
v0.23.0-alpha12
v0.23.0-alpha11
v0.23.0-alpha10
v0.23.0-alpha9
v0.23.0-alpha8
v0.23.0-alpha7
v0.23.0-alpha6
v0.23.0-alpha5
v0.23.0-alpha4
v0.23.0-alpha4-docker-ko-test9
v0.23.0-alpha4-docker-ko-test8
v0.23.0-alpha4-docker-ko-test7
v0.23.0-alpha4-docker-ko-test6
v0.23.0-alpha4-docker-ko-test5
v0.23.0-alpha-docker-release-test-debug2
v0.23.0-alpha-docker-release-test-debug
v0.23.0-alpha4-docker-ko-test4
v0.23.0-alpha4-docker-ko-test3
v0.23.0-alpha4-docker-ko-test2
v0.23.0-alpha4-docker-ko-test
v0.23.0-alpha3
v0.23.0-alpha2
v0.23.0-alpha1
v0.22.3
v0.22.2
v0.23.0-alpha-docker-release-test
v0.22.1
v0.22.0
v0.22.0-alpha3
v0.22.0-alpha2
v0.22.0-alpha1
v0.22.0-nfpmtest
v0.21.0
v0.20.0
v0.19.0
v0.19.0-beta2
v0.19.0-beta1
v0.18.0
v0.18.0-beta4
v0.18.0-beta3
v0.18.0-beta2
v0.18.0-beta1
v0.17.1
v0.17.0
v0.17.0-beta5
v0.17.0-beta4
v0.17.0-beta3
v0.17.0-beta2
v0.17.0-beta1
v0.17.0-alpha4
v0.17.0-alpha3
v0.17.0-alpha2
v0.17.0-alpha1
v0.16.4
v0.16.3
v0.16.2
v0.16.1
v0.16.0
v0.16.0-beta7
v0.16.0-beta6
v0.16.0-beta5
v0.16.0-beta4
v0.16.0-beta3
v0.16.0-beta2
v0.16.0-beta1
v0.15.0
v0.15.0-beta6
v0.15.0-beta5
v0.15.0-beta4
v0.15.0-beta3
v0.15.0-beta2
v0.15.0-beta1
v0.14.0
v0.14.0-beta2
v0.14.0-beta1
v0.13.0
v0.13.0-beta3
v0.13.0-beta2
v0.13.0-beta1
upstream/v0.12.4
v0.12.4
v0.12.3
v0.12.2
v0.12.2-beta1
v0.12.1
v0.12.0-beta2
v0.12.0-beta1
v0.11.0
v0.10.8
v0.10.7
v0.10.6
v0.10.5
v0.10.4
v0.10.3
v0.10.2
v0.10.1
v0.10.0
v0.9.3
v0.9.2
v0.9.1
v0.9.0
v0.8.1
v0.8.0
v0.7.1
v0.7.0
v0.6.1
v0.6.0
v0.5.2
v0.5.1
v0.5.0
v0.4.0
v0.3.6
v0.3.5
v0.3.4
v0.3.3
v0.3.2
v0.3.1
v0.3.0
v0.2.2
v0.2.1
v0.2.0
v0.1.1
v0.1.0
Labels
Clear labels
CLI
DERP
DNS
Nix
OIDC
SSH
bug
database
documentation
duplicate
enhancement
faq
good first issue
grants
help wanted
might-come
needs design doc
needs investigation
no-stale-bot
out of scope
performance
policy 📝
pull-request
question
regression
routes
stale
tags
tailscale-feature-gap
well described ❤️
wontfix
Mirrored from GitHub Pull Request
No Label
bug
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/headscale#513
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @isaac-mcfadyen on GitHub (May 15, 2023).
Hi!
First of all, thanks for all of the hard work that goes into Headscale. I use it daily for personal use and couldn't be happier. 🙏
I'm wondering about the use of the POST method in the Websocket handshake when connecting to Headscale. Per Section 4.1 of RFC 6455, "the method of the request MUST be GET". Further down the RFC specifies that invalid requests (such as methods other than GET) should be rejected.
I understand deviating from the spec if required - however, some proxies really don't handle Websocket handshakes via POST well (see this StackOverflow and this issue for lack of compatibility with Cloudflare Tunnel, a reverse proxy https://github.com/cloudflare/cloudflared/issues/883).
I was wondering if there was a purpose making the Websocket handshake be a POST instead of the standard GET? 🙂
@juanfont commented on GitHub (May 15, 2023):
Hi Isaac,
Unfortunately it is part of the tailscale control protocol.
@gbraad commented on GitHub (Jul 6, 2023):
Is it related to the following?
cb53846717/control/controlhttp/client.go (L479-L487)Perhaps good to file an upstream issue for this.
@kradalby WDYT?
@kradalby commented on GitHub (Jul 7, 2023):
Our general take on this is that we do not support proxies, and this is one of the reason.
In the end it is more of a custom protocol than a RFC protocol, and while an issue could be raised upstream, it would probably not be a change that there is intensive to fix as it would break (or make more surface to maintain) backwards compatibility.
The social contract between Headscale and Tailscale is based on not causing Tailscale additional work and while they very much welcome changes that improve stuff for both users, we do not really want to push these boundaries to maintain our good relationship.
If issues are raised upstream, my take is that they should not solely improve life for Headscale, and they should not cause additional work for Tailscale.
@kradalby commented on GitHub (Jul 7, 2023):
I'm going to close this as out of scope.
@lukeIam commented on GitHub (Jul 30, 2023):
idea for workaround: can we identify the requests with missing headers and "repair" them with an additional reverse proxy?
I added a nginx reverse proxy between my headscale and cloudflared cointainers.
But adding the headers to all POST requests to /ts2021 seems to be too much and causes other errors...
@isaac-mcfadyen @gbraad
@Ducky6944 commented on GitHub (Feb 27, 2024):
Just for POSTerity, the usage of POST here is antithetical to the Websockets RFC.
https://www.rfc-editor.org/rfc/rfc6455#section-4.1
I, very respectfully, believe that this improves tailscale and is largely inconsequential for most everyone else.
Cloudflare doesn't want to break from RFCs, and Headscale doesn't want to burden Tailscale. I suspect this affects a large number of newcomers to Headscale, who probably hit this point are unable to effectively troubleshoot it, or see the situation as described and just abandon their attempts rather than raising an issue. Though it doesn't seem widely reported, Cloudflare is ubiquitous for homelabbers, small businesses, etc, particularly in the US. It's reasonable for headscale to not want to "support" proxies, but also reasonable that tailscale adheres to RFCs unless theres a specific reason not to.
I apologize for bumping a closed thread. I'm not trying to get into a conversation, disrespect, or point fingers. Regardless of workarounds, raising issues with cloudflare/tailscale etc, it might be nice to put a disclaimer high up on the repos' readme for visibility. I do see the reverse proxies notification, but also many proxies, guides on the internet, discussions on reddit etc use them. Maybe linking to the issue or something would be valuable to some. Just a thought.
@alx-xlx commented on GitHub (Apr 13, 2025):
That is why people always use an opensource project or repo, that sticks to open standards.
this repo is no longer opensource
Opensource has 4 requirements:
This repo doesn't tick the 3rd box.
Yes, You can modify the code however it will be unusable with the closed tailscale clients. so pretty much you can't modify the code.
This is how they get you !!
I bet many people chose tailscale seeing the headscale as alternative to their control server. Hoping to maybe one day spin their cloudflared tunnel to run headscale. Gotcha !!!
strategically headscale is in tailscale pockets.
@juanfont commented on GitHub (Apr 13, 2025):
The purpose of this project is to allow people to re-use the Tailscale client with a control server of their own. For that, we need to reimplement the Tailscale control protocol. If we don't do that correctly, the Tailscale clients won't work. If that's being in "Tailscale pockets" so be it.
Tailscale uses the standard websocket library from Go to hijack the TCP connection and create a Noise session over it between server and client. That does not mean that "Tailscale uses websockets".
We mention Websockets because the config in reverse proxies that enable websockets to work usually will allow Headscale/Tailscale to work. But that's not granted. And we even mention the Cloudflare case:
@luckycreationsindia commented on GitHub (Dec 19, 2025):
Hi,
I don't know why it didn't work for some people out there. It's working great for me even with cloudflare DNS proxy.
I'm using nginx for reverse proxy like below,
http://localhost:8080 -> headscale
It's working great for me without issues. I do have proxy enabled in cloudflare DNS.
@jimstrang commented on GitHub (Dec 20, 2025):
@luckycreationsindia - you are right there's no issues with the DNS proxy but people are having issues with the full cloudflare tunnel (cloudflared) proxy
@luckycreationsindia commented on GitHub (Dec 20, 2025):
So it's Cloudflared Tunnel issue and not Cloudflare DNS Proxy.
Maybe we need to be more clear about it in docs.