[Bug] testing for server_url containing base_domain is too restrictive #840

Closed
opened 2025-12-29 02:24:41 +01:00 by adam · 7 comments
Owner

Originally created by @quite on GitHub (Oct 24, 2024).

Is this a support request?

  • This is not a support request

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

I have server_url: https://homer.example.com and dns.base_domain: h. This does not work, headscale complains with server_url cannot contain the base_domain [..].

@mtoohey31 recently noted the same issue in a comment to https://github.com/juanfont/headscale/pull/2034:

I could be wrong, but I wonder if the string.Contains check might be too strict of a test. I want to use (for example) https://bar.foo.com as my server_url, and just foo as my dns.base_domain, but this check rejects that. I've manually removed the check and this seems to work without issue.

Expected Behavior

I don't want to be overly and unnecessarily restricted about the choice of base_domain.
I think that what should not be allowed are the following:

  • base_domain that is a prefix of server_url's hostname
  • base_domain equal to server_url's hostname
  • maybe also server_url's hostname that is a prefix of base_domain?

Possible plain prefix comparison is not suitable, but dot-separated parts needs to be taken into consideration separately? All this needs some more thinking through. Any ideas?

Steps To Reproduce

I have server_url: https://homer.example.com and dns.base_domain: h. This does not work, headscale complains with server_url cannot contain the base_domain [..].

Environment

- OS: Debian 12
- Headscale version: 0.23.0
- Tailscale version: 1.76.1

Runtime environment

  • Headscale is behind a (reverse) proxy
  • Headscale runs in a container

Anything else?

No response

Originally created by @quite on GitHub (Oct 24, 2024). ### Is this a support request? - [X] This is not a support request ### Is there an existing issue for this? - [X] I have searched the existing issues ### Current Behavior I have `server_url: https://homer.example.com` and `dns.base_domain: h`. This does not work, headscale complains with `server_url cannot contain the base_domain [..]`. @mtoohey31 recently noted the same issue in a [comment](https://github.com/juanfont/headscale/pull/2034#discussion_r1805755064) to https://github.com/juanfont/headscale/pull/2034: > I could be wrong, but I wonder if the `string.Contains` check might be too strict of a test. I want to use (for example) `https://bar.foo.com` as my `server_url`, and just `foo` as my `dns.base_domain`, but this check rejects that. I've manually removed the check and this seems to work without issue. ### Expected Behavior I don't want to be overly and unnecessarily restricted about the choice of `base_domain`. I *think* that what should *not* be allowed are the following: - `base_domain` that is a prefix of `server_url`'s hostname - `base_domain` equal to `server_url`'s hostname - maybe also `server_url`'s hostname that is a prefix of `base_domain`? Possible plain prefix comparison is not suitable, but dot-separated parts needs to be taken into consideration separately? All this needs some more thinking through. Any ideas? ### Steps To Reproduce I have `server_url: https://homer.example.com` and `dns.base_domain: h`. This does not work, headscale complains with `server_url cannot contain the base_domain [..]`. ### Environment ```markdown - OS: Debian 12 - Headscale version: 0.23.0 - Tailscale version: 1.76.1 ``` ### Runtime environment - [ ] Headscale is behind a (reverse) proxy - [ ] Headscale runs in a container ### Anything else? _No response_
adam added the bug label 2025-12-29 02:24:41 +01:00
adam closed this issue 2025-12-29 02:24:41 +01:00
Author
Owner

@hopleus commented on GitHub (Oct 28, 2024):

I assume that using a second-level domain in dns.base_domain, may cause conflicts, for example, when using *.base.domain at NPM or CloudFlare level (example 1), as well as possible conflicts with server_url (example 2).

Example 1:
There is a test-stage.base.domain that leads to a specific portal.
If a node with the same name test-stage is added, the portal will never open because the dns headscale will see this DNS record.

Example 2:

server_url: https://gateway.headscale.net
dns.base_domain: headscale.net

Add a node with the name gateway, that's it, the Headscale API working on gateway.headscale.net is no longer working, so the connection with the TailScale client is lost.

With the current implementation it seems logical to allocate a separate subdomain for the HeadScale network

@hopleus commented on GitHub (Oct 28, 2024): I assume that using a second-level domain in dns.base_domain, may cause conflicts, for example, when using `*.base.domain` at NPM or CloudFlare level (**example 1**), as well as possible conflicts with `server_url` (**example 2**). **Example 1:** There is a `test-stage.base.domain` that leads to a specific portal. If a node with the same name test-stage is added, the portal will never open because the dns headscale will see this DNS record. **Example 2:** ``` server_url: https://gateway.headscale.net dns.base_domain: headscale.net ``` Add a node with the name `gateway`, that's it, the Headscale API working on `gateway.headscale.net` is no longer working, so the connection with the TailScale client is lost. With the current implementation it seems logical to allocate a separate subdomain for the HeadScale network
Author
Owner

