Compare commits

..

31 Commits

Author SHA1 Message Date
Juan Font
26623d794b Merge pull request #268 from juanfont/prepare-0.12.2
Prepare CHANGELOG for 0.12.2
2022-01-11 16:49:51 +01:00
Juan Font Alonso
e9cc60e49c Updated changelog for 0.12.2 2022-01-11 15:45:13 +01:00
Juan Font
be2a28dd61 Merge pull request #267 from piec/patch-1
Fix example config link
2022-01-11 15:39:55 +01:00
Pierre Carru
cec236ce24 Fix example config link
Everything is in the title :p
2022-01-10 14:44:11 +01:00
Kristoffer Dalby
45d331da99 Merge pull request #263 from JJGadgets/patch-1 2022-01-06 10:40:04 +00:00
JJGadgets
897fa558b0 prettier: Docker docs 2022-01-06 17:25:07 +08:00
JJGadgets
d971cf1295 Improve Docker docs
- Fix URLs referring to files in this repository
- Better explain that we are creating the headscale directory and running the commands on the host Docker node
- Place instructions to download example config file to use as config file, as recommended steps.
2022-01-06 14:10:28 +08:00
Kristoffer Dalby
42bed58329 Merge pull request #262 from kradalby/improve-docs
Rewrite main documentation
2022-01-04 16:26:27 +00:00
Kristoffer Dalby
d9f52efe70 Fix typo 2022-01-02 23:17:48 +00:00
Kristoffer Dalby
25b5eb8d7f Update tests to aline with new config example 2022-01-02 23:17:42 +00:00
Kristoffer Dalby
81c60939c9 Add vertical line for breathing 2022-01-02 19:55:38 +00:00
Kristoffer Dalby
4edc96d14d Make strongly strong 2022-01-02 19:54:37 +00:00
Kristoffer Dalby
6b7c74133d Use markdown numbering so github gets it 2022-01-02 19:53:49 +00:00
Kristoffer Dalby
8da029bd14 Add missing links 2022-01-02 19:48:57 +00:00
Kristoffer Dalby
1d01103b67 Link to example config from docs 2022-01-02 19:43:06 +00:00
Kristoffer Dalby
5df100539c Remove outdated configuration page in favour of config-example 2022-01-02 19:42:35 +00:00
Kristoffer Dalby
11c86acbe3 update case in readme 2022-01-02 19:39:51 +00:00
Kristoffer Dalby
86f36f9a43 Lowercase markdown docs 2022-01-02 19:39:03 +00:00
Kristoffer Dalby
271cb71754 Add more explaination and less redunancy with docs 2022-01-02 19:38:04 +00:00
Kristoffer Dalby
80d196cbfd Remove DNS file, it will be merged into example configuration 2022-01-02 19:37:48 +00:00
Kristoffer Dalby
3ce3ccb559 Reorder tls docs 2022-01-02 19:36:50 +00:00
Kristoffer Dalby
a11c6fd8b9 Fix formatting error in container doc 2022-01-02 20:08:18 +01:00
Kristoffer Dalby
a75c5a4cff Add eradme to examples 2022-01-02 20:08:04 +01:00
Kristoffer Dalby
8d504c35bf Move kubernetes to kustomize, since thats what it is 2022-01-02 20:06:32 +01:00
Kristoffer Dalby
8a07a63b1c Write disclaimer in kubernetes example 2022-01-02 20:06:21 +01:00
Kristoffer Dalby
74fd5de43d Move kubernetes example under docs 2022-01-02 20:04:35 +01:00
Kristoffer Dalby
f9e6722635 Rewrite main documentation
This commit starts restructuring the documentation and updating it to be
compliant with 0.12.x+ releases.

The main change is that the documentation has been rewritten for the
ground up, and hopefully simplified.

The documentation has been split into an official documentation for
running headscale as a binary under Linux with SystemD and a "community"
provided documentation for Docker.

