2024-10-10 15:24:04 +02:00
# DNS
2024-12-16 07:07:53 +01:00
Headscale supports [most DNS features ](../about/features.md ) from Tailscale. DNS releated settings can be configured
within `dns` section of the [configuration file ](./configuration.md ).
2024-10-10 15:24:04 +02:00
2024-12-16 07:07:53 +01:00
## Setting extra DNS records
2024-10-10 15:24:04 +02:00
2024-12-16 07:07:53 +01:00
Headscale allows to set extra DNS records which are made available via
[MagicDNS ](https://tailscale.com/kb/1081/magicdns ). Extra DNS records can be configured either via static entries in the
[configuration file ](./configuration.md ) or from a JSON file that Headscale continously watches for changes:
2024-10-10 15:24:04 +02:00
2024-12-16 07:07:53 +01:00
* Use the `dns.extra_records` option in the [configuration file ](./configuration.md ) for entries that are static and
don't change while Headscale is running. Those entries are processed when Headscale is starting up and changes to the
configuration require a restart of Headscale.
* For dynamic DNS records that may be added, updated or removed while Headscale is running or DNS records that are
generated by scripts the option `dns.extra_records_path` in the [configuration file ](./configuration.md ) is useful.
Set it to the absolute path of the JSON file containing DNS records and Headscale processes this file as it detects
changes.
2024-10-10 15:24:04 +02:00
2024-12-16 07:07:53 +01:00
An example use case is to serve multiple 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 port combination "http://hostname-in-magic-dns.myvpn.example.com:3000".
2024-10-10 15:24:04 +02:00
!!! warning "Limitations"
2024-12-16 07:07:53 +01:00
Currently, [only A and AAAA records are processed by Tailscale ](https://github.com/tailscale/tailscale/blob/v1.78.3/ipn/ipnlocal/local.go#L4461-L4479 ).
2024-10-10 15:24:04 +02:00
2024-12-16 07:07:53 +01:00
1. Configure extra DNS records using one of the available configuration options:
2024-10-10 15:24:04 +02:00
2024-12-16 07:07:53 +01:00
=== "Static entries, via `dns.extra_records` "
2024-12-17 07:30:21 +01:00
```yaml title="config.yaml"
2024-12-16 07:07:53 +01:00
dns:
...
extra_records:
- name: "grafana.myvpn.example.com"
type: "A"
value: "100.64.0.3"
- name: "prometheus.myvpn.example.com"
type: "A"
value: "100.64.0.3"
...
```
Restart your headscale instance.
=== "Dynamic entries, via `dns.extra_records_path` "
2024-12-17 07:30:21 +01:00
```json title="extra-records.json"
2024-12-16 07:07:53 +01:00
[
{
"name": "grafana.myvpn.example.com",
"type": "A",
"value": "100.64.0.3"
},
{
"name": "prometheus.myvpn.example.com",
"type": "A",
"value": "100.64.0.3"
}
]
```
Headscale picks up changes to the above JSON file automatically.
!!! tip "Good to know"
2024-10-10 15:24:04 +02:00
2024-12-16 07:07:53 +01:00
* The `dns.extra_records_path` option in the [configuration file ](./configuration.md ) needs to reference the
JSON file containing extra DNS records.
* Be sure to "sort keys" and produce a stable output in case you generate the JSON file with a script.
Headscale uses a checksum to detect changes to the file and a stable output avoids unnecessary processing.
2024-10-10 15:24:04 +02:00
1. Verify that DNS records are properly set using the DNS querying tool of your choice:
=== "Query with dig"
```shell
dig +short grafana.myvpn.example.com
100.64.0.3
```
=== "Query with drill"
```shell
drill -Q grafana.myvpn.example.com
100.64.0.3
```
1. 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, depicted as NGINX configuration snippet:
2024-12-17 07:30:21 +01:00
```nginx title="nginx.conf"
2024-10-10 15:24:04 +02:00
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;
}
}
```