From 3199058dadeae3d721910f8cd6c8a6ea2eefecb1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 28 Nov 2025 20:28:24 +0000 Subject: [PATCH] Deployed f00c412c to development with MkDocs 1.6.1 and mike 2.1.3 --- development/404.html | 2 +- development/about/clients/index.html | 2 +- development/about/contributing/index.html | 2 +- development/about/faq/index.html | 2 +- development/about/features/index.html | 2 +- development/about/help/index.html | 2 +- development/about/releases/index.html | 2 +- development/about/sponsor/index.html | 2 +- development/assets/favicon.png | Bin 0 -> 22340 bytes .../images/headscale-acl-network.png | Bin .../{ => assets}/logo/headscale3-dots.pdf | Bin .../{ => assets}/logo/headscale3-dots.png | Bin .../{ => assets}/logo/headscale3-dots.svg | 0 .../logo/headscale3_header_stacked_left.pdf | Bin .../logo/headscale3_header_stacked_left.png | Bin .../logo/headscale3_header_stacked_left.svg | 0 development/index.html | 2 +- development/ref/acls/index.html | 4 +- development/ref/api/index.html | 2 +- development/ref/configuration/index.html | 2 +- development/ref/debug/index.html | 2 +- development/ref/derp/index.html | 2 +- development/ref/dns/index.html | 2 +- .../ref/integration/reverse-proxy/index.html | 2 +- development/ref/integration/tools/index.html | 2 +- development/ref/integration/web-ui/index.html | 2 +- development/ref/oidc/index.html | 2 +- development/ref/routes/index.html | 2 +- development/ref/tls/index.html | 2 +- .../setup/install/community/index.html | 2 +- .../setup/install/container/index.html | 2 +- development/setup/install/official/index.html | 2 +- development/setup/install/source/index.html | 2 +- development/setup/requirements/index.html | 2 +- development/setup/upgrade/index.html | 2 +- development/sitemap.xml | 60 +++++++++--------- development/sitemap.xml.gz | Bin 433 -> 433 bytes development/usage/connect/android/index.html | 2 +- development/usage/connect/apple/index.html | 2 +- development/usage/connect/windows/index.html | 2 +- development/usage/getting-started/index.html | 2 +- versions.json | 4 +- 42 files changed, 64 insertions(+), 64 deletions(-) create mode 100644 development/assets/favicon.png rename development/{ => assets}/images/headscale-acl-network.png (100%) rename development/{ => assets}/logo/headscale3-dots.pdf (100%) rename development/{ => assets}/logo/headscale3-dots.png (100%) rename development/{ => assets}/logo/headscale3-dots.svg (100%) rename development/{ => assets}/logo/headscale3_header_stacked_left.pdf (100%) rename development/{ => assets}/logo/headscale3_header_stacked_left.png (100%) rename development/{ => assets}/logo/headscale3_header_stacked_left.svg (100%) diff --git a/development/404.html b/development/404.html index 6d43edec..75a3697c 100644 --- a/development/404.html +++ b/development/404.html @@ -1 +1 @@ - Headscale

404 - Not found

\ No newline at end of file + Headscale

404 - Not found

\ No newline at end of file diff --git a/development/about/clients/index.html b/development/about/clients/index.html index 3279a1b9..629f9356 100644 --- a/development/about/clients/index.html +++ b/development/about/clients/index.html @@ -1 +1 @@ - Clients - Headscale
Skip to content

Client and operating system support

We aim to support the last 10 releases of the Tailscale client on all provided operating systems and platforms. Some platforms might require additional configuration to connect with headscale.

OS Supports headscale
Linux Yes
OpenBSD Yes
FreeBSD Yes
Windows Yes (see docs and /windows on your headscale for more information)
Android Yes (see docs for more information)
macOS Yes (see docs and /apple on your headscale for more information)
iOS Yes (see docs and /apple on your headscale for more information)
tvOS Yes (see docs and /apple on your headscale for more information)
\ No newline at end of file + Clients - Headscale
Skip to content

Client and operating system support

We aim to support the last 10 releases of the Tailscale client on all provided operating systems and platforms. Some platforms might require additional configuration to connect with headscale.

OS Supports headscale
Linux Yes
OpenBSD Yes
FreeBSD Yes
Windows Yes (see docs and /windows on your headscale for more information)
Android Yes (see docs for more information)
macOS Yes (see docs and /apple on your headscale for more information)
iOS Yes (see docs and /apple on your headscale for more information)
tvOS Yes (see docs and /apple on your headscale for more information)
\ No newline at end of file diff --git a/development/about/contributing/index.html b/development/about/contributing/index.html index 097496f2..8448baab 100644 --- a/development/about/contributing/index.html +++ b/development/about/contributing/index.html @@ -1 +1 @@ - Contributing - Headscale
Skip to content

Contributing

Headscale is "Open Source, acknowledged contribution", this means that any contribution will have to be discussed with the maintainers before being added to the project. This model has been chosen to reduce the risk of burnout by limiting the maintenance overhead of reviewing and validating third-party code.

Why do we have this model?

Headscale has a small maintainer team that tries to balance working on the project, fixing bugs and reviewing contributions.

When we work on issues ourselves, we develop first hand knowledge of the code and it makes it possible for us to maintain and own the code as the project develops.

Code contributions are seen as a positive thing. People enjoy and engage with our project, but it also comes with some challenges; we have to understand the code, we have to understand the feature, we might have to become familiar with external libraries or services and we think about security implications. All those steps are required during the reviewing process. After the code has been merged, the feature has to be maintained. Any changes reliant on external services must be updated and expanded accordingly.

The review and day-1 maintenance adds a significant burden on the maintainers. Often we hope that the contributor will help out, but we found that most of the time, they disappear after their new feature was added.

This means that when someone contributes, we are mostly happy about it, but we do have to run it through a series of checks to establish if we actually can maintain this feature.

What do we require?

A general description is provided here and an explicit list is provided in our pull request template.

All new features have to start out with a design document, which should be discussed on the issue tracker (not discord). It should include a use case for the feature, how it can be implemented, who will implement it and a plan for maintaining it.

All features have to be end-to-end tested (integration tests) and have good unit test coverage to ensure that they work as expected. This will also ensure that the feature continues to work as expected over time. If a change cannot be tested, a strong case for why this is not possible needs to be presented.

The contributor should help to maintain the feature over time. In case the feature is not maintained probably, the maintainers reserve themselves the right to remove features they redeem as unmaintainable. This should help to improve the quality of the software and keep it in a maintainable state.

Bug fixes

Headscale is open to code contributions for bug fixes without discussion.

Documentation

If you find mistakes in the documentation, please submit a fix to the documentation.

\ No newline at end of file + Contributing - Headscale
Skip to content

Contributing

Headscale is "Open Source, acknowledged contribution", this means that any contribution will have to be discussed with the maintainers before being added to the project. This model has been chosen to reduce the risk of burnout by limiting the maintenance overhead of reviewing and validating third-party code.

Why do we have this model?

Headscale has a small maintainer team that tries to balance working on the project, fixing bugs and reviewing contributions.

When we work on issues ourselves, we develop first hand knowledge of the code and it makes it possible for us to maintain and own the code as the project develops.

Code contributions are seen as a positive thing. People enjoy and engage with our project, but it also comes with some challenges; we have to understand the code, we have to understand the feature, we might have to become familiar with external libraries or services and we think about security implications. All those steps are required during the reviewing process. After the code has been merged, the feature has to be maintained. Any changes reliant on external services must be updated and expanded accordingly.

The review and day-1 maintenance adds a significant burden on the maintainers. Often we hope that the contributor will help out, but we found that most of the time, they disappear after their new feature was added.

This means that when someone contributes, we are mostly happy about it, but we do have to run it through a series of checks to establish if we actually can maintain this feature.

What do we require?

A general description is provided here and an explicit list is provided in our pull request template.

All new features have to start out with a design document, which should be discussed on the issue tracker (not discord). It should include a use case for the feature, how it can be implemented, who will implement it and a plan for maintaining it.

All features have to be end-to-end tested (integration tests) and have good unit test coverage to ensure that they work as expected. This will also ensure that the feature continues to work as expected over time. If a change cannot be tested, a strong case for why this is not possible needs to be presented.

The contributor should help to maintain the feature over time. In case the feature is not maintained probably, the maintainers reserve themselves the right to remove features they redeem as unmaintainable. This should help to improve the quality of the software and keep it in a maintainable state.

Bug fixes

Headscale is open to code contributions for bug fixes without discussion.

Documentation

If you find mistakes in the documentation, please submit a fix to the documentation.

\ No newline at end of file diff --git a/development/about/faq/index.html b/development/about/faq/index.html index 15c9d89b..553be64f 100644 --- a/development/about/faq/index.html +++ b/development/about/faq/index.html @@ -1 +1 @@ - FAQ - Headscale
Skip to content

Frequently Asked Questions

What is the design goal of headscale?

Headscale aims to implement a self-hosted, open source alternative to the Tailscale control server. Headscale's goal is to provide self-hosters and hobbyists with an open-source server they can use for their projects and labs. It implements a narrow scope, a single Tailscale network (tailnet), suitable for a personal use, or a small open-source organisation.

How can I contribute?

Headscale is "Open Source, acknowledged contribution", this means that any contribution will have to be discussed with the Maintainers before being submitted.

Please see Contributing for more information.

Why is 'acknowledged contribution' the chosen model?

Both maintainers have full-time jobs and families, and we want to avoid burnout. We also want to avoid frustration from contributors when their PRs are not accepted.

We are more than happy to exchange emails, or to have dedicated calls before a PR is submitted.

When/Why is Feature X going to be implemented?

We don't know. We might be working on it. If you're interested in contributing, please post a feature request about it.

