Reformat docs with mdformat

This commit is contained in:
Florian Preinstorfer
2026-02-20 21:59:29 +01:00
committed by nblock
parent 47307d19cf
commit acddd73183
17 changed files with 120 additions and 121 deletions

View File

@@ -257,9 +257,11 @@ Includes devices where the same user is authenticated on both the source and des
"dst": ["autogroup:self:*"]
}
```
*Using `autogroup:self` may cause performance degradation on the Headscale coordinator server in large deployments, as filter rules must be compiled per-node rather than globally and the current implementation is not very efficient.*
If you experience performance issues, consider using more specific ACL rules or limiting the use of `autogroup:self`.
```json
{
// The following rules allow internal users to communicate with their

View File

@@ -1,4 +1,5 @@
# API
Headscale provides a [HTTP REST API](#rest-api) and a [gRPC interface](#grpc) which may be used to integrate a [web
interface](integration/web-ui.md), [remote control Headscale](#setup-remote-control) or provide a base for custom
integration and tooling.
@@ -30,8 +31,7 @@ headscale apikeys expire --prefix <PREFIX>
- API endpoint: `/api/v1`, e.g. `https://headscale.example.com/api/v1`
- Documentation: `/swagger`, e.g. `https://headscale.example.com/swagger`
- Headscale Version: `/version`, e.g. `https://headscale.example.com/version`
- Authenticate using HTTP Bearer authentication by sending the [API key](#api) with the HTTP `Authorization: Bearer
<API_KEY>` header.
- Authenticate using HTTP Bearer authentication by sending the [API key](#api) with the HTTP `Authorization: Bearer <API_KEY>` header.
Start by [creating an API key](#api) and test it with the examples below. Read the API documentation provided by your
Headscale server at `/swagger` for details.
@@ -72,17 +72,17 @@ The gRPC interface can be used to control a Headscale instance from a remote mac
### Setup remote control
1. Download the [`headscale` binary from GitHub's release page](https://github.com/juanfont/headscale/releases). Make
sure to use the same version as on the server.
1. Download the [`headscale` binary from GitHub's release page](https://github.com/juanfont/headscale/releases). Make
sure to use the same version as on the server.
1. Put the binary somewhere in your `PATH`, e.g. `/usr/local/bin/headscale`
1. Put the binary somewhere in your `PATH`, e.g. `/usr/local/bin/headscale`
1. Make `headscale` executable: `chmod +x /usr/local/bin/headscale`
1. Make `headscale` executable: `chmod +x /usr/local/bin/headscale`
1. [Create an API key](#api) on the Headscale server.
1. [Create an API key](#api) on the Headscale server.
1. Provide the connection parameters for the remote Headscale server either via a minimal YAML configuration file or
via environment variables:
1. Provide the connection parameters for the remote Headscale server either via a minimal YAML configuration file or
via environment variables:
=== "Minimal YAML configuration file"
@@ -102,7 +102,7 @@ The gRPC interface can be used to control a Headscale instance from a remote mac
This instructs the `headscale` binary to connect to a remote instance at `<HEADSCALE_ADDRESS>:<PORT>`, instead of
connecting to the local instance.
1. Test the connection by listing all nodes:
1. Test the connection by listing all nodes:
```shell
headscale nodes list

View File

@@ -17,8 +17,8 @@
=== "View on GitHub"
* Development version: <https://github.com/juanfont/headscale/blob/main/config-example.yaml>
* Version {{ headscale.version }}: <https://github.com/juanfont/headscale/blob/v{{ headscale.version }}/config-example.yaml>
- Development version: <https://github.com/juanfont/headscale/blob/main/config-example.yaml>
- Version {{ headscale.version }}: https://github.com/juanfont/headscale/blob/v{{ headscale.version }}/config-example.yaml
=== "Download with `wget`"

View File

@@ -63,10 +63,10 @@ maps fetched via URL or to offer your own, custom DERP servers to nodes.
ID. You can explicitly disable a specific region by setting its region ID to `null`. The following sample
`derp.yaml` disables the New York DERP region (which has the region ID 1):
```yaml title="derp.yaml"
regions:
1: null
```
```yaml title="derp.yaml"
regions:
1: null
```
Use the following configuration to serve the default DERP map (excluding New York) to nodes:
@@ -165,11 +165,10 @@ Any Tailscale client may be used to introspect the DERP map and to check for con
Additional DERP related metrics and information is available via the [metrics and debug
endpoint](./debug.md#metrics-and-debug-endpoint).
[^1]:
This assumes that the default region code of the [configuration file](./configuration.md) is used.
## Limitations
- The embedded DERP server can't be used for Tailscale's captive portal checks as it doesn't support the `/generate_204`
endpoint via HTTP on port tcp/80.
- There are no speed or throughput optimisations, the main purpose is to assist in node connectivity.
[^1]: This assumes that the default region code of the [configuration file](./configuration.md) is used.

View File

@@ -25,7 +25,7 @@ hostname and port combination "http://hostname-in-magic-dns.myvpn.example.com:30
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:
1. Configure extra DNS records using one of the available configuration options:
=== "Static entries, via `dns.extra_records`"
@@ -66,12 +66,12 @@ hostname and port combination "http://hostname-in-magic-dns.myvpn.example.com:30
!!! tip "Good to know"
* The `dns.extra_records_path` option in the [configuration file](./configuration.md) needs to reference the
- 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.
- 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:
1. Verify that DNS records are properly set using the DNS querying tool of your choice:
=== "Query with dig"
@@ -87,7 +87,7 @@ hostname and port combination "http://hostname-in-magic-dns.myvpn.example.com:30
100.64.0.3
```
1. Optional: Setup the reverse proxy
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:

View File

@@ -40,9 +40,9 @@ A basic configuration connects Headscale to an identity provider and typically r
=== "Identity provider"
* Create a new confidential client (`Client ID`, `Client secret`)
* Add Headscale's OIDC callback URL as valid redirect URL: `https://headscale.example.com/oidc/callback`
* Configure additional parameters to improve user experience such as: name, description, logo, …
- Create a new confidential client (`Client ID`, `Client secret`)
- Add Headscale's OIDC callback URL as valid redirect URL: `https://headscale.example.com/oidc/callback`
- Configure additional parameters to improve user experience such as: name, description, logo, …
### Enable PKCE (recommended)
@@ -63,8 +63,8 @@ recommended and needs to be configured for Headscale and the identity provider a
=== "Identity provider"
* Enable PKCE for the headscale client
* Set the PKCE challenge method to "S256"
- Enable PKCE for the headscale client
- Set the PKCE challenge method to "S256"
### Authorize users with filters
@@ -75,11 +75,11 @@ are configured, a user needs to pass all of them.
=== "Allowed domains"
* Check the email domain of each authenticating user against the list of allowed domains and only authorize users
- Check the email domain of each authenticating user against the list of allowed domains and only authorize users
whose email domain matches `example.com`.
* A verified email address is required [unless email verification is disabled](#control-email-verification).
* Access allowed: `alice@example.com`
* Access denied: `bob@example.net`
- A verified email address is required [unless email verification is disabled](#control-email-verification).
- Access allowed: `alice@example.com`
- Access denied: `bob@example.net`
```yaml hl_lines="5-6"
oidc:
@@ -92,11 +92,11 @@ are configured, a user needs to pass all of them.
=== "Allowed users/emails"
* Check the email address of each authenticating user against the list of allowed email addresses and only authorize
- Check the email address of each authenticating user against the list of allowed email addresses and only authorize
users whose email is part of the `allowed_users` list.
* A verified email address is required [unless email verification is disabled](#control-email-verification).
* Access allowed: `alice@example.com`, `bob@example.net`
* Access denied: `mallory@example.net`
- A verified email address is required [unless email verification is disabled](#control-email-verification).
- Access allowed: `alice@example.com`, `bob@example.net`
- Access denied: `mallory@example.net`
```yaml hl_lines="5-7"
oidc:
@@ -110,10 +110,10 @@ are configured, a user needs to pass all of them.
=== "Allowed groups"
* Use the OIDC `groups` claim of each authenticating user to get their group membership and only authorize users
- Use the OIDC `groups` claim of each authenticating user to get their group membership and only authorize users
which are members in at least one of the referenced groups.
* Access allowed: users in the `headscale_users` group
* Access denied: users without groups, users with other groups
- Access allowed: users in the `headscale_users` group
- Access denied: users without groups, users with other groups
```yaml hl_lines="5-7"
oidc:
@@ -163,7 +163,6 @@ Access Token.
Please keep in mind that the Access Token is typically a short-lived token that expires within a few minutes. You
will have to configure token expiration in your identity provider to avoid frequent re-authentication.
```yaml hl_lines="5"
oidc:
issuer: "https://sso.example.com"
@@ -175,6 +174,7 @@ Access Token.
!!! tip "Expire a node and force re-authentication"
A node can be expired immediately via:
```console
headscale node expire -i <NODE_ID>
```
@@ -303,16 +303,16 @@ Console.
#### Steps
1. Go to [Google Console](https://console.cloud.google.com) and login or create an account if you don't have one.
2. Create a project (if you don't already have one).
3. On the left hand menu, go to `APIs and services` -> `Credentials`
4. Click `Create Credentials` -> `OAuth client ID`
5. Under `Application Type`, choose `Web Application`
6. For `Name`, enter whatever you like
7. Under `Authorised redirect URIs`, add Headscale's OIDC callback URL: `https://headscale.example.com/oidc/callback`
8. Click `Save` at the bottom of the form
9. Take note of the `Client ID` and `Client secret`, you can also download it for reference if you need it.
10. [Configure Headscale following the "Basic configuration" steps](#basic-configuration). The issuer URL for Google
OAuth is: `https://accounts.google.com`.
1. Create a project (if you don't already have one).
1. On the left hand menu, go to `APIs and services` -> `Credentials`
1. Click `Create Credentials` -> `OAuth client ID`
1. Under `Application Type`, choose `Web Application`
1. For `Name`, enter whatever you like
1. Under `Authorised redirect URIs`, add Headscale's OIDC callback URL: `https://headscale.example.com/oidc/callback`
1. Click `Save` at the bottom of the form
1. Take note of the `Client ID` and `Client secret`, you can also download it for reference if you need it.
1. [Configure Headscale following the "Basic configuration" steps](#basic-configuration). The issuer URL for Google
OAuth is: `https://accounts.google.com`.
### Kanidm
@@ -323,10 +323,10 @@ Console.
username which might be confusing as the username and email fields now contain values that look like an email address.
[Kanidm can be configured to send the short username as `preferred_username` attribute
instead](https://kanidm.github.io/kanidm/stable/integrations/oauth2.html#short-names):
```console
kanidm system oauth2 prefer-short-username <client name>
```
Once configured, the short username in Headscale will be `alice` and can be referred to as `alice@` in the policy.
```console
kanidm system oauth2 prefer-short-username <client name>
```
Once configured, the short username in Headscale will be `alice` and can be referred to as `alice@` in the policy.
### Keycloak

View File

@@ -136,6 +136,6 @@ Its best suited for automation.
tailscale up --login-server <YOUR_HEADSCALE_URL> --authkey <YOUR_AUTH_KEY>
```
The registration of a tagged node is complete and it should be listed as "online" in the output of `headscale nodes
list`. The "User" column displays `tagged-devices` as the owner of the node. See the "Tags" column for the list of
The registration of a tagged node is complete and it should be listed as "online" in the output of
`headscale nodes list`. The "User" column displays `tagged-devices` as the owner of the node. See the "Tags" column for the list of
assigned tags.

View File

@@ -50,7 +50,7 @@ Headscale uses [autocert](https://pkg.go.dev/golang.org/x/crypto/acme/autocert),
If you want to validate that certificate renewal completed successfully, this can be done either manually, or through external monitoring software. Two examples of doing this manually:
1. Open the URL for your headscale server in your browser of choice, and manually inspecting the expiry date of the certificate you receive.
2. Or, check remotely from CLI using `openssl`:
1. Or, check remotely from CLI using `openssl`:
```console
$ openssl s_client -servername [hostname] -connect [hostname]:443 | openssl x509 -noout -dates