diff --git a/config-example.yaml b/config-example.yaml index 4cd33f6c..b0db5d1d 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -235,6 +235,17 @@ dns_config: # Search domains to inject. domains: [] + # Extra DNS records + # so far only A-records are supported (on the tailscale side) + # See https://github.com/juanfont/headscale/blob/main/docs/dns-records.md#Limitations + # extra_records: + # - name: "grafana.myvpn.example.com" + # type: "A" + # value: "100.64.0.3" + # + # # you can also put it in one line + # - { name: "prometheus.myvpn.example.com", type: "A", value: "100.64.0.3" } + # Whether to use [MagicDNS](https://tailscale.com/kb/1081/magicdns/). # Only works if there is at least a nameserver defined. magic_dns: true diff --git a/docs/README.md b/docs/README.md index dfad6116..f215e80f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -29,6 +29,7 @@ written by community members. It is _not_ verified by `headscale` developers. - [Running headscale in a container](running-headscale-container.md) - [Running headscale on OpenBSD](running-headscale-openbsd.md) - [Running headscale behind a reverse proxy](reverse-proxy.md) +- [Set Custom DNS records](dns-records.md) ## Misc diff --git a/docs/dns-records.md b/docs/dns-records.md new file mode 100644 index 00000000..530590bc --- /dev/null +++ b/docs/dns-records.md @@ -0,0 +1,83 @@ +# Setting custom DNS records + +## Goal + +This documentation has the goal of showing how a user can set custom DNS records client with `headscale`s magic dns. +An example usecase is to serve apps on the same host via a reverse proxy like NGinX, in this case a prometheus monitoring stack. This allows to nicely access the service with "http://grafana.myvpn.example.com" instead of the hostname and portnum combination "http://hostname-in-magic-dns.myvpn.example.com:3000". + +## Setup + +### Change the configuration + +1. Change the `config.yaml` to contain the desired records like so: + +```yaml +dns_config: + ... + extra_records: + - name: "prometheus.myvpn.example.com" + type: "A" + value: "100.64.0.3" + + - name: "grafana.myvpn.example.com" + type: "A" + value: "100.64.0.3" + ... +``` + +Restart your headscale instance. + +Beware of the limitations listed later on! + +### Verify that the records are set + +You can use a DNS querying tool of your choice on one of your hosts to verify that your newly set records are actually available in MagicDNS, here we used [`dig`](https://man.archlinux.org/man/dig.1.en): + +``` +$ dig grafana.myvpn.example.com + +; <<>> DiG 9.18.10 <<>> grafana.myvpn.example.com +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44054 +;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 65494 +;; QUESTION SECTION: +;grafana.myvpn.example.com. IN A + +;; ANSWER SECTION: +grafana.myvpn.example.com. 593 IN A 100.64.0.3 + +;; Query time: 0 msec +;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP) +;; WHEN: Sat Dec 31 11:46:55 CET 2022 +;; MSG SIZE rcvd: 66 +``` + +### Optional: Setup the reverse proxy + +The motivating example here was to be able to access internal monitoring services on the same host without specifying a port: + +``` +server { + listen 80; + listen [::]:80; + + server_name grafana.myvpn.example.com; + + location / { + proxy_pass http://localhost:3000; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + +} +``` + +## Limitations + +[Not all types of Records are Supported](https://github.com/tailscale/tailscale/blob/main/ipn/ipnlocal/local.go#L2891-L2909), especially no CNAME records.