Please be aware that there are a number of reasons why we might not accept specific contributions:

  • It is not possible to implement the feature in a way that makes sense in a self-hosted environment.
  • Given that we are reverse-engineering Tailscale to satisfy our own curiosity, we might be interested in implementing the feature ourselves.
  • You are not sending unit and integration tests with it.

Do you support Y method of deploying headscale?

We currently support deploying headscale using our binaries and the DEB packages. Visit our installation guide using official releases for more information.

In addition to that, you may use packages provided by the community or from distributions. Learn more in the installation guide using community packages.

For convenience, we also build container images with headscale. But please be aware that we don't officially support deploying headscale using Docker. On our Discord server we have a "docker-issues" channel where you can ask for Docker-specific help to the community.

Please follow the steps outlined in the upgrade guide to update your existing Headscale installation. Its best to update from one stable version to the next (e.g. 0.24.0 → 0.25.1 → 0.26.1) in case you are multiple releases behind. You should always pick the latest available patch release.

Be sure to check the changelog for version specific upgrade instructions and breaking changes.

Scaling / How many clients does Headscale support?

It depends. As often stated, Headscale is not enterprise software and our focus is homelabbers and self-hosters. Of course, we do not prevent people from using it in a commercial/professional setting and often get questions about scaling.

Please note that when Headscale is developed, performance is not part of the consideration as the main audience is considered to be users with a modest amount of devices. We focus on correctness and feature parity with Tailscale SaaS over time.

To understand if you might be able to use Headscale for your use case, I will describe two scenarios in an effort to explain what is the central bottleneck of Headscale:

  1. An environment with 1000 servers

  2. they rarely "move" (change their endpoints)

  3. new nodes are added rarely

  4. An environment with 80 laptops/phones (end user devices)

  5. nodes move often, e.g. switching from home to office

Headscale calculates a map of all nodes that need to talk to each other, creating this "world map" requires a lot of CPU time. When an event that requires changes to this map happens, the whole "world" is recalculated, and a new "world map" is created for every node in the network.

This means that under certain conditions, Headscale can likely handle 100s of devices (maybe more), if there is little to no change happening in the network. For example, in Scenario 1, the process of computing the world map is extremely demanding due to the size of the network, but when the map has been created and the nodes are not changing, the Headscale instance will likely return to a very low resource usage until the next time there is an event requiring the new map.

In the case of Scenario 2, the process of computing the world map is less demanding due to the smaller size of the network, however, the type of nodes will likely change frequently, which would lead to a constant resource usage.

Headscale will start to struggle when the two scenarios overlap, e.g. many nodes with frequent changes will cause the resource usage to remain constantly high. In the worst case scenario, the queue of nodes waiting for their map will grow to a point where Headscale never will be able to catch up, and nodes will never learn about the current state of the world.

We expect that the performance will improve over time as we improve the code base, but it is not a focus. In general, we will never make the tradeoff to make things faster on the cost of less maintainable or readable code. We are a small team and have to optimise for maintainability.

Which database should I use?

We recommend the use of SQLite as database for headscale:

  • SQLite is simple to setup and easy to use
  • It scales well for all of headscale's use cases
  • Development and testing happens primarily on SQLite
  • PostgreSQL is still supported, but is considered to be in "maintenance mode"

The headscale project itself does not provide a tool to migrate from PostgreSQL to SQLite. Please have a look at the related tools documentation for migration tooling provided by the community.

The choice of database has little to no impact on the performance of the server, see Scaling / How many clients does Headscale support? for understanding how Headscale spends its resources.

Why is my reverse proxy not working with headscale?

We don't know. We don't use reverse proxies with headscale ourselves, so we don't have any experience with them. We have community documentation on how to configure various reverse proxies, and a dedicated "reverse-proxy-issues" channel on our Discord server where you can ask for help to the community.

Can I use headscale and tailscale on the same machine?

Running headscale on a machine that is also in the tailnet can cause problems with subnet routers, traffic relay nodes, and MagicDNS. It might work, but it is not supported.

Why do two nodes see each other in their status, even if an ACL allows traffic only in one direction?

A frequent use case is to allow traffic only from one node to another, but not the other way around. For example, the workstation of an administrator should be able to connect to all nodes but the nodes themselves shouldn't be able to connect back to the administrator's node. Why do all nodes see the administrator's workstation in the output of tailscale status?

This is essentially how Tailscale works. If traffic is allowed to flow in one direction, then both nodes see each other in their output of tailscale status. Traffic is still filtered according to the ACL, with the exception of tailscale ping which is always allowed in either direction.

See also https://tailscale.com/kb/1087/device-visibility.

My policy is stored in the database and Headscale refuses to start due to an invalid policy. How can I recover?

Headscale checks if the policy is valid during startup and refuses to start if it detects an error. The error message indicates which part of the policy is invalid. Follow these steps to fix your policy:

  • Dump the policy to a file: headscale policy get --bypass-grpc-and-access-database-directly > policy.json
  • Edit and fixup policy.json. Use the command headscale policy check --file policy.json to validate the policy.
  • Load the modified policy: headscale policy set --bypass-grpc-and-access-database-directly --file policy.json
  • Start Headscale as usual.

Full server configuration required

The above commands to get/set the policy require a complete server configuration file including database settings. A minimal config to control Headscale via remote CLI is not sufficient. You may use headscale -c /path/to/config.yaml to specify the path to an alternative configuration file.

How can I avoid to send logs to Tailscale Inc?

A Tailscale client collects logs about its operation and connection attempts with other clients and sends them to a central log service operated by Tailscale Inc.

Headscale, by default, instructs clients to disable log submission to the central log service. This configuration is applied by a client once it successfully connected with Headscale. See the configuration option logtail.enabled in the configuration file for details.

Alternatively, logging can also be disabled on the client side. This is independent of Headscale and opting out of client logging disables log submission early during client startup. The configuration is operating system specific and is usually achieved by setting the environment variable TS_NO_LOGS_NO_SUPPORT=true or by passing the flag --no-logs-no-support to tailscaled. See https://tailscale.com/kb/1011/log-mesh-traffic#opting-out-of-client-logging for details.

\ No newline at end of file + FAQ - Headscale
Skip to content

Frequently Asked Questions

What is the design goal of headscale?

Headscale aims to implement a self-hosted, open source alternative to the Tailscale control server. Headscale's goal is to provide self-hosters and hobbyists with an open-source server they can use for their projects and labs. It implements a narrow scope, a single Tailscale network (tailnet), suitable for a personal use, or a small open-source organisation.

How can I contribute?

Headscale is "Open Source, acknowledged contribution", this means that any contribution will have to be discussed with the Maintainers before being submitted.

Please see Contributing for more information.

Why is 'acknowledged contribution' the chosen model?

Both maintainers have full-time jobs and families, and we want to avoid burnout. We also want to avoid frustration from contributors when their PRs are not accepted.

We are more than happy to exchange emails, or to have dedicated calls before a PR is submitted.

When/Why is Feature X going to be implemented?

We don't know. We might be working on it. If you're interested in contributing, please post a feature request about it.

Please be aware that there are a number of reasons why we might not accept specific contributions:

  • It is not possible to implement the feature in a way that makes sense in a self-hosted environment.
  • Given that we are reverse-engineering Tailscale to satisfy our own curiosity, we might be interested in implementing the feature ourselves.
  • You are not sending unit and integration tests with it.

Do you support Y method of deploying headscale?

We currently support deploying headscale using our binaries and the DEB packages. Visit our installation guide using official releases for more information.

In addition to that, you may use packages provided by the community or from distributions. Learn more in the installation guide using community packages.

For convenience, we also build container images with headscale. But please be aware that we don't officially support deploying headscale using Docker. On our Discord server we have a "docker-issues" channel where you can ask for Docker-specific help to the community.

Please follow the steps outlined in the upgrade guide to update your existing Headscale installation. Its best to update from one stable version to the next (e.g. 0.24.0 → 0.25.1 → 0.26.1) in case you are multiple releases behind. You should always pick the latest available patch release.

Be sure to check the changelog for version specific upgrade instructions and breaking changes.

Scaling / How many clients does Headscale support?

It depends. As often stated, Headscale is not enterprise software and our focus is homelabbers and self-hosters. Of course, we do not prevent people from using it in a commercial/professional setting and often get questions about scaling.

Please note that when Headscale is developed, performance is not part of the consideration as the main audience is considered to be users with a modest amount of devices. We focus on correctness and feature parity with Tailscale SaaS over time.

To understand if you might be able to use Headscale for your use case, I will describe two scenarios in an effort to explain what is the central bottleneck of Headscale:

  1. An environment with 1000 servers

  2. they rarely "move" (change their endpoints)

  3. new nodes are added rarely

  4. An environment with 80 laptops/phones (end user devices)

  5. nodes move often, e.g. switching from home to office

Headscale calculates a map of all nodes that need to talk to each other, creating this "world map" requires a lot of CPU time. When an event that requires changes to this map happens, the whole "world" is recalculated, and a new "world map" is created for every node in the network.

This means that under certain conditions, Headscale can likely handle 100s of devices (maybe more), if there is little to no change happening in the network. For example, in Scenario 1, the process of computing the world map is extremely demanding due to the size of the network, but when the map has been created and the nodes are not changing, the Headscale instance will likely return to a very low resource usage until the next time there is an event requiring the new map.

In the case of Scenario 2, the process of computing the world map is less demanding due to the smaller size of the network, however, the type of nodes will likely change frequently, which would lead to a constant resource usage.

Headscale will start to struggle when the two scenarios overlap, e.g. many nodes with frequent changes will cause the resource usage to remain constantly high. In the worst case scenario, the queue of nodes waiting for their map will grow to a point where Headscale never will be able to catch up, and nodes will never learn about the current state of the world.

We expect that the performance will improve over time as we improve the code base, but it is not a focus. In general, we will never make the tradeoff to make things faster on the cost of less maintainable or readable code. We are a small team and have to optimise for maintainability.