This should make the two documents a lot easier to read and follow than
the mishmash document we had.
2022-01-02 19:11:36 +01:00
Juan Font
0bd4250a53 Merge pull request #261 from juanfont/kradalby-patch-2
Add note about outdated docs until we fix them
2021-12-29 10:53:15 +01:00
Kristoffer Dalby
4b44aa2180 Add note about outdated docs until we fix them 2021-12-28 10:16:20 +01:00
Kristoffer Dalby
f78984f2ef Merge pull request #258 from ohdearaugustin/fix-docker-release
Fix docker release
2021-12-27 22:09:16 +01:00
ohdearaugustin
3de311b7f4 Fix docker release 2021-12-27 21:24:57 +01:00
34 changed files with 491 additions and 335 deletions

View File

@@ -40,6 +40,8 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Set up QEMU for multiple platforms
uses: docker/setup-qemu-action@master
with:
@@ -63,6 +65,7 @@ jobs:
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest
type=sha
- name: Login to DockerHub
uses: docker/login-action@v1
@@ -98,6 +101,8 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Set up QEMU for multiple platforms
uses: docker/setup-qemu-action@master
with:
@@ -150,5 +155,5 @@ jobs:
cache-to: type=local,dest=/tmp/.buildx-cache-debug-new
- name: Prepare cache for next build
run: |
rm -rf /tmp/.buildx-cache
rm -rf /tmp/.buildx-cache-debug
mv /tmp/.buildx-cache-debug-new /tmp/.buildx-cache-debug

View File

