Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FR: Support custom records in MagicDNS #1543

Open
darshinimashar opened this issue Mar 18, 2021 · 53 comments
Open

FR: Support custom records in MagicDNS #1543

darshinimashar opened this issue Mar 18, 2021 · 53 comments
Labels
fr Feature request L3 Some users Likelihood P2 Aggravating Priority level T0 New feature Issue type

Comments

@darshinimashar
Copy link

darshinimashar commented Mar 18, 2021

Also, for DNS, the Customer would really like to make DNS aliases such as example.ourdomain.beta.tailscale.net always point to a machine name staging-1 or something like that.

This way, they can easily access the machines.

@bradfitz bradfitz changed the title Renaming MagicDNS URLs to. machine name only. Allow adding custom DNS records, including CNAMEs Mar 18, 2021
@DentonGentry DentonGentry added L1 Very few Likelihood P2 Aggravating Priority level T0 New feature Issue type labels May 20, 2021
@guidoiaquinti
Copy link

I would love to see as well support for an internal .tailscale domain name (example: nas.tailscale, pi.tailscale) and maybe even subzones (example: nas.home.tailscale VS nas.office.tailscale) without the need of a dedicated/external DNS server.

@MingSpace
Copy link

This feature will easily customize the DNS of the home server , just use tailscale 😀

I would love to see as well support for an internal .tailscale domain name (example: nas.tailscale, pi.tailscale) and maybe even subzones (example: nas.home.tailscale VS nas.office.tailscale) without the need of a dedicated/external DNS server.

@DentonGentry DentonGentry changed the title Allow adding custom DNS records, including CNAMEs Support custom records in MagicDNS Jul 21, 2021
@bradfitz
Copy link
Member

0debb99 added client support for a new ExtraRecords field. It's not yet supported server-side.

@awoimbee
Copy link

Sorry to be this person, but: Any news on this @bradfitz ? It's awkward that it has been partially implemented for 7 months.
This would simplify the process described here #1748 (comment) quite a bit by removing the need to host a DNS server.

@bradfitz
Copy link
Member

It's awkward that it has been partially implemented for 7 months.

Well, it was "partially implemented" because we needed the part we implemented (and now use) for the LetsEncrypt support.

Exposing more of it for this has a ton of product & security considerations and interacts often surprisingly with various DNS stacks on different platforms, which will increase our support burden if we ship something that seems to work sometimes but not on all platforms in all configs.