Which database should I use?

We recommend the use of SQLite as database for headscale:

  • SQLite is simple to setup and easy to use
  • It scales well for all of headscale's use cases
  • Development and testing happens primarily on SQLite
  • PostgreSQL is still supported, but is considered to be in "maintenance mode"

The headscale project itself does not provide a tool to migrate from PostgreSQL to SQLite. Please have a look at the related tools documentation for migration tooling provided by the community.

The choice of database has little to no impact on the performance of the server, see Scaling / How many clients does Headscale support? for understanding how Headscale spends its resources.

Why is my reverse proxy not working with headscale?

We don't know. We don't use reverse proxies with headscale ourselves, so we don't have any experience with them. We have community documentation on how to configure various reverse proxies, and a dedicated "reverse-proxy-issues" channel on our Discord server where you can ask for help to the community.

Can I use headscale and tailscale on the same machine?

Running headscale on a machine that is also in the tailnet can cause problems with subnet routers, traffic relay nodes, and MagicDNS. It might work, but it is not supported.

Why do two nodes see each other in their status, even if an ACL allows traffic only in one direction?

A frequent use case is to allow traffic only from one node to another, but not the other way around. For example, the workstation of an administrator should be able to connect to all nodes but the nodes themselves shouldn't be able to connect back to the administrator's node. Why do all nodes see the administrator's workstation in the output of tailscale status?

This is essentially how Tailscale works. If traffic is allowed to flow in one direction, then both nodes see each other in their output of tailscale status. Traffic is still filtered according to the ACL, with the exception of tailscale ping which is always allowed in either direction.

See also https://tailscale.com/kb/1087/device-visibility.

My policy is stored in the database and Headscale refuses to start due to an invalid policy. How can I recover?

Headscale checks if the policy is valid during startup and refuses to start if it detects an error. The error message indicates which part of the policy is invalid. Follow these steps to fix your policy:

  • Dump the policy to a file: headscale policy get --bypass-grpc-and-access-database-directly > policy.json
  • Edit and fixup policy.json. Use the command headscale policy check --file policy.json to validate the policy.
  • Load the modified policy: headscale policy set --bypass-grpc-and-access-database-directly --file policy.json
  • Start Headscale as usual.

Full server configuration required

The above commands to get/set the policy require a complete server configuration file including database settings. A minimal config to control Headscale via remote CLI is not sufficient. You may use headscale -c /path/to/config.yaml to specify the path to an alternative configuration file.

How can I avoid to send logs to Tailscale Inc?

A Tailscale client collects logs about its operation and connection attempts with other clients and sends them to a central log service operated by Tailscale Inc.

Headscale, by default, instructs clients to disable log submission to the central log service. This configuration is applied by a client once it successfully connected with Headscale. See the configuration option logtail.enabled in the configuration file for details.

Alternatively, logging can also be disabled on the client side. This is independent of Headscale and opting out of client logging disables log submission early during client startup. The configuration is operating system specific and is usually achieved by setting the environment variable TS_NO_LOGS_NO_SUPPORT=true or by passing the flag --no-logs-no-support to tailscaled. See https://tailscale.com/kb/1011/log-mesh-traffic#opting-out-of-client-logging for details.

\ No newline at end of file diff --git a/development/about/features/index.html b/development/about/features/index.html index ca34580a..c1912681 100644 --- a/development/about/features/index.html +++ b/development/about/features/index.html @@ -1 +1 @@ - Features - Headscale
Skip to content

Features

Headscale aims to implement a self-hosted, open source alternative to the Tailscale control server. Headscale's goal is to provide self-hosters and hobbyists with an open-source server they can use for their projects and labs. This page provides on overview of Headscale's feature and compatibility with the Tailscale control server:

\ No newline at end of file + Features - Headscale
Skip to content

Features

Headscale aims to implement a self-hosted, open source alternative to the Tailscale control server. Headscale's goal is to provide self-hosters and hobbyists with an open-source server they can use for their projects and labs. This page provides on overview of Headscale's feature and compatibility with the Tailscale control server:

\ No newline at end of file diff --git a/development/about/help/index.html b/development/about/help/index.html index 801fd3e6..0a0bcc7c 100644 --- a/development/about/help/index.html +++ b/development/about/help/index.html @@ -1 +1 @@ - Getting help - Headscale
Skip to content
\ No newline at end of file + Getting help - Headscale
Skip to content
\ No newline at end of file diff --git a/development/about/releases/index.html b/development/about/releases/index.html index e03a20ac..ef308dfc 100644 --- a/development/about/releases/index.html +++ b/development/about/releases/index.html @@ -1 +1 @@ - Releases - Headscale
Skip to content

Releases

All headscale releases are available on the GitHub release page. Those releases are available as binaries for various platforms and architectures, packages for Debian based systems and source code archives. Container images are available on Docker Hub and GitHub Container Registry.

An Atom/RSS feed of headscale releases is available here.

See the "announcements" channel on our Discord server for news about headscale.

\ No newline at end of file + Releases - Headscale
Skip to content

Releases

All headscale releases are available on the GitHub release page. Those releases are available as binaries for various platforms and architectures, packages for Debian based systems and source code archives. Container images are available on Docker Hub and GitHub Container Registry.

An Atom/RSS feed of headscale releases is available here.

See the "announcements" channel on our Discord server for news about headscale.

\ No newline at end of file diff --git a/development/about/sponsor/index.html b/development/about/sponsor/index.html index 9c9e601d..898c9000 100644 --- a/development/about/sponsor/index.html +++ b/development/about/sponsor/index.html @@ -1 +1 @@ - Sponsor - Headscale
Skip to content

Sponsor

If you like to support the development of headscale, please consider a donation via ko-fi.com/headscale. Thank you!

\ No newline at end of file + Sponsor - Headscale
Skip to content

Sponsor

If you like to support the development of headscale, please consider a donation via ko-fi.com/headscale. Thank you!

\ No newline at end of file diff --git a/development/assets/favicon.png b/development/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..4989810faa546554d0e8a494ce8b980816c46b54 GIT binary patch literal 22340 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 H^o;*2r@Ea? literal 0 HcmV?d00001 diff --git a/development/images/headscale-acl-network.png b/development/assets/images/headscale-acl-network.png similarity index 100% rename from development/images/headscale-acl-network.png rename to development/assets/images/headscale-acl-network.png diff --git a/development/logo/headscale3-dots.pdf b/development/assets/logo/headscale3-dots.pdf similarity index 100% rename from development/logo/headscale3-dots.pdf rename to development/assets/logo/headscale3-dots.pdf diff --git a/development/logo/headscale3-dots.png b/development/assets/logo/headscale3-dots.png similarity index 100% rename from development/logo/headscale3-dots.png rename to development/assets/logo/headscale3-dots.png diff --git a/development/logo/headscale3-dots.svg b/development/assets/logo/headscale3-dots.svg similarity index 100% rename from development/logo/headscale3-dots.svg rename to development/assets/logo/headscale3-dots.svg diff --git a/development/logo/headscale3_header_stacked_left.pdf b/development/assets/logo/headscale3_header_stacked_left.pdf similarity index 100% rename from development/logo/headscale3_header_stacked_left.pdf rename to development/assets/logo/headscale3_header_stacked_left.pdf diff --git a/development/logo/headscale3_header_stacked_left.png b/development/assets/logo/headscale3_header_stacked_left.png similarity index 100% rename from development/logo/headscale3_header_stacked_left.png rename to development/assets/logo/headscale3_header_stacked_left.png diff --git a/development/logo/headscale3_header_stacked_left.svg b/development/assets/logo/headscale3_header_stacked_left.svg similarity index 100% rename from development/logo/headscale3_header_stacked_left.svg rename to development/assets/logo/headscale3_header_stacked_left.svg diff --git a/development/index.html b/development/index.html index 12dd64f5..f17c7eae 100644 --- a/development/index.html +++ b/development/index.html @@ -1 +1 @@ - Headscale

Welcome to headscale

Headscale is an open source, self-hosted implementation of the Tailscale control server.

This page contains the documentation for the latest version of headscale. Please also check our FAQ.

Join our Discord server for a chat and community support.

Design goal

Headscale aims to implement a self-hosted, open source alternative to the Tailscale control server. Headscale's goal is to provide self-hosters and hobbyists with an open-source server they can use for their projects and labs. It implements a narrow scope, a single Tailscale network (tailnet), suitable for a personal use, or a small open-source organisation.

Supporting headscale

Please see Sponsor for more information.

Contributing

Headscale is "Open Source, acknowledged contribution", this means that any contribution will have to be discussed with the Maintainers before being submitted.

Please see Contributing for more information.

About

Headscale is maintained by Kristoffer Dalby and Juan Font.

\ No newline at end of file + Headscale

Welcome to headscale

Headscale is an open source, self-hosted implementation of the Tailscale control server.

This page contains the documentation for the latest version of headscale. Please also check our FAQ.

Join our Discord server for a chat and community support.

Design goal

Headscale aims to implement a self-hosted, open source alternative to the Tailscale control server. Headscale's goal is to provide self-hosters and hobbyists with an open-source server they can use for their projects and labs. It implements a narrow scope, a single Tailscale network (tailnet), suitable for a personal use, or a small open-source organisation.

Supporting headscale

Please see Sponsor for more information.

Contributing

Headscale is "Open Source, acknowledged contribution", this means that any contribution will have to be discussed with the Maintainers before being submitted.

Please see Contributing for more information.

About

Headscale is maintained by Kristoffer Dalby and Juan Font.

\ No newline at end of file diff --git a/development/ref/acls/index.html b/development/ref/acls/index.html index 19b5ed7d..53cf4e8b 100644 --- a/development/ref/acls/index.html +++ b/development/ref/acls/index.html @@ -1,8 +1,8 @@ - ACLs - Headscale