@motiejus commented on GitHub (Nov 16, 2024):

I stumbled upon the same issue while testing an upgrade to NixOS 24.11. Here is my config:

          server_url = "https://vpn.jakstys.lt";
          dns_config.base_domain = "jakst";

I don't care about the base_domain part (it's vanity). Is it safe to just change it on a running headscale instance with clients connected?

@motiejus commented on GitHub (Nov 16, 2024): I stumbled upon the same issue while testing an upgrade to NixOS 24.11. [Here](https://git.jakstys.lt/motiejus/config/src/commit/0292f83c72fc9b065ab4369aa57e846d9a2475e2/modules/services/headscale/default.nix#L28-L37) is my config: ```nix server_url = "https://vpn.jakstys.lt"; dns_config.base_domain = "jakst"; ``` I don't care about the `base_domain` part (it's vanity). Is it safe to just change it on a running headscale instance with clients connected?
Author
Owner

@kradalby commented on GitHub (Nov 17, 2024):

I don't care about the base_domain part (it's vanity). Is it safe to just change it on a running headscale instance with clients connected?

Yes, its only added at runtime, no database involved.

@kradalby commented on GitHub (Nov 17, 2024): > I don't care about the base_domain part (it's vanity). Is it safe to just change it on a running headscale instance with clients connected? Yes, its only added at runtime, no database involved.
Author
Owner

@kradalby commented on GitHub (Nov 17, 2024):

I could be wrong, but I wonder if the string.Contains check might be too strict of a test. I want to use (for example) https://bar.foo.com as my server_url, and just foo as my dns.base_domain, but this check rejects that. I've manually removed the check and this seems to work without issue.

I agree that it is a bit conservative. I am happy for a contribution relaxing it to ContainsSuffix given that:

  • potential characters that breaks the suffix are stripped
  • all "imaginable" test cases are added to ensure we dont have a silent breaking scenario causing support load.

Edit: parsing the full URL and comparing only the domain should probably be a good place to start.

@kradalby commented on GitHub (Nov 17, 2024): > I could be wrong, but I wonder if the `string.Contains` check might be too strict of a test. I want to use (for example) `https://bar.foo.com` as my `server_url`, and just `foo` as my `dns.base_domain`, but this check rejects that. I've manually removed the check and this seems to work without issue. I agree that it is a bit conservative. I am happy for a contribution relaxing it to `ContainsSuffix` given that: - potential characters that breaks the suffix are stripped - all "imaginable" test cases are added to ensure we dont have a silent breaking scenario causing support load. Edit: parsing the full URL and comparing only the domain should probably be a good place to start.
Author
Owner

@motiejus commented on GitHub (Nov 19, 2024):

Started implementing this.

Do I understand correctly that the Host parts of server_url and base_domain must be nonequal?

@motiejus commented on GitHub (Nov 19, 2024): Started implementing this. Do I understand correctly that the Host parts of `server_url` and `base_domain` must be nonequal?
Author
Owner

@kradalby commented on GitHub (Nov 20, 2024):

OK:
server_url: headscale.com, base: clients.headscale.com
server_url: headscale.com, base: headscale.net

Not OK:
server_url: server.headscale.com, base: headscale.com

Essentially we have to prevent the possibility where the headscale server has a URL which can also be assigned to a node.

So for the Not OK scenario:

if the server is: server.headscale.com, and a node joins with the name server, it will be assigned server.headscale.com and that will break the connection for nodes which will now try to connect to that node instead of the headscale server.

@kradalby commented on GitHub (Nov 20, 2024): OK: server_url: headscale.com, base: clients.headscale.com server_url: headscale.com, base: headscale.net Not OK: server_url: server.headscale.com, base: headscale.com Essentially we have to prevent the possibility where the headscale server has a URL which can _also_ be assigned to a node. So for the Not OK scenario: if the server is: server.headscale.com, and a node joins with the name `server`, it will be assigned server.headscale.com and that will break the connection for nodes which will now try to connect to that node instead of the headscale server.
Author
Owner

@motiejus commented on GitHub (Nov 21, 2024):

https://github.com/juanfont/headscale/pull/2248

@motiejus commented on GitHub (Nov 21, 2024): https://github.com/juanfont/headscale/pull/2248
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#840