Example of problems:

  • if you add a foo.net record, we need to make sure your OS queries the 100.100.100.100 resolver for that record. But some OSes only let us route *.foo.net to us, which means what do we do with bar.foo.net? We'd have to forward that on upstream, but some OSes don't make it easy or possible for us to figure out what the system's underlying/native DNS servers are. So then we'd require you specify an upstream DNS server in your Tailnet config, which we're trying to move away from so we can enable MagicDNS on by default.
  • if you add a foo.tailnet-name.ts.net record, what if foo already exists as a machine name on the tailnet? what if foo comes into existence later? does that reserve foo for you? do we permit ACME challenges for foo? what if its IP is changed later? which node can then do the ACME challenge?
  • if you add a record pointing at the IP of a node and share that node, does the extra record get shared to other tailnets? (not for now, but that's a possible use case people might want later)

We're leaning towards shipping this soon but with a bunch of limitations to start like:

  • no *.ts.net
  • no *.tailscale.net
  • must have DNS servers set with force override (unfortunate for now, but makes things consistent)

Then we probably won't box ourselves into a corner and have to remove functionality later and can add more of this when other parts are ready.

The real problem here is that this feature means a number of things to different people and we have to make sure we don't try to do all of it at once, poorly.

@Tener
Copy link

Tener commented Mar 22, 2022

@bradfitz any news about the release date for the limited version of this feature? Having Tailscale-integrated DNS is a great feature, but a little bit of flexibility would be very welcome.

@DentonGentry
Copy link
Contributor

  • I promise we will update this bug when something is close to being ready
  • polling for updates is not useful

@Tener
Copy link

Tener commented Mar 22, 2022

Thanks, I didn't mean to push, merely hoping to learn of your plans with this feature.

@mpl
Copy link

mpl commented Jul 1, 2022

@DentonGentry Hello. I understand the meaning of the P2 and T0 labels, but I'm not sure I get the L1 one. Does it describe the likelihood of the issue to get fixed? oh, or does it give an indication of the number of other issues similar to this one?

And I have a question about the feature itself that would address this issue:
Do you envision that there will be a public API for adding DNS entries (which means it could be done with the CLI maybe), or will the feature be limited to the admin web interface?

@DentonGentry DentonGentry added L3 Some users Likelihood and removed L1 Very few Likelihood labels Jul 1, 2022
@DentonGentry
Copy link
Contributor

It is an estimate of the number of sites which would use this feature request. Given the number of 👍 since the label was applied, I changed the assessment.

I expect an initial way to make the functionality available will be a new field in the policy JSON in https://login.tailscale.com/admin/acls. There is an API for that: https://github.com/tailscale/tailscale/blob/main/api.md#tailnet-acl-post

@hybras
Copy link

hybras commented Jul 18, 2022

I'm currently have jobs on my machine's that get my tailscale ip and set dns records with my dynamic dns provider. I then have CNAMEs to these records. I get https certificates using let's encrypt's DNS challenge because these services are only available from my network / tailscale. This works beautifully though it was a pain to figure out.

If tailscale's dns supported arbitrary records, I could cut out the ddns middle man since tailscale already has records pointing to my nodes.

@DentonGentry DentonGentry changed the title Support custom records in MagicDNS FR: Support custom records in MagicDNS Aug 5, 2022
@DentonGentry DentonGentry added the fr Feature request label Aug 5, 2022
bradfitz added a commit that referenced this issue Aug 30, 2022
…ap 41]

If ExtraRecords (Hosts) are specified without a corresponding split
DNS route and global DNS is specified, then program the host OS DNS to
use 100.100.100.100 so it can blend in those ExtraRecords.

Updates #1543

Change-Id: If49014a5ecc8e38978ff26e54d1f74fe8dbbb9bc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
@distantorigin
Copy link

My use case:
I would like to be able to alias certain machines with multiple names, so Caddy/Nginx can reverse proxy to them. For example, https://bitwarden, https://minio, etc, would all map back to the same Tailscale IP while on the tailnet. This functionality became of interest to me when trying to do a three-way split DNS--bitwarden.mydomain.com points to a public IP when not on my LAN. While connected to my LAN it points to the internal address at 192.168.xxx.xxx, and when connected to Tailscale it points to the Tailscale IP (otherwise users not on my LAN wouldn't be able to access it--I'm not interested in advertising the LAN IPs as routes).

I run Pi-Hole on the LAN for DNS. To address not being able to have custom records in MagicDNS, I'm currently using a Pi-Hole image in docker that is paired with the Tailscale docker image to host a TS-only Pi-Hole instance as a machine in my Tailnet. One might argue that I could easily use Dnsmasq and forward onto the LAN-based Pi-Hole as upstream, but that's beyond the scope of this comment.

I would love to see custom records for MagicDNS for this reason--it would remove overhead and a lot of friction from my personal infrastructure.

@0PandaDEV
Copy link

My use case would be that I have multiple services running on a server that is in my Tailscale network, and then I can make aliases to them that are only internally accessible like for example the tailscale IP of my server is 100.86.67.57, and I have a website running on port 3001 now it this scenario I want it to be accessible through h.lan from any device in my tailnet, so I would need an SRV record and an A record or a mixture of them like with Cloudflare zero trust tunnels.

@watsonbox
Copy link

This recent blog post might be of interest for those wanting to add specific docker services directly to a tailnet (complete with their own MagicDNS names):

https://tailscale.com/blog/docker-tailscale-guide

@bouk
Copy link

bouk commented Feb 29, 2024