ACLs

Headscale implements the same policy ACLs as Tailscale.com, adapted to the self-hosted environment.

For instance, instead of referring to users when defining groups you must use users (which are the equivalent to user/logins in Tailscale.com).

Please check https://tailscale.com/kb/1018/acls/ for further information.

When using ACL's the User borders are no longer applied. All machines whichever the User have the ability to communicate with other hosts as long as the ACL's permits this exchange.

ACL Setup

To enable and configure ACLs in Headscale, you need to specify the path to your ACL policy file in the policy.path key in config.yaml.

Your ACL policy file must be formatted using huJSON.

Info on how these policies are written can be found here.

Please reload or restart Headscale after updating the ACL file. Headscale may be reloaded either via its systemd service (sudo systemctl reload headscale) or by sending a SIGHUP signal (sudo kill -HUP $(pidof headscale)) to the main process. Headscale logs the result of ACL policy processing after each reload.

Simple Examples

  • Allow All: If you define an ACL file but completely omit the "acls" field from its content, Headscale will default to an "allow all" policy. This means all devices connected to your tailnet will be able to communicate freely with each other.

    {}
    + ACLs - Headscale      

    ACLs

    Headscale implements the same policy ACLs as Tailscale.com, adapted to the self-hosted environment.

    For instance, instead of referring to users when defining groups you must use users (which are the equivalent to user/logins in Tailscale.com).

    Please check https://tailscale.com/kb/1018/acls/ for further information.

    When using ACL's the User borders are no longer applied. All machines whichever the User have the ability to communicate with other hosts as long as the ACL's permits this exchange.

    ACL Setup

    To enable and configure ACLs in Headscale, you need to specify the path to your ACL policy file in the policy.path key in config.yaml.

    Your ACL policy file must be formatted using huJSON.

    Info on how these policies are written can be found here.

    Please reload or restart Headscale after updating the ACL file. Headscale may be reloaded either via its systemd service (sudo systemctl reload headscale) or by sending a SIGHUP signal (sudo kill -HUP $(pidof headscale)) to the main process. Headscale logs the result of ACL policy processing after each reload.

    Simple Examples

    • Allow All: If you define an ACL file but completely omit the "acls" field from its content, Headscale will default to an "allow all" policy. This means all devices connected to your tailnet will be able to communicate freely with each other.

      {}
       
    • Deny All: To prevent all communication within your tailnet, you can include an empty array for the "acls" field in your policy file.

      {
         "acls": []
       }
      -

    Complex Example

    Let's build a more complex example use case for a small business (It may be the place where ACL's are the most useful).

    We have a small company with a boss, an admin, two developers and an intern.

    The boss should have access to all servers but not to the user's hosts. Admin should also have access to all hosts except that their permissions should be limited to maintaining the hosts (for example purposes). The developers can do anything they want on dev hosts but only watch on productions hosts. Intern can only interact with the development servers.

    There's an additional server that acts as a router, connecting the VPN users to an internal network 10.20.0.0/16. Developers must have access to those internal resources.

    Each user have at least a device connected to the network and we have some servers.

    • database.prod
    • database.dev
    • app-server1.prod
    • app-server1.dev
    • billing.internal
    • router.internal

    ACL implementation example

    When registering the servers we will need to add the flag --advertise-tags=tag:<tag1>,tag:<tag2>, and the user that is registering the server should be allowed to do it. Since anyone can add tags to a server they can register, the check of the tags is done on headscale server and only valid tags are applied. A tag is valid if the user that is registering it is allowed to do it.

    Here are the ACL's to implement the same permissions as above:

    acl.json
    {
    +

Complex Example

Let's build a more complex example use case for a small business (It may be the place where ACL's are the most useful).

We have a small company with a boss, an admin, two developers and an intern.

The boss should have access to all servers but not to the user's hosts. Admin should also have access to all hosts except that their permissions should be limited to maintaining the hosts (for example purposes). The developers can do anything they want on dev hosts but only watch on productions hosts. Intern can only interact with the development servers.

There's an additional server that acts as a router, connecting the VPN users to an internal network 10.20.0.0/16. Developers must have access to those internal resources.

Each user have at least a device connected to the network and we have some servers.

  • database.prod
  • database.dev
  • app-server1.prod
  • app-server1.dev
  • billing.internal
  • router.internal

ACL implementation example

When registering the servers we will need to add the flag --advertise-tags=tag:<tag1>,tag:<tag2>, and the user that is registering the server should be allowed to do it. Since anyone can add tags to a server they can register, the check of the tags is done on headscale server and only valid tags are applied. A tag is valid if the user that is registering it is allowed to do it.

Here are the ACL's to implement the same permissions as above:

