mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-31 08:01:34 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # DNS
 | |
| 
 | |
| Headscale supports [most DNS features](../about/features.md) from Tailscale. DNS related settings can be configured
 | |
| within `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/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 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.78.3/ipn/ipnlocal/local.go#L4461-L4479).
 | |
| 
 | |
| 
 | |
| 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
 | |
|               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.
 | |
| 
 | |
| 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:
 | |
| 
 | |
|     ```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;
 | |
|         }
 | |
| 
 | |
|     }
 | |
|     ```
 |