I have a specific use case for this: I have some machines that are on a local 10.x.x.x network that I want to make accessible over a custom domain name (machinename.local.example.com) so I can get an SSL cert for them. I can use MagicDNS for this, I need it to work when the DNS server is not reachable however since we often have flaky connections.

Preferably we could do this without running an additional service on the user's machine to provide DNS. So it would be useful if I can give a 'hosts file' to the Tailscale API that is then cached and resolved locally over MagicDNS

@luis7722
Copy link

My case is simple, I want to use the custom DNS settings to configure my SMTP server to use the MagicDNS domain.

@bdbusch
Copy link

bdbusch commented Jun 14, 2024

From our perspective, we have apps running on these servers that have a certain domain for SSL (e.g., abc.com) - and we know that the cert matching/validation logic is based on the host name used to hit the service, so if we can call our machine umpty and get an umpty.abc.com alias for the IP automatically, then when a user hits that machine using the FQDN, we get a good SSL match.

https://umpty.abc.com:port will find the machine and match the x509.

Sorry if this use case was mentioned already

@matheuscscp
Copy link

my use case is:

my friend and I are developing an open source project and we have local k8s clusters running inside our machines via kind. we have manually set some A DNS records inside /etc/hosts in our machines to access each other's clusters through my personal tailnet using domains. i'd like to have a private DNS zone inside my tailnet to automatically set those records in our machines (and keep them in sync as a source of truth)

sarumont added a commit to sarumont/homelab that referenced this issue Jun 24, 2024
This helps with the fact that I can't specify custom DNS records inside
of my Tailnet ([ref](tailscale/tailscale#1543)),
allowing me to access "local" services without sending all my DNS
traffic through the Tailnet.
@klevis-a
Copy link

klevis-a commented Jul 30, 2024

Use case: Easy access to SSL-enabled Synology DiskStation without opening ports or configuring a subnet router. This is a viable alternative to the Synology QuickConnect solution.

  1. If you use Synology's DDNS service you also get an SSL certificate. You are stuck with the my-name.synology.me domain, but the upside is that 1) it's a few clicks to configure 2) you get an SSL certificate.
  2. Use the DiskStation's DNS server to configure my-name.synology.me to point to the DiskStation's local IP address and forward other requests to your main DNS server (likely your router/modem).
  3. Configure your local devices (laptop, phone, etc.) so their primary DNS server is Synology and backup is router/modem.
  4. Now you should be able to simply visit my-name.synology.me and use DiskStation over SSL while pointing to a local IP address.
  5. You can easily do the same while using your tailnet as long as you can point my-name.synology.me to your Synology DiskStation node. This removes the need to setup some device (e.g. Synology DiskStation) as a subnet router.

@Zizo4418

This comment has been minimized.

@prostolyubo
Copy link

I would love this. My use case is simple: I only want all subdomains of *.mymachine to point to mymachine.
I have a lot of services running in docker on my server and I'm running into port hell. So I have a reverse proxy and a local DNS server so I can get rid of docker port mapping and access my services simply by: nodered.mymachine, homepage.mymachine instead of mymachine:1880, and so on. It works well until I connect from remote location via tailscale. It all falls apart because for example nodered.mymachine cannot be resolved.

@omnizach
Copy link

omnizach commented Sep 6, 2024

+1. Reverse proxy on Unraid, I would love to use tailnet URLs and completely get rid of public DNS records with custom domain. Tailscale is awesome and so close to completely solving this problem, missing this one feature. Thanks!

@Geekdude
Copy link

Geekdude commented Sep 6, 2024

+1. I would like Tailscale MagicDNS to enable something like having servicename.mymachine.tailnet-name.ts.net point to mymachine.tailnet-name.ts.net:serviceport. That way, I only have to remember the name of the service without having to remember port numbers.

@mattdale77
Copy link

+1 would like to run a reverse proxy with service names instead of using port numbers. Some services also insist on being behind https and is the missing link which would allow that natively in tailscale

@jhsul
Copy link

jhsul commented Oct 9, 2024

For anyone who is looking for a solution right now, here is a docker compose stack which I'm using to run an adguard home DNS instance in my tailnet.

I run this stack on the same physical device as my main server (a different docker compose stack), which is also running a tailscale container in sidecar mode - despite being on the same hardware, these appear as two distinct devices with their own IP address in the tailnet. I give my dns device the IP address 100.100.10.10, and I have that IP configured as the default nameserver.

services:
  adguardhome:
    container_name: adguardhome
    image: adguard/adguardhome
    network_mode: service:tailscale-dns
    restart: unless-stopped
    volumes:
      - ../../data/dns/adguardhome/conf:/opt/adguardhome/conf
      - ../../data/dns/adguardhome/work:/opt/adguardhome/work
    profiles:
      - dns
    depends_on:
      - tailscale-dns
  tailscale-dns:
    container_name: tailscale-dns
    image: tailscale/tailscale:stable
    volumes:
      - ../../data/dns/tailscale:/var/lib
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - net_admin
      - sys_module
    env_file:
      - .env
      - .env.local
    command: tailscaled
    privileged: true
    restart: unless-stopped
    profiles:
      - dns
    networks:
      - dns
networks:
  dns:
    name: dns

In the .env file, I only have these variables set:

TS_ACCEPT_DNS=true
TS_AUTH_KEY=<your auth key>
TS_AUTH_ONCE=false
TS_STATE_DIR=/var/lib/tailscale
TS_USERSPACE=false

@snomiao
Copy link

snomiao commented Oct 9, 2024

Caddy proxy approach

My currently solution for those DNS is setup a local proxy that forward **.fbi.com into correct machine and localservices.

And access local network services by https://<service-name>.<machine-name>.fbi.com

Example

  1. install caddy server https://caddyserver.com/
  2. setup Caddyfile and run it when system start

a example Caddyfile for reference: (same config for every hosts)

{
	servers {
		trusted_proxies static 0.0.0.0/0
	}
}

# route fbi internal
https://127.0.0.1, https://localhost {
	tls internal
	redir https://fbi.com
}
https://fbi.com {
	tls internal
	reverse_proxy http://fbi.com {
		header_up Host fbi.com
	}
}
# forward HTTPS -> HTTP
https://*.fbi.com {
	tls internal
	@proxyhostport header_regexp subdomains Host (.+?).fbi.com
	reverse_proxy @proxyhostport http://fbi.com {
		header_up Host {re.subdomains.1}.fbi.com
	}
}
http://*.fbi.com {
	respond 502
}

