mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-04 20:49:24 +09:00
dns.extra_records_path and derp.paths files ending in .json were decoded with encoding/json, so a comment or trailing comma in otherwise valid JSON made headscale refuse to load the file. Policy files already accept HuJSON regardless of extension. HuJSON is a superset of JSON, so standardizing .json input the same way as .hujson keeps every valid JSON file decoding exactly as before. Add tests for comments and trailing commas in extra records, in generic .json decoding and in ACL policies, and for comment markers inside string values. Fixes #3627
114 lines
4.2 KiB
Markdown
114 lines
4.2 KiB
Markdown
# DNS
|
|
|
|
Headscale supports [most DNS features](../about/features.md) from Tailscale. DNS related settings can be configured
|
|
within the `dns` section of the [configuration file](configuration.md).
|
|
|
|
## Setting extra DNS records
|
|
|
|
Headscale allows to set extra DNS records which are made available via
|
|
[MagicDNS](https://tailscale.com/docs/features/magicdns). Extra DNS records can be configured either via static entries
|
|
in the [configuration file](configuration.md) or from a JSON file that Headscale continuously watches for changes:
|
|
|
|
- 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.
|
|
|
|
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".
|
|
|
|
!!! warning "Limitations"
|
|
|
|
Currently, [only A and AAAA records are processed by Tailscale](https://github.com/tailscale/tailscale/blob/v1.86.5/ipn/ipnlocal/node_backend.go#L662).
|
|
|
|
1. Configure extra DNS records using one of the available configuration options:
|
|
|
|
=== "Static entries, via `dns.extra_records`"
|
|
|
|
```yaml title="config.yaml"
|
|
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`"
|
|
|
|
```json title="extra-records.json"
|
|
[
|
|
{
|
|
"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"
|
|
|
|
- The `dns.extra_records_path` option in the [configuration file](configuration.md) needs to reference the
|
|
file containing extra DNS records. Its extension picks the format: `.json`, `.hujson`, `.yaml` or `.yml`.
|
|
A `.json` file is read as [HuJSON](https://github.com/tailscale/hujson), so it may contain comments and
|
|
trailing commas.
|
|
- 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.
|
|
|
|
1. Verify that DNS records are properly set using the DNS querying tool of your choice:
|
|
|
|
=== "Query with dig"
|
|
|
|
```console
|
|
dig +short grafana.myvpn.example.com
|
|
100.64.0.3
|
|
```
|
|
|
|
=== "Query with drill"
|
|
|
|
```console
|
|
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:
|
|
|
|
```nginx title="nginx.conf"
|
|
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;
|
|
}
|
|
|
|
}
|
|
```
|