acl.json
{
   // groups are collections of users having a common scope. A user can be in multiple groups
   // groups cannot be composed of groups
   "groups": {
diff --git a/development/ref/api/index.html b/development/ref/api/index.html
index 3b34a970..3f0cc26f 100644
--- a/development/ref/api/index.html
+++ b/development/ref/api/index.html
@@ -1,4 +1,4 @@
- API - Headscale      

API

Headscale provides a HTTP REST API and a gRPC interface which may be used to integrate a web interface, remote control Headscale or provide a base for custom integration and tooling.

Both interfaces require a valid API key before use. To create an API key, log into your Headscale server and generate one with the default expiration of 90 days:

headscale apikeys create
+ API - Headscale      

API

Headscale provides a HTTP REST API and a gRPC interface which may be used to integrate a web interface, remote control Headscale or provide a base for custom integration and tooling.

Both interfaces require a valid API key before use. To create an API key, log into your Headscale server and generate one with the default expiration of 90 days:

headscale apikeys create
 

Copy the output of the command and save it for later. Please note that you can not retrieve an API key again. If the API key is lost, expire the old one, and create a new one.

To list the API keys currently associated with the server:

headscale apikeys list
 

and to expire an API key:

headscale apikeys expire --prefix <PREFIX>
 

REST API

  • API endpoint: /api/v1, e.g. https://headscale.example.com/api/v1
  • Documentation: /swagger, e.g. https://headscale.example.com/swagger
  • Authenticate using HTTP Bearer authentication by sending the API key with the HTTP Authorization: Bearer <API_KEY> header.

Start by creating an API key and test it with the examples below. Read the API documentation provided by your Headscale server at /swagger for details.

curl -H "Authorization: Bearer <API_KEY>" \
diff --git a/development/ref/configuration/index.html b/development/ref/configuration/index.html
index 78225cd9..0bbbe4a0 100644
--- a/development/ref/configuration/index.html
+++ b/development/ref/configuration/index.html
@@ -1,4 +1,4 @@
- Configuration - Headscale      

Configuration

  • Headscale loads its configuration from a YAML file
  • It searches for config.yaml in the following paths:
    • /etc/headscale
    • $HOME/.headscale
    • the current working directory
  • To load the configuration from a different path, use:
    • the command line flag -c, --config
    • the environment variable HEADSCALE_CONFIG
  • Validate the configuration file with: headscale configtest

Get the example configuration from the GitHub repository

Always select the same GitHub tag as the released version you use to ensure you have the correct example configuration. The main branch might contain unreleased changes.

# Development version
+ Configuration - Headscale      

Configuration

  • Headscale loads its configuration from a YAML file
  • It searches for config.yaml in the following paths:
    • /etc/headscale
    • $HOME/.headscale
    • the current working directory
  • To load the configuration from a different path, use:
    • the command line flag -c, --config
    • the environment variable HEADSCALE_CONFIG
  • Validate the configuration file with: headscale configtest

Get the example configuration from the GitHub repository

Always select the same GitHub tag as the released version you use to ensure you have the correct example configuration. The main branch might contain unreleased changes.

# Development version
 wget -O config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml
 
 # Version 0.27.1
diff --git a/development/ref/debug/index.html b/development/ref/debug/index.html
index b1f6b62a..13f6ca95 100644
--- a/development/ref/debug/index.html
+++ b/development/ref/debug/index.html
@@ -1,4 +1,4 @@
- Debug - Headscale      

Debugging and troubleshooting

Headscale and Tailscale provide debug and introspection capabilities that can be helpful when things don't work as expected. This page explains some debugging techniques to help pinpoint problems.

Please also have a look at Tailscale's Troubleshooting guide. It offers a many tips and suggestions to troubleshoot common issues.

Tailscale

The Tailscale client itself offers many commands to introspect its state as well as the state of the network:

Many of the commands are helpful when trying to understand differences between Headscale and Tailscale SaaS.

Headscale

Application logging

The log levels debug and trace can be useful to get more information from Headscale.

log:
+ Debug - Headscale      

Debugging and troubleshooting

Headscale and Tailscale provide debug and introspection capabilities that can be helpful when things don't work as expected. This page explains some debugging techniques to help pinpoint problems.

Please also have a look at Tailscale's Troubleshooting guide. It offers a many tips and suggestions to troubleshoot common issues.

Tailscale

The Tailscale client itself offers many commands to introspect its state as well as the state of the network:

Many of the commands are helpful when trying to understand differences between Headscale and Tailscale SaaS.

Headscale

Application logging

The log levels debug and trace can be useful to get more information from Headscale.

log:
   # Valid log levels: panic, fatal, error, warn, info, debug, trace
   level: debug
 

Database logging

The database debug mode logs all database queries. Enable it to see how Headscale interacts with its database. This also requires the application log level to be set to either debug or trace.

database:
diff --git a/development/ref/derp/index.html b/development/ref/derp/index.html
index 1d19b3cb..36ac9203 100644
--- a/development/ref/derp/index.html
+++ b/development/ref/derp/index.html
@@ -1,4 +1,4 @@
- DERP - Headscale      

DERP

A DERP (Designated Encrypted Relay for Packets) server is mainly used to relay traffic between two nodes in case a direct connection can't be established. Headscale provides an embedded DERP server to ensure seamless connectivity between nodes.

Configuration

DERP related settings are configured within the derp section of the configuration file. The following sections only use a few of the available settings, check the example configuration for all available configuration options.

Enable embedded DERP

Headscale ships with an embedded DERP server which allows to run your own self-hosted DERP server easily. The embedded DERP server is disabled by default and needs to be enabled. In addition, you should configure the public IPv4 and public IPv6 address of your Headscale server for improved connection stability:

config.yaml
derp:
+ DERP - Headscale      

DERP

A DERP (Designated Encrypted Relay for Packets) server is mainly used to relay traffic between two nodes in case a direct connection can't be established. Headscale provides an embedded DERP server to ensure seamless connectivity between nodes.

Configuration

DERP related settings are configured within the derp section of the configuration file. The following sections only use a few of the available settings, check the example configuration for all available configuration options.

Enable embedded DERP

Headscale ships with an embedded DERP server which allows to run your own self-hosted DERP server easily. The embedded DERP server is disabled by default and needs to be enabled. In addition, you should configure the public IPv4 and public IPv6 address of your Headscale server for improved connection stability:

config.yaml
derp:
   server:
     enabled: true
     ipv4: 198.51.100.1
diff --git a/development/ref/dns/index.html b/development/ref/dns/index.html
index cc0b0528..3d06cebb 100644
--- a/development/ref/dns/index.html
+++ b/development/ref/dns/index.html
@@ -1,4 +1,4 @@
- DNS - Headscale      

DNS

Headscale supports most DNS features from Tailscale. DNS related settings can be configured within the dns section of the configuration file.

Setting extra DNS records

Headscale allows to set extra DNS records which are made available via MagicDNS. Extra DNS records can be configured either via static entries in the configuration file or from a JSON file that Headscale continuously watches for changes:

  • Use the dns.extra_records option in the configuration file 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 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".

  1. Configure extra DNS records using one of the available configuration options:

    config.yaml
    dns:
    + DNS - Headscale      

    DNS

    Headscale supports most DNS features from Tailscale. DNS related settings can be configured within the dns section of the configuration file.

    Setting extra DNS records

    Headscale allows to set extra DNS records which are made available via MagicDNS. Extra DNS records can be configured either via static entries in the configuration file or from a JSON file that Headscale continuously watches for changes:

    • Use the dns.extra_records option in the configuration file 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 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".

    1. Configure extra DNS records using one of the available configuration options:

      config.yaml
      dns:
         ...
         extra_records:
           - name: "grafana.myvpn.example.com"
      diff --git a/development/ref/integration/reverse-proxy/index.html b/development/ref/integration/reverse-proxy/index.html
      index b377bb8c..ddcca1e8 100644
      --- a/development/ref/integration/reverse-proxy/index.html
      +++ b/development/ref/integration/reverse-proxy/index.html
      @@ -1,4 +1,4 @@
      - Reverse proxy - Headscale      

      Running headscale behind a reverse proxy

      Community documentation

      This page is not actively maintained by the headscale authors and is written by community members. It is not verified by headscale developers.

      It might be outdated and it might miss necessary steps.

      Running headscale behind a reverse proxy is useful when running multiple applications on the same server, and you want to reuse the same external IP and port - usually tcp/443 for HTTPS.

      WebSockets

      The reverse proxy MUST be configured to support WebSockets to communicate with Tailscale clients.

      WebSockets support is also required when using the Headscale embedded DERP server. In this case, you will also need to expose the UDP port used for STUN (by default, udp/3478). Please check our config-example.yaml.

      Cloudflare

      Running headscale behind a cloudflare proxy or cloudflare tunnel is not supported and will not work as Cloudflare does not support WebSocket POSTs as required by the Tailscale protocol. See this issue

      TLS

      Headscale can be configured not to use TLS, leaving it to the reverse proxy to handle. Add the following configuration values to your headscale config file.

      config.yaml
      server_url: https://<YOUR_SERVER_NAME> # This should be the FQDN at which headscale will be served
      + Reverse proxy - Headscale      

      Running headscale behind a reverse proxy

      Community documentation

      This page is not actively maintained by the headscale authors and is written by community members. It is not verified by headscale developers.

      It might be outdated and it might miss necessary steps.

      Running headscale behind a reverse proxy is useful when running multiple applications on the same server, and you want to reuse the same external IP and port - usually tcp/443 for HTTPS.

      WebSockets

      The reverse proxy MUST be configured to support WebSockets to communicate with Tailscale clients.

      WebSockets support is also required when using the Headscale embedded DERP server. In this case, you will also need to expose the UDP port used for STUN (by default, udp/3478). Please check our config-example.yaml.

      Cloudflare

      Running headscale behind a cloudflare proxy or cloudflare tunnel is not supported and will not work as Cloudflare does not support WebSocket POSTs as required by the Tailscale protocol. See this issue

      TLS

      Headscale can be configured not to use TLS, leaving it to the reverse proxy to handle. Add the following configuration values to your headscale config file.

      config.yaml
      server_url: https://<YOUR_SERVER_NAME> # This should be the FQDN at which headscale will be served
       listen_addr: 0.0.0.0:8080
       metrics_listen_addr: 0.0.0.0:9090
       tls_cert_path: ""
      diff --git a/development/ref/integration/tools/index.html b/development/ref/integration/tools/index.html
      index 78badc6d..bc35e34d 100644
      --- a/development/ref/integration/tools/index.html
      +++ b/development/ref/integration/tools/index.html
      @@ -1 +1 @@
      - Tools - Headscale      

      Tools related to headscale

      Community contributions

      This page contains community contributions. The projects listed here are not maintained by the headscale authors and are written by community members.

      This page collects third-party tools, client libraries, and scripts related to headscale.

      Name Repository Link Description
      tailscale-manager Github Dynamically manage Tailscale route advertisements
      headscalebacktosqlite Github Migrate headscale from PostgreSQL back to SQLite
      headscale-pf Github Populates user groups based on user groups in Jumpcloud or Authentik
      headscale-client-go Github A Go client implementation for the Headscale HTTP API.
      headscale-zabbix Github A Zabbix Monitoring Template for the Headscale Service.
      \ No newline at end of file + Tools - Headscale

      Tools related to headscale

      Community contributions

      This page contains community contributions. The projects listed here are not maintained by the headscale authors and are written by community members.

      This page collects third-party tools, client libraries, and scripts related to headscale.

      Name Repository Link Description
      tailscale-manager Github Dynamically manage Tailscale route advertisements
      headscalebacktosqlite Github Migrate headscale from PostgreSQL back to SQLite
      headscale-pf Github Populates user groups based on user groups in Jumpcloud or Authentik
      headscale-client-go Github A Go client implementation for the Headscale HTTP API.
      headscale-zabbix Github A Zabbix Monitoring Template for the Headscale Service.
      \ No newline at end of file diff --git a/development/ref/integration/web-ui/index.html b/development/ref/integration/web-ui/index.html index a99acf3c..e7a22240 100644 --- a/development/ref/integration/web-ui/index.html +++ b/development/ref/integration/web-ui/index.html @@ -1 +1 @@ - Web UI - Headscale

      Web interfaces for headscale

      Community contributions

      This page contains community contributions. The projects listed here are not maintained by the headscale authors and are written by community members.

      Headscale doesn't provide a built-in web interface but users may pick one from the available options.

      Name Repository Link Description
      headscale-ui Github A web frontend for the headscale Tailscale-compatible coordination server
      HeadscaleUi GitHub A static headscale admin ui, no backend environment required
      Headplane GitHub An advanced Tailscale inspired frontend for headscale
      headscale-admin Github Headscale-Admin is meant to be a simple, modern web interface for headscale
      ouroboros Github Ouroboros is designed for users to manage their own devices, rather than for admins
      unraid-headscale-admin Github A simple headscale admin UI for Unraid, it offers Local (docker exec) and API Mode
      headscale-console Github WebAssembly-based client supporting SSH, VNC and RDP with optional self-service capabilities

      You can ask for support on our Discord server in the "web-interfaces" channel.

      \ No newline at end of file + Web UI - Headscale

      Web interfaces for headscale

      Community contributions

      This page contains community contributions. The projects listed here are not maintained by the headscale authors and are written by community members.

      Headscale doesn't provide a built-in web interface but users may pick one from the available options.

      Name Repository Link Description
      headscale-ui Github A web frontend for the headscale Tailscale-compatible coordination server
      HeadscaleUi GitHub A static headscale admin ui, no backend environment required
      Headplane GitHub An advanced Tailscale inspired frontend for headscale
      headscale-admin Github Headscale-Admin is meant to be a simple, modern web interface for headscale
      ouroboros Github Ouroboros is designed for users to manage their own devices, rather than for admins
      unraid-headscale-admin Github A simple headscale admin UI for Unraid, it offers Local (docker exec) and API Mode
      headscale-console Github WebAssembly-based client supporting SSH, VNC and RDP with optional self-service capabilities

      You can ask for support on our Discord server in the "web-interfaces" channel.

      \ No newline at end of file diff --git a/development/ref/oidc/index.html b/development/ref/oidc/index.html index 0c8c5e18..df05d279 100644 --- a/development/ref/oidc/index.html +++ b/development/ref/oidc/index.html @@ -1,4 +1,4 @@ - OpenID Connect - Headscale

      OpenID Connect

      Headscale supports authentication via external identity providers using OpenID Connect (OIDC). It features:

      Please see limitations for known issues and limitations.

      Configuration

      OpenID requires configuration in Headscale and your identity provider:

      • Headscale: The oidc section of the Headscale configuration contains all available configuration options along with a description and their default values.
      • Identity provider: Please refer to the official documentation of your identity provider for specific instructions. Additionally, there might be some useful hints in the Identity provider specific configuration section below.

      Basic configuration

      A basic configuration connects Headscale to an identity provider and typically requires:

      • OpenID Connect Issuer URL from the identity provider. Headscale uses the OpenID Connect Discovery Protocol 1.0 to automatically obtain OpenID configuration parameters (example: https://sso.example.com).
      • Client ID from the identity provider (example: headscale).
      • Client secret generated by the identity provider (example: generated-secret).
      • Redirect URI for your identity provider (example: https://headscale.example.com/oidc/callback).
      oidc:
      + OpenID Connect - Headscale      

      OpenID Connect

      Headscale supports authentication via external identity providers using OpenID Connect (OIDC). It features:

      Please see limitations for known issues and limitations.

      Configuration

      OpenID requires configuration in Headscale and your identity provider:

      • Headscale: The oidc section of the Headscale configuration contains all available configuration options along with a description and their default values.
      • Identity provider: Please refer to the official documentation of your identity provider for specific instructions. Additionally, there might be some useful hints in the Identity provider specific configuration section below.

      Basic configuration

      A basic configuration connects Headscale to an identity provider and typically requires:

      • OpenID Connect Issuer URL from the identity provider. Headscale uses the OpenID Connect Discovery Protocol 1.0 to automatically obtain OpenID configuration parameters (example: https://sso.example.com).
      • Client ID from the identity provider (example: headscale).
      • Client secret generated by the identity provider (example: generated-secret).
      • Redirect URI for your identity provider (example: https://headscale.example.com/oidc/callback).
      oidc:
         issuer: "https://sso.example.com"
         client_id: "headscale"
         client_secret: "generated-secret"
      diff --git a/development/ref/routes/index.html b/development/ref/routes/index.html
      index 5433176d..167ce489 100644
      --- a/development/ref/routes/index.html
      +++ b/development/ref/routes/index.html
      @@ -1,4 +1,4 @@
      - Routes - Headscale      

      Routes

      Headscale supports route advertising and can be used to manage subnet routers and exit nodes for a tailnet.

      • Subnet routers may be used to connect an existing network such as a virtual private cloud or an on-premise network with your tailnet. Use a subnet router to access devices where Tailscale can't be installed or to gradually rollout Tailscale.
      • Exit nodes can be used to route all Internet traffic for another Tailscale node. Use it to securely access the Internet on an untrusted Wi-Fi or to access online services that expect traffic from a specific IP address.

      Subnet router

      The setup of a subnet router requires double opt-in, once from a subnet router and once on the control server to allow its use within the tailnet. Optionally, use autoApprovers to automatically approve routes from a subnet router.

      Setup a subnet router

      Configure a node as subnet router

      Register a node and advertise the routes it should handle as comma separated list:

      $ sudo tailscale up --login-server <YOUR_HEADSCALE_URL> --advertise-routes=10.0.0.0/8,192.168.0.0/24
      + Routes - Headscale      

      Routes

      Headscale supports route advertising and can be used to manage subnet routers and exit nodes for a tailnet.

      • Subnet routers may be used to connect an existing network such as a virtual private cloud or an on-premise network with your tailnet. Use a subnet router to access devices where Tailscale can't be installed or to gradually rollout Tailscale.
      • Exit nodes can be used to route all Internet traffic for another Tailscale node. Use it to securely access the Internet on an untrusted Wi-Fi or to access online services that expect traffic from a specific IP address.

      Subnet router

      The setup of a subnet router requires double opt-in, once from a subnet router and once on the control server to allow its use within the tailnet. Optionally, use autoApprovers to automatically approve routes from a subnet router.

      Setup a subnet router

      Configure a node as subnet router

      Register a node and advertise the routes it should handle as comma separated list:

      $ sudo tailscale up --login-server <YOUR_HEADSCALE_URL> --advertise-routes=10.0.0.0/8,192.168.0.0/24
       

      If the node is already registered, it can advertise new routes or update previously announced routes with:

      $ sudo tailscale set --advertise-routes=10.0.0.0/8,192.168.0.0/24
       

      Finally, enable IP forwarding to route traffic.

      Enable the subnet router on the control server

      The routes of a tailnet can be displayed with the headscale nodes list-routes command. A subnet router with the hostname myrouter announced the IPv4 networks 10.0.0.0/8 and 192.168.0.0/24. Those need to be approved before they can be used.

      $ headscale nodes list-routes
       ID | Hostname | Approved | Available                  | Serving (Primary)
      diff --git a/development/ref/tls/index.html b/development/ref/tls/index.html
      index b8b15db6..39abc1c0 100644
      --- a/development/ref/tls/index.html
      +++ b/development/ref/tls/index.html
      @@ -1,4 +1,4 @@
      - TLS - Headscale      

      Running the service via TLS (optional)

      Bring your own certificate

      Headscale can be configured to expose its web service via TLS. To configure the certificate and key file manually, set the tls_cert_path and tls_key_path configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.

      config.yaml
      tls_cert_path: ""
      + TLS - Headscale      

      Running the service via TLS (optional)

      Bring your own certificate

      Headscale can be configured to expose its web service via TLS. To configure the certificate and key file manually, set the tls_cert_path and tls_key_path configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.

      config.yaml
      tls_cert_path: ""
       tls_key_path: ""
       

      The certificate should contain the full chain, else some clients, like the Tailscale Android client, will reject it.

      Let's Encrypt / ACME

      To get a certificate automatically via Let's Encrypt, set tls_letsencrypt_hostname to the desired certificate hostname. This name must resolve to the IP address(es) headscale is reachable on (i.e., it must correspond to the server_url configuration parameter). The certificate and Let's Encrypt account credentials will be stored in the directory configured in tls_letsencrypt_cache_dir. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.

      config.yaml
      tls_letsencrypt_hostname: ""
       tls_letsencrypt_listen: ":http"
      diff --git a/development/setup/install/community/index.html b/development/setup/install/community/index.html
      index 03b5c36a..ef903926 100644
      --- a/development/setup/install/community/index.html
      +++ b/development/setup/install/community/index.html
      @@ -1,4 +1,4 @@
      - Community packages - Headscale      

      Community packages

      Several Linux distributions and community members provide packages for headscale. Those packages may be used instead of the official releases provided by the headscale maintainers. Such packages offer improved integration for their targeted operating system and usually:

      • setup a dedicated local user account to run headscale
      • provide a default configuration
      • install headscale as system service

      Community packages might be outdated

      The packages mentioned on this page might be outdated or unmaintained. Use the official releases to get the current stable version or to test pre-releases.

      Packaging status

      Arch Linux

      Arch Linux offers a package for headscale, install via:

      pacman -S headscale
      + Community packages - Headscale      

      Community packages

      Several Linux distributions and community members provide packages for headscale. Those packages may be used instead of the official releases provided by the headscale maintainers. Such packages offer improved integration for their targeted operating system and usually:

      • setup a dedicated local user account to run headscale
      • provide a default configuration
      • install headscale as system service

      Community packages might be outdated

      The packages mentioned on this page might be outdated or unmaintained. Use the official releases to get the current stable version or to test pre-releases.

      Packaging status

      Arch Linux

      Arch Linux offers a package for headscale, install via:

      pacman -S headscale
       

      The AUR package headscale-git can be used to build the current development version.

      Fedora, RHEL, CentOS

      A third-party repository for various RPM based distributions is available at: https://copr.fedorainfracloud.org/coprs/jonathanspw/headscale/. The site provides detailed setup and installation instructions.

      Nix, NixOS

      A Nix package is available as: headscale. See the NixOS package site for installation details.

      Gentoo

      emerge --ask net-vpn/headscale
       

      Gentoo specific documentation is available here.

      OpenBSD

      Headscale is available in ports. The port installs headscale as system service with rc.d and provides usage instructions upon installation.

      pkg_add headscale
       
      \ No newline at end of file diff --git a/development/setup/install/container/index.html b/development/setup/install/container/index.html index a71aaadf..38c0c385 100644 --- a/development/setup/install/container/index.html +++ b/development/setup/install/container/index.html @@ -1,4 +1,4 @@ - Container - Headscale

      Running headscale in a container

      Community documentation

      This page is not actively maintained by the headscale authors and is written by community members. It is not verified by headscale developers.

      It might be outdated and it might miss necessary steps.

      This documentation has the goal of showing a user how-to set up and run headscale in a container. A container runtime such as Docker or Podman is required. The container image can be found on Docker Hub and GitHub Container Registry. The container image URLs are:

      Configure and run headscale

      1. Create a directory on the container host to store headscale's configuration and the SQLite database:

        mkdir -p ./headscale/{config,lib}
        + Container - Headscale      

        Running headscale in a container

        Community documentation

        This page is not actively maintained by the headscale authors and is written by community members. It is not verified by headscale developers.

        It might be outdated and it might miss necessary steps.

        This documentation has the goal of showing a user how-to set up and run headscale in a container. A container runtime such as Docker or Podman is required. The container image can be found on Docker Hub and GitHub Container Registry. The container image URLs are:

        Configure and run headscale

        1. Create a directory on the container host to store headscale's configuration and the SQLite database:

          mkdir -p ./headscale/{config,lib}
           cd ./headscale
           
        2. Download the example configuration for your chosen version and save it as: $(pwd)/config/config.yaml. Adjust the configuration to suit your local environment. See Configuration for details.

        3. Start headscale from within the previously created ./headscale directory:

          docker run \
             --name headscale \
          diff --git a/development/setup/install/official/index.html b/development/setup/install/official/index.html
          index d2515be3..eed8c279 100644
          --- a/development/setup/install/official/index.html
          +++ b/development/setup/install/official/index.html
          @@ -1,4 +1,4 @@
          - Official releases - Headscale      

          Official releases

          Official releases for headscale are available as binaries for various platforms and DEB packages for Debian and Ubuntu. Both are available on the GitHub releases page.

          It is recommended to use our DEB packages to install headscale on a Debian based system as those packages configure a local user to run headscale, provide a default configuration and ship with a systemd service file. Supported distributions are Ubuntu 22.04 or newer, Debian 12 or newer.

          1. Download the latest headscale package for your platform (.deb for Ubuntu and Debian).

            HEADSCALE_VERSION="" # See above URL for latest version, e.g. "X.Y.Z" (NOTE: do not add the "v" prefix!)
            + Official releases - Headscale      

            Official releases

            Official releases for headscale are available as binaries for various platforms and DEB packages for Debian and Ubuntu. Both are available on the GitHub releases page.

            It is recommended to use our DEB packages to install headscale on a Debian based system as those packages configure a local user to run headscale, provide a default configuration and ship with a systemd service file. Supported distributions are Ubuntu 22.04 or newer, Debian 12 or newer.

            1. Download the latest headscale package for your platform (.deb for Ubuntu and Debian).

              HEADSCALE_VERSION="" # See above URL for latest version, e.g. "X.Y.Z" (NOTE: do not add the "v" prefix!)
               HEADSCALE_ARCH="" # Your system architecture, e.g. "amd64"
               wget --output-document=headscale.deb \
                "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
              diff --git a/development/setup/install/source/index.html b/development/setup/install/source/index.html
              index 767c5d55..71dd7c53 100644
              --- a/development/setup/install/source/index.html
              +++ b/development/setup/install/source/index.html
              @@ -1,4 +1,4 @@
              - Build from source - Headscale      

              Build from source

              Community documentation

              This page is not actively maintained by the headscale authors and is written by community members. It is not verified by headscale developers.

              It might be outdated and it might miss necessary steps.

              Headscale can be built from source using the latest version of Go and Buf (Protobuf generator). See the Contributing section in the GitHub README for more information.

              OpenBSD

              Install from source

              # Install prerequisites
              + Build from source - Headscale      

              Build from source

              Community documentation

              This page is not actively maintained by the headscale authors and is written by community members. It is not verified by headscale developers.

              It might be outdated and it might miss necessary steps.

              Headscale can be built from source using the latest version of Go and Buf (Protobuf generator). See the Contributing section in the GitHub README for more information.

              OpenBSD

              Install from source

              # Install prerequisites
               pkg_add go git
               
               git clone https://github.com/juanfont/headscale.git
              diff --git a/development/setup/requirements/index.html b/development/setup/requirements/index.html
              index c0557740..ea31543e 100644
              --- a/development/setup/requirements/index.html
              +++ b/development/setup/requirements/index.html
              @@ -1 +1 @@
              - Requirements and Assumptions - Headscale      

              Requirements

              Headscale should just work as long as the following requirements are met:

              • A server with a public IP address for headscale. A dual-stack setup with a public IPv4 and a public IPv6 address is recommended.
              • Headscale is served via HTTPS on port 4431 and may use additional ports.
              • A reasonably modern Linux or BSD based operating system.
              • A dedicated local user account to run headscale.
              • A little bit of command line knowledge to configure and operate headscale.

              Ports in use

              The ports in use vary with the intended scenario and enabled features. Some of the listed ports may be changed via the configuration file but we recommend to stick with the default values.

              • tcp/80
                • Expose publicly: yes
                • HTTP, used by Let's Encrypt to verify ownership via the HTTP-01 challenge.
                • Only required if the built-in Let's Enrypt client with the HTTP-01 challenge is used. See TLS for details.
              • tcp/443
                • Expose publicly: yes
                • HTTPS, required to make Headscale available to Tailscale clients1
                • Required if the embedded DERP server is enabled
              • udp/3478
              • tcp/50443
              • tcp/9090

              Assumptions

              The headscale documentation and the provided examples are written with a few assumptions in mind:

              • Headscale is running as system service via a dedicated local user headscale.
              • The configuration is loaded from /etc/headscale/config.yaml.
              • SQLite is used as database.
              • The data directory for headscale (used for private keys, ACLs, SQLite database, …) is located in /var/lib/headscale.
              • URLs and values that need to be replaced by the user are either denoted as <VALUE_TO_CHANGE> or use placeholder values such as headscale.example.com.

              Please adjust to your local environment accordingly.


              1. The Tailscale client assumes HTTPS on port 443 in certain situations. Serving headscale either via HTTP or via HTTPS on a port other than 443 is possible but sticking with HTTPS on port 443 is strongly recommended for production setups. See issue 2164 for more information. 

              \ No newline at end of file + Requirements and Assumptions - Headscale

              Requirements

              Headscale should just work as long as the following requirements are met:

              • A server with a public IP address for headscale. A dual-stack setup with a public IPv4 and a public IPv6 address is recommended.
              • Headscale is served via HTTPS on port 4431 and may use additional ports.
              • A reasonably modern Linux or BSD based operating system.
              • A dedicated local user account to run headscale.
              • A little bit of command line knowledge to configure and operate headscale.

              Ports in use

              The ports in use vary with the intended scenario and enabled features. Some of the listed ports may be changed via the configuration file but we recommend to stick with the default values.

              • tcp/80
                • Expose publicly: yes
                • HTTP, used by Let's Encrypt to verify ownership via the HTTP-01 challenge.
                • Only required if the built-in Let's Enrypt client with the HTTP-01 challenge is used. See TLS for details.
              • tcp/443
                • Expose publicly: yes
                • HTTPS, required to make Headscale available to Tailscale clients1
                • Required if the embedded DERP server is enabled
              • udp/3478
              • tcp/50443
              • tcp/9090

              Assumptions

              The headscale documentation and the provided examples are written with a few assumptions in mind:

              • Headscale is running as system service via a dedicated local user headscale.
              • The configuration is loaded from /etc/headscale/config.yaml.
              • SQLite is used as database.
              • The data directory for headscale (used for private keys, ACLs, SQLite database, …) is located in /var/lib/headscale.
              • URLs and values that need to be replaced by the user are either denoted as <VALUE_TO_CHANGE> or use placeholder values such as headscale.example.com.

              Please adjust to your local environment accordingly.


              1. The Tailscale client assumes HTTPS on port 443 in certain situations. Serving headscale either via HTTP or via HTTPS on a port other than 443 is possible but sticking with HTTPS on port 443 is strongly recommended for production setups. See issue 2164 for more information. 

              \ No newline at end of file diff --git a/development/setup/upgrade/index.html b/development/setup/upgrade/index.html index ac65b07d..651daccf 100644 --- a/development/setup/upgrade/index.html +++ b/development/setup/upgrade/index.html @@ -1 +1 @@ - Upgrade - Headscale

              Upgrade an existing installation

              Update an existing headscale installation to a new version:

              • Read the announcement on the GitHub releases page for the new version. It lists the changes of the release along with possible breaking changes.
              • Create a backup of your database.
              • Update headscale to the new version, preferably by following the same installation method.
              • Compare and update the configuration file.
              • Restart headscale.
              \ No newline at end of file + Upgrade - Headscale

              Upgrade an existing installation

              Update an existing headscale installation to a new version:

              • Read the announcement on the GitHub releases page for the new version. It lists the changes of the release along with possible breaking changes.
              • Create a backup of your database.
              • Update headscale to the new version, preferably by following the same installation method.
              • Compare and update the configuration file.
              • Restart headscale.
              \ No newline at end of file diff --git a/development/sitemap.xml b/development/sitemap.xml index 95db26d5..a23529b1 100644 --- a/development/sitemap.xml +++ b/development/sitemap.xml @@ -2,122 +2,122 @@ https://juanfont.github.io/headscale/development/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/about/clients/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/about/contributing/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/about/faq/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/about/features/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/about/help/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/about/releases/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/about/sponsor/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/acls/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/api/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/configuration/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/debug/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/derp/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/dns/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/oidc/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/routes/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/tls/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/integration/reverse-proxy/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/integration/tools/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/ref/integration/web-ui/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/setup/requirements/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/setup/upgrade/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/setup/install/community/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/setup/install/container/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/setup/install/official/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/setup/install/source/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/usage/getting-started/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/usage/connect/android/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/usage/connect/apple/ - 2025-11-24 + 2025-11-28 https://juanfont.github.io/headscale/development/usage/connect/windows/ - 2025-11-24 + 2025-11-28 \ No newline at end of file diff --git a/development/sitemap.xml.gz b/development/sitemap.xml.gz index 4a246f08037a2364e8ddf55389c87adc1bf795fe..b9743ac1ad23af38ea9a1f5958d5a8a9c2a23758 100644 GIT binary patch delta 415 zcmV;Q0bu^I1F-`KABzYG0Olx>2OfWb0o{`o30J20o8e~x=sk(jp(M>Syz8$EG zErF&!Q1nmg^76js!y6DMEZ6Qd9J>RQfH9Tj+Wq|Ty?^dr#-~f8%peCfE`057BK4bd z+qMmy1Xf>pKw2D!n@-q07Tt09+Ko>K9lL}3+vm7s4CC&F)y=Qw%Zx>aCCPuSO+!L= z10Ol~3@*YOWUMO`aTm9L_O}<$vSJ+1$Mcu|bn4H~YVugSZ|nZ-`(FtBgiTz?NhfTF zM@=bBP4v*rK+XQu4hwi`1a?mB2DzGnA;{p_P;|IrVI%`Q1hexYvlWz@jF710%xP)l zMeBwUrU+A8%&<_kf>NxcFQ$JOjG&O}3|NVam=Ty%1eV87O|Z9x&{x9u4}*MyXfkda zOntMU)7r4Ns(7z05v)c!);m`o30J20o9Ar_YsJeao(M>Syz8$EG zErF&!Q1nmg^8B`@!z*w_%Gd5R9J>SLKoRqD?SB6F-hb(y$EQo$RCV*K`8-pWVL^YnwP`?d zH}J6rpTI?Ug+yhAEbij=&;It}tE?2q^YQ$-Kb`vXCpCGj-M4jr_WdseexfEWB-BZ@ z!=t8*QxiQjGf=aCvBLsh8iSn^yFn^uU>FkkYA8CjP_D!Vco=5qL#kF#3K}6%$(eC! z>_zK_5vB-JTg)JBPyFs!n9y72xGMZ-$=#x3H zN{xes9Bb7t;1-bmg4Qb>3q&(qnpqiw_TD+NR%m-%r6e#%wPB95{euspempc`$KT!* Jul|D(008q4%%=bV diff --git a/development/usage/connect/android/index.html b/development/usage/connect/android/index.html index b3aea29b..51167c06 100644 --- a/development/usage/connect/android/index.html +++ b/development/usage/connect/android/index.html @@ -1 +1 @@ - Android - Headscale

              Connecting an Android client

              This documentation has the goal of showing how a user can use the official Android Tailscale client with headscale.

              Installation

              Install the official Tailscale Android client from the Google Play Store or F-Droid.

              Connect via normal, interactive login

              • Open the app and select the settings menu in the upper-right corner
              • Tap on Accounts
              • In the kebab menu icon (three dots) in the upper-right corner select Use an alternate server
              • Enter your server URL (e.g https://headscale.example.com) and follow the instructions
              • The client connects automatically as soon as the node registration is complete on headscale. Until then, nothing is visible in the server logs.

              Connect using a preauthkey

              • Open the app and select the settings menu in the upper-right corner
              • Tap on Accounts
              • In the kebab menu icon (three dots) in the upper-right corner select Use an alternate server
              • Enter your server URL (e.g https://headscale.example.com). If login prompts open, close it and continue
              • Open the settings menu in the upper-right corner
              • Tap on Accounts
              • In the kebab menu icon (three dots) in the upper-right corner select Use an auth key
              • Enter your preauthkey generated from headscale
              • If needed, tap Log in on the main screen. You should now be connected to your headscale.
              \ No newline at end of file + Android - Headscale

              Connecting an Android client

              This documentation has the goal of showing how a user can use the official Android Tailscale client with headscale.

              Installation

              Install the official Tailscale Android client from the Google Play Store or F-Droid.

              Connect via normal, interactive login

              • Open the app and select the settings menu in the upper-right corner
              • Tap on Accounts
              • In the kebab menu icon (three dots) in the upper-right corner select Use an alternate server
              • Enter your server URL (e.g https://headscale.example.com) and follow the instructions
              • The client connects automatically as soon as the node registration is complete on headscale. Until then, nothing is visible in the server logs.

              Connect using a preauthkey

              • Open the app and select the settings menu in the upper-right corner
              • Tap on Accounts
              • In the kebab menu icon (three dots) in the upper-right corner select Use an alternate server
              • Enter your server URL (e.g https://headscale.example.com). If login prompts open, close it and continue
              • Open the settings menu in the upper-right corner
              • Tap on Accounts
              • In the kebab menu icon (three dots) in the upper-right corner select Use an auth key
              • Enter your preauthkey generated from headscale
              • If needed, tap Log in on the main screen. You should now be connected to your headscale.
              \ No newline at end of file diff --git a/development/usage/connect/apple/index.html b/development/usage/connect/apple/index.html index bf9c6670..6a806ad5 100644 --- a/development/usage/connect/apple/index.html +++ b/development/usage/connect/apple/index.html @@ -1,2 +1,2 @@ - Apple - Headscale

              Connecting an Apple client

              This documentation has the goal of showing how a user can use the official iOS and macOS Tailscale clients with headscale.

              Instructions on your headscale instance

              An endpoint with information on how to connect your Apple device is also available at /apple on your running instance.

              iOS

              Installation

              Install the official Tailscale iOS client from the App Store.

              Configuring the headscale URL

              • Open the Tailscale app
              • Click the account icon in the top-right corner and select Log in….
              • Tap the top-right options menu button and select Use custom coordination server.
              • Enter your instance url (e.g https://headscale.example.com)
              • Enter your credentials and log in. Headscale should now be working on your iOS device.

              macOS

              Installation

              Choose one of the available Tailscale clients for macOS and install it.

              Configuring the headscale URL

              Command line

              Use Tailscale's login command to connect with your headscale instance (e.g https://headscale.example.com):

              tailscale login --login-server <YOUR_HEADSCALE_URL>
              + Apple - Headscale      

              Connecting an Apple client

              This documentation has the goal of showing how a user can use the official iOS and macOS Tailscale clients with headscale.

              Instructions on your headscale instance

              An endpoint with information on how to connect your Apple device is also available at /apple on your running instance.

              iOS

              Installation

              Install the official Tailscale iOS client from the App Store.

              Configuring the headscale URL

              • Open the Tailscale app
              • Click the account icon in the top-right corner and select Log in….
              • Tap the top-right options menu button and select Use custom coordination server.
              • Enter your instance url (e.g https://headscale.example.com)
              • Enter your credentials and log in. Headscale should now be working on your iOS device.

              macOS

              Installation

              Choose one of the available Tailscale clients for macOS and install it.

              Configuring the headscale URL

              Command line

              Use Tailscale's login command to connect with your headscale instance (e.g https://headscale.example.com):

              tailscale login --login-server <YOUR_HEADSCALE_URL>
               

              GUI

              • Option + Click the Tailscale icon in the menu and hover over the Debug menu
              • Under Custom Login Server, select Add Account...
              • Enter the URL of your headscale instance (e.g https://headscale.example.com) and press Add Account
              • Follow the login procedure in the browser

              tvOS

              Installation

              Install the official Tailscale tvOS client from the App Store.

              Danger

              Don't open the Tailscale App after installation!

              Configuring the headscale URL

              • Open Settings (the Apple tvOS settings) > Apps > Tailscale
              • Under ALTERNATE COORDINATION SERVER URL, select URL
              • Enter the URL of your headscale instance (e.g https://headscale.example.com) and press OK
              • Return to the tvOS Home screen
              • Open Tailscale
              • Click the button Install VPN configuration and confirm the appearing popup by clicking the Allow button
              • Scan the QR code and follow the login procedure
              \ No newline at end of file diff --git a/development/usage/connect/windows/index.html b/development/usage/connect/windows/index.html index b166879a..d86279ab 100644 --- a/development/usage/connect/windows/index.html +++ b/development/usage/connect/windows/index.html @@ -1,4 +1,4 @@ - Windows - Headscale

              Connecting a Windows client

              This documentation has the goal of showing how a user can use the official Windows Tailscale client with headscale.

              Instructions on your headscale instance

              An endpoint with information on how to connect your Windows device is also available at /windows on your running instance.

              Installation

              Download the Official Windows Client and install it.

              Configuring the headscale URL

              Open a Command Prompt or Powershell and use Tailscale's login command to connect with your headscale instance (e.g https://headscale.example.com):

              tailscale login --login-server <YOUR_HEADSCALE_URL>
              + Windows - Headscale      

              Connecting a Windows client

              This documentation has the goal of showing how a user can use the official Windows Tailscale client with headscale.

              Instructions on your headscale instance

              An endpoint with information on how to connect your Windows device is also available at /windows on your running instance.

              Installation

              Download the Official Windows Client and install it.

              Configuring the headscale URL

              Open a Command Prompt or Powershell and use Tailscale's login command to connect with your headscale instance (e.g https://headscale.example.com):

              tailscale login --login-server <YOUR_HEADSCALE_URL>
               

              Follow the instructions in the opened browser window to finish the configuration.

              Troubleshooting

              Unattended mode

              By default, Tailscale's Windows client is only running when the user is logged in. If you want to keep Tailscale running all the time, please enable "Unattended mode":

              • Click on the Tailscale tray icon and select Preferences
              • Enable Run unattended
              • Confirm the "Unattended mode" message

              See also Keep Tailscale running when I'm not logged in to my computer

              Failing node registration

              If you are seeing repeated messages like:

              [GIN] 2022/02/10 - 16:39:34 | 200 |    1.105306ms |       127.0.0.1 | POST     "/machine/redacted"
               

              in your headscale output, turn on DEBUG logging and look for:

              2022-02-11T00:59:29Z DBG Machine registration has expired. Sending a authurl to register machine=redacted
               

              This typically means that the registry keys above was not set appropriately.

              To reset and try again, it is important to do the following:

              1. Shut down the Tailscale service (or the client running in the tray)
              2. Delete Tailscale Application data folder, located at C:\Users\<USERNAME>\AppData\Local\Tailscale and try to connect again.
              3. Ensure the Windows node is deleted from headscale (to ensure fresh setup)
              4. Start Tailscale on the Windows machine and retry the login.
              \ No newline at end of file diff --git a/development/usage/getting-started/index.html b/development/usage/getting-started/index.html index 222fb49e..96f3edf0 100644 --- a/development/usage/getting-started/index.html +++ b/development/usage/getting-started/index.html @@ -1,4 +1,4 @@ - Getting started - Headscale

              Getting started

              This page helps you get started with headscale and provides a few usage examples for the headscale command line tool headscale.

              Prerequisites

              Getting help

              The headscale command line tool provides built-in help. To show available commands along with their arguments and options, run:

              # Show help
              + Getting started - Headscale      

              Getting started

              This page helps you get started with headscale and provides a few usage examples for the headscale command line tool headscale.

              Prerequisites

              Getting help

              The headscale command line tool provides built-in help. To show available commands along with their arguments and options, run:

              # Show help
               headscale help
               
               # Show help for a specific command
              diff --git a/versions.json b/versions.json
              index 8714efa4..f27446bc 100644
              --- a/versions.json
              +++ b/versions.json
              @@ -10,8 +10,8 @@
                   "version": "0.27.1",
                   "title": "0.27.1",
                   "aliases": [
              -      "latest",
              -      "stable"
              +      "stable",
              +      "latest"
                   ]
                 },
                 {