# ====================================================
# hosts

# route to hosts
https://*.host1.fbi.com {
	tls internal
	@proxyhostport header_regexp service Host (.+?).host1.fbi.com
	reverse_proxy @proxyhostport http://host1 {
		header_up Host {re.service.1}.fbi.com
	}
}
https://*.host2.fbi.com {
	tls internal
	@proxyhostport header_regexp service Host (.+?).host2.fbi.com
	reverse_proxy @proxyhostport http://host2 {
		header_up Host {re.service.1}.fbi.com
	}
}
https://*.host3.fbi.com {
	tls internal
	@proxyhostport header_regexp service Host (.+?).host3.fbi.com
	reverse_proxy @proxyhostport http://host3 {
		header_up Host {re.service.1}.fbi.com
	}
}

# ==================================================
# services
# route to services
http://vscode.fbi.com {
	# hack: fix xfh for code
	@xfh header_regexp xfh X-Forwarded-Host (.*)
	reverse_proxy @xfh :8000 {
		header_up X-Forwarded-Host {re.xfh.1}
	}
	reverse_proxy :8000
}

# activitywatch
http://activitywatch.fbi.com {
	reverse_proxy :5600
}
# alias
http://aw.fbi.com {
	reverse_proxy :5600 {
		header_up Host localhost
	}
}

# everything
http://everything.fbi.com {
	reverse_proxy :2489
}
# alias
http://et.fbi.com {
	reverse_proxy :2489
}
  1. and then for example, you can access aw service by

