mirror of
https://github.com/juanfont/headscale.git
synced 2026-01-11 20:00:28 +01:00
Handle CORS headers and OPTIONS method for HTTP API #272
Closed
opened 2025-12-29 01:25:37 +01:00 by adam
·
24 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
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/headscale#272
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 @routerino on GitHub (Jun 9, 2022).
Bug description
When trying to use a browser to generate API requests (like, hypothetically, if you're building a web frontend for headscale), the browser expects to to use CORS to determine if it can talk to the external server. The browser does this by the following:
OPTIONSrequest, expecting back a 204 response with the CORS headers attachedFor this to work, we need two things:
OPTIONSrequests without authorization.To Reproduce
Generate a fetch request from a browser in a separate domain. Such as:
If no CORS headers are specified, you get this nice error in the browser console:

If you have the right headers (if you, for example, inject them with a reverse proxy) but the OPTIONS request is blocked by authorization, you get this nice error instead:

Because the OPTIONS request is returning a 401 unauthorized when it shouldn't.
Both are not ideal. You can fix both with a reverse proxy, but you certainly shouldn't have to. The web server (gin?) should return OPTIONS with a 204 and be setting the CORS headers on all requests (and the CORS headers should be configurable).
Context info
These problems were fixed externally by routing through a Caddy reverse proxy using these matching settings:
@Mikle-Bond commented on GitHub (Jan 21, 2023):
If you use caddy-docker-proxy, here's the same (mostly) config, done in labels:
@deimjons commented on GitHub (Aug 30, 2023):
Someone know how to configure it for Traefik?
I tryed to add next labels:
Looks like the first part of the problem is solved, but I have a problem with 204 status code in the answer..
I think maybe this plugin should help but I can't configure it properly, it shows me error "status code is smallest than minimum value: 100"
(Issue with details opened here: https://github.com/Medzoner/traefik-plugin-cors-preflight/issues/8)
@Mikle-Bond commented on GitHub (Aug 31, 2023):
@deimjons
Maybe try this plugin instead? https://plugins.traefik.io/plugins/628c9f0f108ecc83915d7771/replace-status-code
@deimjons commented on GitHub (Sep 1, 2023):
@Mikle-Bond Thank you for your attention. I tried this plugin but it didn't help me. I don't know: I doing something wrong or the plugin just not working.
I have added additional routes in labels:
also, I added a plugin and middleware (like they show in the documentation example) in the configuration file of traefik: traefik.yaml
As a result, I have the same error:
@mich2k commented on GitHub (Sep 20, 2023):
did you manage? I also have to do this
edit: https://doc.traefik.io/traefik/v2.4/middlewares/headers/
@deimjons commented on GitHub (Oct 1, 2023):
no, I use it via prefix /admin.. ((
@masterwishx commented on GitHub (Jan 7, 2024):
How to add this to Nginx Proxy Manager ?
@sapstar commented on GitHub (Feb 11, 2024):
Hi, did you ever figure this out? I am also unable to access api via NPM.
@masterwishx commented on GitHub (Feb 11, 2024):
Yes, all working fine, if you using cloudflare disable the proxy (orange cloud)
@sapstar commented on GitHub (Feb 12, 2024):
Thank you very much. That sorted it.
@fcwys commented on GitHub (Feb 29, 2024):
I hope to support CORS, and I would like to use healscale directly instead of using Nginx and other programs for proxy, which is very inconvenient
@B08Z commented on GitHub (Feb 29, 2024):
Has anyone else made this work I can't figure it out.
@fcwys commented on GitHub (Feb 29, 2024):
I don't use Caddy, and I don't actually have any plans to use it. I just want to run Headscale directly.
@B08Z commented on GitHub (Mar 4, 2024):
I am getting this error with the above implementation using Headscale-admin
@GoodiesHQ commented on GitHub (Apr 26, 2024):
@B08Z This might be super old and you may have opened an issue on headscale-admin referencing this, but you should be able to use this value to allow CORS from anywhere:
"Access-Control-Allow-Headers Authorization, *"or perhaps
'Access-Control-Allow-Headers "Authorization, *"'is the right syntax?
It needs to be explicit for whatever reason.
@github-actions[bot] commented on GitHub (Jul 26, 2024):
This issue is stale because it has been open for 90 days with no activity.
@github-actions[bot] commented on GitHub (Aug 2, 2024):
This issue was closed because it has been inactive for 14 days since being marked as stale.
@fjeddy commented on GitHub (Aug 22, 2024):
This issue is preventing and stopping developers from creating any serious web-ui for headscale and should not be closed, without this, all we're gonna have is the five minute UI's that currently exist.
@Corbeno commented on GitHub (Aug 25, 2024):
Here's my solution for Nginx Proxy Manager. I'm no expert but it works :)
I have two different URLs, for example:
headscale.mydomain.com
headscale-admin.mydomain.com
I put this under the NPM config for headscale.mydomain.com
@gregoryca commented on GitHub (Oct 7, 2024):
For @mich2k and anyone else looking for the traefik config:
This should work, and prevent the error @B08Z encountered.
@taizen01 commented on GitHub (Feb 7, 2025):
I had to adjust some parts of your config, then it worked for me! Thank you.
@javito1081 commented on GitHub (Apr 19, 2025):
What do u mean by this? im trying to set it up with nginx proxy manager as well but its not working, it fails to test the connection :-(
@javito1081 commented on GitHub (Apr 19, 2025):
u mean the advance tab in the NPM forwarder?
@javito1081 commented on GitHub (Apr 19, 2025):
This one worked for me, this goes into the Advance tab of the domain on NPM, i just changed https://your-domain for my ui domain and worked like a charm :-)