@@ -2,6 +2,16 @@
**TBD (TBD):**
**0.12.2 (2022-01-11):**
Happy New Year!
**Changes**:
- Fix Docker release [#258](https://github.com/juanfont/headscale/pull/258)
- Rewrite main docs [#262](https://github.com/juanfont/headscale/pull/262)
- Improve Docker docs [#263](https://github.com/juanfont/headscale/pull/263)
**0.12.1 (2021-12-24):**
(We are skipping 0.12.0 to correct a mishap done weeks ago with the version tagging)

View File

@@ -54,9 +54,8 @@ func (*Suite) TestConfigLoading(c *check.C) {
// Test that config file was interpreted correctly
c.Assert(viper.GetString("server_url"), check.Equals, "http://127.0.0.1:8080")
c.Assert(viper.GetString("listen_addr"), check.Equals, "0.0.0.0:8080")
c.Assert(viper.GetStringSlice("derp.paths")[0], check.Equals, "derp-example.yaml")
c.Assert(viper.GetString("db_type"), check.Equals, "sqlite3")
c.Assert(viper.GetString("db_path"), check.Equals, "db.sqlite")
c.Assert(viper.GetString("db_path"), check.Equals, "/var/lib/headscale/db.sqlite")
c.Assert(viper.GetString("tls_letsencrypt_hostname"), check.Equals, "")
c.Assert(viper.GetString("tls_letsencrypt_listen"), check.Equals, ":http")
c.Assert(viper.GetString("tls_letsencrypt_challenge_type"), check.Equals, "HTTP-01")

View File

@@ -1,39 +1,65 @@
---
# headscale will look for a configuration file named `config.yaml` (or `config.json`) in the following order:
#
# - `/etc/headscale`
# - `~/.headscale`
# - current working directory
# The url clients will connect to.
# Typically this will be a domain.
# Typically this will be a domain like:
#
# https://myheadscale.example.com:443
#
server_url: http://127.0.0.1:8080
# Address to listen to / bind to on the server
#
listen_addr: 0.0.0.0:8080
# Private key file which will be
# Private key used encrypt the traffic between headscale
# and Tailscale clients.
# The private key file which will be
# autogenerated if it's missing
private_key_path: private.key
private_key_path: /var/lib/headscale/private.key
# DERP is a relay system that Tailscale uses when a direct
# connection cannot be established.
# https://tailscale.com/blog/how-tailscale-works/#encrypted-tcp-relays-derp
#
# headscale needs a list of DERP servers that can be presented
# to the clients.
derp:
# List of externally available DERP maps encoded in JSON
urls:
- https://controlplane.tailscale.com/derpmap/default
# Locally available DERP map files encoded in YAML
paths:
- derp-example.yaml
#
# This option is mostly interesting for people hosting
# their own DERP servers:
# https://tailscale.com/kb/1118/custom-derp-servers/
#
# paths:
# - /etc/headscale/derp-example.yaml
paths: []
# If enabled, a worker will be set up to periodically
# refresh the given sources and update the derpmap
# will be set up.
auto_update_enabled: true
# How often should we check for updates?
# How often should we check for DERP updates?
update_frequency: 24h
# Disables the automatic check for updates on startup
# Disables the automatic check for headscale updates on startup
disable_check_updates: false
# Time before an inactive ephemeral node is deleted?
ephemeral_node_inactivity_timeout: 30m
# SQLite config
db_type: sqlite3
db_path: db.sqlite
db_path: /var/lib/headscale/db.sqlite
# # Postgres config
# db_type: postgres
@@ -43,35 +69,87 @@ db_path: db.sqlite
# db_user: foo
# db_pass: bar
### TLS configuration
#
## Let's encrypt / ACME
#
# headscale supports automatically requesting and setting up
# TLS for a domain with Let's Encrypt.
#
# URL to ACME directory
acme_url: https://acme-v02.api.letsencrypt.org/directory
# Email to register with ACME provider
acme_email: ""
# Domain name to request a TLS certificate for:
tls_letsencrypt_hostname: ""
tls_letsencrypt_listen: ":http"
tls_letsencrypt_cache_dir: ".cache"
tls_letsencrypt_challenge_type: HTTP-01
# Path to store certificates and metadata needed by
# letsencrypt
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
# Type of ACME challenge to use, currently supported types:
# HTTP-01 or TLS_ALPN-01
# See [docs/tls.md](docs/tls.md) for more information
tls_letsencrypt_challenge_type: HTTP-01
# When HTTP-01 challenge is chosen, letsencrypt must set up a
# verification endpoint, and it will be listning on:
# :http = port 80
tls_letsencrypt_listen: ":http"
## Use already defined certificates:
tls_cert_path: ""
tls_key_path: ""
log_level: info
# Path to a file containg ACL policies.
# Recommended path: /etc/headscale/acl.hujson
acl_policy_path: ""
## DNS
#
# headscale supports Tailscale's DNS configuration and MagicDNS.
# Please have a look to their KB to better understand the concepts:
#
# - https://tailscale.com/kb/1054/dns/
# - https://tailscale.com/kb/1081/magicdns/
# - https://tailscale.com/blog/2021-09-private-dns-with-magicdns/
#
dns_config:
# Upstream DNS servers
# List of DNS servers to expose to clients.
nameservers:
- 1.1.1.1
# Split DNS (see https://tailscale.com/kb/1054/dns/),
# list of search domains and the DNS to query for each one.
#
# restricted_nameservers:
# foo.bar.com:
# - 1.1.1.1
# darp.headscale.net:
# - 1.1.1.1
# - 8.8.8.8
# Search domains to inject.
domains: []
# Whether to use [MagicDNS](https://tailscale.com/kb/1081/magicdns/).
# Only works if there is at least a nameserver defined.
magic_dns: true
# Defines the base domain to create the hostnames for MagicDNS.
# `base_domain` must be a FQDNs, without the trailing dot.
# The FQDN of the hosts will be
# `hostname.namespace.base_domain` (e.g., _myhost.mynamespace.example.com_).
base_domain: example.com
# Unix socket used for the CLI to connect without authentication
# Note: for local development, you probably want to change this to:
# unix_socket: ./headscale.sock
unix_socket: /var/run/headscale.sock
#
# headscale supports experimental OpenID connect support,
# it is still being tested and might have some bugs, please
# help us test it.

View File

@@ -1,74 +0,0 @@
# Configuration reference
Headscale will look for a configuration file named `config.yaml` (or `config.json`) in the following order:
- `/etc/headscale`
- `~/.headscale`
- current working directory
```yaml
server_url: http://headscale.mydomain.net
listen_addr: 0.0.0.0:8080
ip_prefix: 100.64.0.0/10
disable_check_updates: false
```
`server_url` is the external URL via which Headscale is reachable. `listen_addr` is the IP address and port the Headscale program should listen on. `ip_prefix` is the IP prefix (range) in which IP addresses for nodes will be allocated (default 100.64.0.0/10, e.g., 192.168.4.0/24, 10.0.0.0/8). `disable_check_updates` disables the automatic check for updates.
```yaml
log_level: debug
```
`log_level` can be used to set the Log level for Headscale, it defaults to `debug`, and the available levels are: `trace`, `debug`, `info`, `warn` and `error`.
```yaml
derp_map_path: derp.yaml
```
`derp_map_path` is the path to the [DERP](https://pkg.go.dev/tailscale.com/derp) map file. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.
```yaml
ephemeral_node_inactivity_timeout: "30m"
```
`ephemeral_node_inactivity_timeout` is the timeout after which inactive ephemeral node records will be deleted from the database. The default is 30 minutes. This value must be higher than 65 seconds (the keepalive timeout for the HTTP long poll is 60 seconds, plus a few seconds to avoid race conditions).
PostgresSQL
```yaml
db_host: localhost
db_port: 5432
db_name: headscale
db_user: foo
db_pass: bar
```
SQLite
```yaml
db_type: sqlite3
db_path: db.sqlite
```
The fields starting with `db_` are used for the DB connection information.
### TLS configuration
Please check [`TLS.md`](TLS.md).
### DNS configuration
Please refer to [`DNS.md`](DNS.md).
### Policy 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 namespaces (which are the equivalent to user/logins in Tailscale.com).
Please check https://tailscale.com/kb/1018/acls/, and `./tests/acls/` in this repo for working examples.
### Apple devices
An endpoint with information on how to connect your Apple devices (currently macOS only) is available at `/apple` on your running instance.

View File

@@ -1,37 +0,0 @@
# DNS in headscale
headscale supports Tailscale's DNS configuration and MagicDNS. Please have a look to their KB to better understand what this means:
- https://tailscale.com/kb/1054/dns/
- https://tailscale.com/kb/1081/magicdns/
- https://tailscale.com/blog/2021-09-private-dns-with-magicdns/
Long story short, you can define the DNS servers you want to use in your tailnets, activate MagicDNS (so you don't have to remember the IP addresses of your nodes), define search domains, as well as predefined hosts. headscale will inject that settings into your nodes.
## Configuration reference
The setup is done via the `config.yaml` file, under the `dns_config` key.
```yaml
server_url: http://127.0.0.1:8001
listen_addr: 0.0.0.0:8001
dns_config:
nameservers:
- 1.1.1.1
- 8.8.8.8
restricted_nameservers:
foo.bar.com:
- 1.1.1.1
darp.headscale.net:
- 1.1.1.1
- 8.8.8.8
domains: []
magic_dns: true
base_domain: example.com
```
- `nameservers`: The list of DNS servers to use.
- `domains`: Search domains to inject.
- `magic_dns`: Whether to use [MagicDNS](https://tailscale.com/kb/1081/magicdns/). Only works if there is at least a nameserver defined.
- `base_domain`: Defines the base domain to create the hostnames for MagicDNS. `base_domain` must be a FQDNs, without the trailing dot. The FQDN of the hosts will be `hostname.namespace.base_domain` (e.g., _myhost.mynamespace.example.com_).
- `restricted_nameservers`: Split DNS (see https://tailscale.com/kb/1054/dns/), list of search domains and the DNS to query for each one.

View File

@@ -1,7 +1,42 @@
# Official headscale documentation
# headscale documentation
- [Configuration](Configuration.md)
- [Running](Running.md)
- [DNS](DNS.md)
- [TLS](TLS.md)
- [Glossary](Glossary.md)
This page contains the official and community contributed documentation for `headscale`.
If you are having trouble with following the documentation or get unexpected results,
please ask on [Discord](https://discord.gg/XcQxk2VHjx) instead of opening an Issue.
## Official documentation
### How-to
- [Running headscale on Linux](running-headscale-linux.md)
### References
- [Configuration](../config-example.yaml)
- [Glossary](glossary.md)
- [TLS](tls.md)
## Community documentation
Community documentation 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 in a container](running-headscale-container.md)
## Misc
### Policy 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 namespaces (which are the equivalent to user/logins in Tailscale.com).
Please check https://tailscale.com/kb/1018/acls/, and `./tests/acls/` in this repo for working examples.
### Apple devices
An endpoint with information on how to connect your Apple devices (currently macOS only) is available at `/apple` on your running instance.

View File

@@ -1,191 +0,0 @@
# Running headscale
## Server configuration
1. Download the headscale binary https://github.com/juanfont/headscale/releases, and place it somewhere in your $PATH or use the docker container
```shell
docker pull headscale/headscale:x.x.x
```
<!--
or
```shell
docker pull ghrc.io/juanfont/headscale:x.x.x
``` -->
2. When running headscale in a docker container, prepare a directory to hold all configuration
```shell
mkdir config
```
3. Get yourself a DB
a) Get a Postgres DB running in Docker:
```shell
docker run --name headscale \
-e POSTGRES_DB=headscale \
-e POSTGRES_USER=foo \
-e POSTGRES_PASSWORD=bar \
-p 5432:5432 \
-d postgres
```
or b) Prepare a SQLite DB file:
```shell
touch config/db.sqlite
```
4. Create a headscale configuration, and a DERP map file. Refer to [tailscale sample](https://raw.githubusercontent.com/tailscale/tailscale/main/net/dnsfallback/dns-fallback-servers.json) for more guidance.
```shell
cp config.yaml.[sqlite|postgres].example config/config.yaml
cp derp-example.yaml config/derp.yaml
```
5. Create a namespace
```shell
headscale namespaces create myfirstnamespace
```
or Docker:
```shell
docker run \
-v $(pwd)/config:/etc/headscale/ \
-p 127.0.0.1:8080:8080 \
headscale/headscale:x.x.x \
headscale namespaces create myfirstnamespace
```
or if your server is already running in Docker:
```shell
docker exec <container_name> \
headscale namespaces create myfirstnamespace
```
6. Run the server
```shell
headscale serve
```
or Docker:
```shell
docker run \
-v $(pwd)/config:/etc/headscale/ \
-p 127.0.0.1:8080:8080 \
headscale/headscale:x.x.x \
headscale serve
```
## Nodes configuration
If you used tailscale.com before in your nodes, make sure you clear the tailscaled data folder
```shell
systemctl stop tailscaled
rm -fr /var/lib/tailscale
systemctl start tailscaled
```
### Adding node based on MACHINEKEY
1. Add your first machine
```shell
tailscale up --login-server YOUR_HEADSCALE_URL
```
2. Navigate to the URL returned by `tailscale up`, where you'll find your machine key.
3. In the server, register your machine to a namespace with the CLI
```shell
headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY
```
or Docker:
```shell
docker run \
-v $(pwd)/config:/etc/headscale/ \
headscale/headscale:x.x.x \
headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY
```
or if your server is already running in Docker:
```shell
docker exec <container_name> \
headscale -n myfirstnamespace nodes register -k YOURMACHINEKEY
```
### Alternative: adding node with AUTHKEY
1. Create an authkey
```shell
headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h
```
or Docker:
```shell
docker run \
-v $(pwd)/config:/etc/headscale/ \
headscale/headscale:x.x.x \
headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h
```
or if your server is already running in Docker:
```shell
docker exec <container_name> \
headscale -n myfirstnamespace preauthkeys create --reusable --expiration 24h
```
2. Use the authkey on your node to register it:
```shell
tailscale up --login-server YOUR_HEADSCALE_URL --authkey YOURAUTHKEY
```
If you create an authkey with the `--ephemeral` flag, that key will create ephemeral nodes. This implies that `--reusable` is true.
Please bear in mind that all headscale commands support adding `-o json` or `-o json-line` to get nicely JSON-formatted output.
## Debugging headscale running in Docker
The `headscale/headscale` Docker container is based on a "distroless" image that does not contain a shell or any other debug tools. If you need to debug your application running in the Docker container, you can use the `-debug` variant, for example `headscale/headscale:x.x.x-debug`.
### Running the debug Docker container
To run the debug Docker container, use the exact same commands as above, but replace `headscale/headscale:x.x.x` with `headscale/headscale:x.x.x-debug` (`x.x.x` is the version of headscale). The two containers are compatible with each other, so you can alternate between them.
### Executing commands in the debug container
The default command in the debug container is to run `headscale`, which is located at `/bin/headscale` inside the container.
Additionally, the debug container includes a minimalist Busybox shell.
To launch a shell in the container, use:
```
docker run -it headscale/headscale:x.x.x-debug sh
```
You can also execute commands directly, such as `ls /bin` in this example:
```
docker run headscale/headscale:x.x.x-debug ls /bin
```
Using `docker exec` allows you to run commands in an existing container.

5
docs/examples/README.md Normal file
View File

@@ -0,0 +1,5 @@
# Examples
This directory contains examples on how to run `headscale` on different platforms.
All examples are provided by the community and they are not verified by the `headscale` authors.

View File

@@ -1,5 +1,7 @@
# Deploying headscale on Kubernetes
**Note:** This is contributed by the community and not verified by the headscale authors.
This directory contains [Kustomize](https://kustomize.io) templates that deploy
headscale in various configurations.
@@ -66,7 +68,7 @@ tasks like creating namespaces, authkeys, etc.
headscale is an open source implementation of the Tailscale control server
https://gitlab.com/juanfont/headscale
https://github.com/juanfont/headscale
Usage:
headscale [command]

View File

@@ -0,0 +1,148 @@
# Running headscale in a container
**Note:** the container documentation is maintained by the _community_ and there is no guarentee
it is up to date, or working.
## Goal
This documentation has the goal of showing a user how-to set up and run `headscale` in a container.
[Docker](https://www.docker.com) is used as the reference container implementation, but there is no reason that it should
not work with alternatives like [Podman](https://podman.io). The Docker image can be found on Docker Hub [here](https://hub.docker.com/r/headscale/headscale).
## Configure and run `headscale`
1. Prepare a directory on the host Docker node in your directory of choice, used to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database:
```shell
mkdir ./headscale && cd ./headscale
mkdir ./config
```
2. Create an empty SQlite datebase in the headscale directory:
```shell
touch ./config/db.sqlite
```
3. **(Strongly Recommended)** Download a copy of the [example configuration](../config-example.yaml) from the [headscale repository](https://github.com/juanfont/headscale/).
Using wget:
```shell
wget -O ./config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml
```
Using curl:
```shell
curl https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml -o ./config/config.yaml
```
**(Advanced)** If you would like to hand craft a config file **instead** of downloading the example config file, create a blank `headscale` configuration in the headscale directory to edit:
```shell
touch ./config/config.yaml
```
Modify the config file to your preferences before launching Docker container.
4. Start the headscale server while working in the host headscale directory:
```shell
docker run \
--name headscale \
--detach \
--rm \
--volume $(pwd)/config:/etc/headscale/ \
--publish 127.0.0.1:8080:8080 \
headscale/headscale:<VERSION> \
headscale serve
```
This command will mount `config/` under `/etc/headscale`, forward port 8080 out of the container so the
`headscale` instance becomes available and then detach so headscale runs in the background.
5. Verify `headscale` is running:
Follow the container logs:
```shell
docker logs --follow headscale
```
Verify running containers:
```shell
docker ps
```
Verify `headscale` is available:
```shell
curl http://127.0.0.1:8080/metrics
```
6. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)):
```shell
docker exec headscale -- headscale namespaces create myfirstnamespace
```
### Register a machine (normal login)
On a client machine, execute the `tailscale` login command:
```shell
tailscale up --login-server YOUR_HEADSCALE_URL
```
To register a machine when running `headscale` in a container, take the headscale command and pass it to the container:
```shell
docker exec headscale -- \
headscale --namespace myfirstnamespace nodes register --key <YOU_+MACHINE_KEY>
```
### Register machine using a pre authenticated key
Generate a key using the command line:
```shell
docker exec headscale -- \
headscale --namespace myfirstnamespace preauthkeys create --reusable --expiration 24h
```
This will return a pre-authenticated key that can be used to connect a node to `headscale` during the `tailscale` command:
```shell
tailscale up --login-server <YOUR_HEADSCALE_URL> --authkey <YOUR_AUTH_KEY>
```
## Debugging headscale running in Docker
The `headscale/headscale` Docker container is based on a "distroless" image that does not contain a shell or any other debug tools. If you need to debug your application running in the Docker container, you can use the `-debug` variant, for example `headscale/headscale:x.x.x-debug`.
### Running the debug Docker container
To run the debug Docker container, use the exact same commands as above, but replace `headscale/headscale:x.x.x` with `headscale/headscale:x.x.x-debug` (`x.x.x` is the version of headscale). The two containers are compatible with each other, so you can alternate between them.
### Executing commands in the debug container
The default command in the debug container is to run `headscale`, which is located at `/bin/headscale` inside the container.
Additionally, the debug container includes a minimalist Busybox shell.
To launch a shell in the container, use:
```
docker run -it headscale/headscale:x.x.x-debug sh
```
You can also execute commands directly, such as `ls /bin` in this example:
```
docker run headscale/headscale:x.x.x-debug ls /bin
```
Using `docker exec` allows you to run commands in an existing container.

View File

@@ -0,0 +1,172 @@
# Running headscale on Linux
## Goal
This documentation has the goal of showing a user how-to set up and run `headscale` on Linux.
In additional to the "get up and running section", there is an optional [SystemD section](#running-headscale-in-the-background-with-systemd)
describing how to make `headscale` run properly in a server environment.
## Configure and run `headscale`
1. Download the latest [`headscale` binary from GitHub's release page](https://github.com/juanfont/headscale/releases):
```shell
wget --output-document=/usr/local/bin/headscale \
https://github.com/juanfont/headscale/releases/download/v<HEADSCALE VERSION>/headscale_<HEADSCALE VERSION>_linux_<ARCH>
```
2. Make `headscale` executable:
```shell
chmod +x /usr/local/bin/headscale
```
3. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database:
```shell
# Directory for configuration
mkdir -p /etc/headscale
# Directory for Database, and other variable data (like certificates)
mkdir -p /var/lib/headscale
```
4. Create an empty SQlite datebase:
```shell
touch /var/lib/headscale/db.sqlite
```
5. Create a `headscale` configuration:
```shell
touch /etc/headscale/config.yaml
```
It is **strongly recommended** to copy and modifiy the [example configuration](../config-example.yaml)
from the [headscale repository](../)
6. Start the headscale server:
```shell
headscale serve
```
This command will start `headscale` in the current terminal session.
---
To continue the tutorial, open a new terminal and let it run in the background.
Alternatively use terminal emulators like [tmux](https://github.com/tmux/tmux) or [screen](https://www.gnu.org/software/screen/).
To run `headscale` in the background, please follow the steps in the [SystemD section](#running-headscale-in-the-background-with-systemd) before continuing.
7. Verify `headscale` is running:
Verify `headscale` is available:
```shell
curl http://127.0.0.1:8080/metrics
```
8. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)):
```shell
headscale namespaces create myfirstnamespace
```
### Register a machine (normal login)
On a client machine, execute the `tailscale` login command:
```shell
tailscale up --login-server YOUR_HEADSCALE_URL
```
Register the machine:
```shell
headscale --namespace myfirstnamespace nodes register --key <YOU_+MACHINE_KEY>
```
### Register machine using a pre authenticated key
Generate a key using the command line:
```shell
headscale --namespace myfirstnamespace preauthkeys create --reusable --expiration 24h
```
This will return a pre-authenticated key that can be used to connect a node to `headscale` during the `tailscale` command:
```shell
tailscale up --login-server <YOUR_HEADSCALE_URL> --authkey <YOUR_AUTH_KEY>
```
## Running `headscale` in the background with SystemD
In this section it will be demonstrated how to run `headscale` as a service in the background with [SystemD](https://www.freedesktop.org/wiki/Software/systemd/).
This should work on most modern Linux distributions.
1. Create a SystemD service configuration at `/etc/systemd/system/headscale.service` containing:
```systemd
[Unit]
Description=headscale controller
After=syslog.target
After=network.target
[Service]
Type=simple
User=headscale
Group=headscale
ExecStart=/usr/local/bin/headscale serve
Restart=always
RestartSec=5
# Optional security enhancements
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/headscale /var/run/headscale
AmbientCapabilities=CAP_NET_BIND_SERVICE
RuntimeDirectory=headscale
[Install]
WantedBy=multi-user.target
```
2. In `/etc/headscale/config.yaml`, override the default `headscale` unix socket with a SystemD friendly path:
```yaml
unix_socket: /var/run/headscale/headscale.sock
```
3. Reload SystemD to load the new configuration file:
```shell
systemctl daemon-reload
```
4. Enable and start the new `headscale` service:
```shell
systemctl enable headscale
systemctl start headscale
```
5. Verify the headscale service:
```shell
systemctl status headscale
```
Verify `headscale` is available:
```shell
curl http://127.0.0.1:8080/metrics
```
`headscale` will now run in the background and start at boot.

View File

@@ -1,5 +1,9 @@
# Running the service via TLS (optional)
## Let's Encrypt / ACME
To get a certificate automatically via [Let's Encrypt](https://letsencrypt.org/), 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. The certificate will automatically be renewed as needed.
```yaml
tls_letsencrypt_hostname: ""
tls_letsencrypt_listen: ":http"
@@ -7,21 +11,21 @@ tls_letsencrypt_cache_dir: ".cache"
tls_letsencrypt_challenge_type: HTTP-01
```
To get a certificate automatically via [Let's Encrypt](https://letsencrypt.org/), 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. The certificate will automatically be renewed as needed.
```yaml
tls_cert_path: ""
tls_key_path: ""
```
headscale can also be configured to expose its web service via TLS. To configure the certificate and key file manually, set the `tls_cert_path` and `tls_cert_path` configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.
## Challenge type HTTP-01
### Challenge type HTTP-01
The default challenge type `HTTP-01` requires that headscale is reachable on port 80 for the Let's Encrypt automated validation, in addition to whatever port is configured in `listen_addr`. By default, headscale listens on port 80 on all local IPs for Let's Encrypt automated validation.
If you need to change the ip and/or port used by headscale for the Let's Encrypt validation process, set `tls_letsencrypt_listen` to the appropriate value. This can be handy if you are running headscale as a non-root user (or can't run `setcap`). Keep in mind, however, that Let's Encrypt will _only_ connect to port 80 for the validation callback, so if you change `tls_letsencrypt_listen` you will also need to configure something else (e.g. a firewall rule) to forward the traffic from port 80 to the ip:port combination specified in `tls_letsencrypt_listen`.
## Challenge type TLS-ALPN-01
### Challenge type TLS-ALPN-01
Alternatively, `tls_letsencrypt_challenge_type` can be set to `TLS-ALPN-01`. In this configuration, headscale listens on the ip:port combination defined in `listen_addr`. Let's Encrypt will _only_ connect to port 443 for the validation callback, so if `listen_addr` is not set to port 443, something else (e.g. a firewall rule) will be required to forward the traffic from port 443 to the ip:port combination specified in `listen_addr`.
## Bring your own certificate
headscale can also be configured to expose its web service via TLS. To configure the certificate and key file manually, set the `tls_cert_path` and `tls_cert_path` configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.
```yaml
tls_cert_path: ""
tls_key_path: ""
```