activitywatch on localhost
https://aw.fbi.com/#/home

activitywatch on host1
https://aw.host1.fbi.com/#/home

activitywatch on host2
https://aw.host2.fbi.com/#/home

https://aw.jr.fbi.com https://vscode.fbi.com
image image

extend

Btw you could also expose this network into public by forwarding into *.<your-domain> to *.fbi.com

Hopefully someone could enjoy this (bad) idea.

references

@prostolyubo
Copy link

Guys, those are really nice WORKAROUNDS, but the idea here is to request Tailscale to implement a solution that would not require from us to make such a workarounds and greatly simplify the process.

@sbrocket
Copy link

sbrocket commented Oct 9, 2024

references

The fact that whoever owns fbi.com directed it at 127.0.0.1 is funny, but it is a really bad idea to rely on a domain you don’t control and which you can’t issue anything more than locally-trusted certificates for.

That will not give you HTTPS worth the name and is not a setup I’d recommend to anyone, especially someone setting up Tailscale and so presumably interested in a solid security posture. This setup is just begging for the admin to not actually distribute that locally-trusted Caddy root to the hosts that will access these services and instead have users just regularly click through the HTTPS not trusted prompts, intentionally or otherwise, which in turn is just asking for whoever owns fbi.com to change their A record and MitM you.

Don’t try to get clever with security unless you are really sure about what you’re doing. It is so easy to get wrong.

Tailscale team: If you needed more justification for why this feature is important than the hundreds of votes here, this should be it. This is complex enough that people are going to get it wrong in subtle but important ways and end up with insecure setups, and we’re well past the “people copying configurations around without fully understanding them” stage here.

@sevenrats
Copy link

sevenrats commented Oct 13, 2024

is there any fundamental blocker to this? i noticed the TODO here:

// TODO: more

My two cents is this:
I would implement cnames probably if I had any indicator that it would be accepted (and its not blocked by stuff thats over my head).
It would also be cool to automatically return records for machines with a specific tag. like if I lookup a particular record, x.domain.tld, then an A record would be returned for every machine with the tag tag:dns:x
or even something super cool like tag:dns:roundrobin:x versus tag:dns:failover:x

@almereyda
Copy link

The use case for resolving tags is tracked in #4324.

@dolceAlka
Copy link

This would be great short even for workarounds. Because tailscale uses ULA addressing for IPv6, validating resolvers will not resolve domains because of potential dns rebinding attacks. Short of migrating the entire tailscale addressing scheme, it would be ideal to have this.

@jucor
Copy link

jucor commented Nov 13, 2024

For anyone needing these custom record, wouldn't TSDProxy solve the issue? It was advertised in Tailscale November newsletter. @almeidapaulopt , what do you think ?

@madscientist16
Copy link

Your link points to the wrong page https://almeidapaulopt.github.io/tsdproxy/

Also from what I understand tsdproxy only works for containers. It does help somewhat since I won't need to create a seperate tailscale container for each service.

@almeidapaulopt
Copy link

Your link points to the wrong page https://almeidapaulopt.github.io/tsdproxy/

Also from what I understand tsdproxy only works for containers. It does help somewhat since I won't need to create a seperate tailscale container for each service.

this will change soon. you'll be able to add services that aren't running in docker

@marjacob
Copy link

I need custom SRV and TXT records for my use case. As far as I can see tsdproxy won't be able to help with that?

@jucor
Copy link

jucor commented Nov 14, 2024

@madscientist16 thanks for the flag on the link, fixed!

@dolceAlka
Copy link

For anyone needing these custom record, wouldn't TSDProxy solve the issue? It was advertised in Tailscale November newsletter. @almeidapaulopt , what do you think ?

It would be much better to handle this outside of a specific niche project, and allow for more flexible domaining and analytics

@jucor
Copy link

jucor commented Nov 14, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fr Feature request L3 Some users Likelihood P2 Aggravating Priority level T0 New feature Issue type
Projects
None yet
Development

No branches or pull requests