Tailscale - ArchWiki

Jump to content

# Tailscale

From ArchWiki

Related articles

- Netbird
- WireGuard

Tailscale builds on top of WireGuard and provides OAuth2 (SSO), OpenID, and SAML authentication for peers to build a mesh network. It is cross-platform, has ACL settings and internal DNS.

It is designed to provide an easy-to-use mesh network, and to manage akin security, like encryption keys for wireguard. Familiarising with its related concepts is essential to using it.

## Installation

Install tailscale and reboot your system.

It is also possible to run tailscale as a Docker container. This way, one can run multiple exit nodes on a single machine, each with its own tailnet.

### System tray application

Note This feature is currently in beta.

Introduced with v1.88, tailscale ships with the systray application. To launch the systray run:

    $ tailscale systray

To run the systray at startup, either as a systemd user service:

    $ tailscale configure systray --enable-startup=systemd

or using a freedesktop autostart file:

    $ tailscale configure systray --enable-startup=freedesktop

More information is available at tailscale's official documentation.

### Third-party clients

- KTailctl — GUI to monitor and manage Tailscale.

  https://github.com/f-koehler/KTailctl || ktailctlAUR

- trayscale — An unofficial GUI wrapper for the Tailscale CLI client.

  https://github.com/DeedleFake/trayscale || trayscaleAUR

- tailscaledesktop — Unnofficial Tailscale desktop application.

  https://gitlab.com/tailscaledesktop/application || tailscaledesktopAUR

- tailscale-systray-git — Linux port of tailscale system tray menu.

  https://github.com/mattn/tailscale-systray || tailscale-systray-gitAUR

## Usage

To use tailscale, enable/start `tailscaled.service` and run the server as follows:

    # tailscale up

You can authenticate a headless machine by specifying the auth key:

    # tailscale up --authkey=tskey-KEY

Note By default tailscale will send logs to their servers for central storage. You may want to opt out with one of the following steps:

- Edit `/etc/default/tailscaled` to include `TS_NO_LOGS_NO_SUPPORT=true`
- Edit `/etc/default/tailscaled` and add `--no-logs-no-support` to `FLAGS`

If you opt out of centralized logging, Tailscale may not be able to provide technical support.

## Advanced usage

### Using a custom Control Server

Using a custom control server like headscale is possible.

Warning When using a custom control server like Headscale, the server has full authority over node key distribution. Because Tailscale does not support WireGuard pre-shared keys, and as of May 2026 Headscale does not support tailnet lock, a compromised control server or VPS provider can maliciously inject unauthorized nodes into your tailnet. See PSKs and tailscale and headscale issue #1307 for details.

To login run

    # tailscale up --login-server https://example.com

On headless systems a non-interactive login using a token is possible.

    # tailscale up --login-server https://example.com --authkey your_auth_key

You may create user and auth-key using following commands after starting `headscale.service`:

    # headscale users create USER -e email@example.com
    # headscale users list
    # headscale preauthkeys create -u <ID> --reusable

#### Share nodes between users

Create file with policy:

    {
     "tagOwners": {
       "tag:shared": ["user1@"]
     },
     "groups": {
       "group:all": ["user1@", "user2@", "user3@"]
     },
     "acls": [
       {
         "action": "accept",
         "src": ["group:all"],
         "dst": ["tag:shared:*"]
       }
     ]
    }

Point this file in config.yaml:

    policy:
     mode: file
     path: "/etc/headscale/policy.json"

Advertise tag:

     tailscale up --advertise-tags=tag:shared --login-server=https://headscale.localdomain/

#### Integration with nextcloud or another OIDC provider

Install nextcloud-app-oidcAUR and create client key, use https://headscale.localdomain/oidc/callback as redirection uri.

Add following snippet into config.yaml:

    oidc:
     issuer: "https://cloud.example.com"
     client_id: "<client-id>"
     client_secret: "<client-secret>"
     scope: ["openid", "profile", "email"]
     user_map:
       name: "preferred_username"
       email: "email"

### Running as a Docker container

Follow this guide for a general idea of how to run tailscale as a docker container.

#### As an exit node

In order to be able to use a tailscale instance running as a docker container as an exit node, we need to use a smaller MTU for the container's network. This is due to an MTU-related issue.

If you do not have one already, create a custom network:

    # docker network create --opt com.docket.network.driver.mtu=1280 my_custom_network

Then, use that network for the container instance:

    # docker run --detach --name=my_tailscale_container --network=my_custom_network --volume /var/lib/tailscale-exitnode-1:/var/lib/tailscale --env TS_STATE_DIR=/var/lib/tailscale --env TS_USERSPACE=1 --env TS_AUTHKEY=tskey-auth-XXX --env TS_EXTRA_ARGS='--advertise-exit-node' tailscale/tailscale

Note that:

- By default, docker will create a network of type `bridge`, so no need to specify it here.
- Use an auth key to authenticate the node. Authenticating with the regular SSO method usually takes too long, and the process may time out before initial authentication is successful.
- Define `TS_USERSPACE=1` so that the container does not need elevated permissions (`CAP_NET_ADMIN` and `CAP_NET_RAW`).
- Bind mount an unused directory on the host (`/var/lib/tailscale-exitnode-1`) to `/var/lib/tailscale` inside the container, and also define `TS_STATE_DIR=/var/lib/tailscale`, so that tailscale will use a persistent state file. Without these, the exit node will use volatile memory to keep state, and thus get a new ID and tailnet IP address every time the container is restarted.

## Tips and tricks

### Using with NetworkManager

If you use NetworkManager, you may notice connection issues with other devices within your tailnet. This is due to a management conflict that is happening between NetworkManager and tailscaled.

To clear this up, we need NetworkManager to unmanage the tailscale network devices (e.g. `tailscale0`).

To do so, simply create a config like `/etc/NetworkManager/conf.d/99-tailscale.conf` with the contents of:

    [keyfile]
    unmanaged-devices=interface-name:tailscale0

Then restart `NetworkManager.service` and `tailscaled.service`.

You may also need to cycle tailscale:

    # tailscale down
    # tailscale up

After this, you should be able to `ping` other devices on your tailnet.

### Magic DNS

Tailscale expects system with working systemd-resolved to set up DNS server and search suffixes from tailnet configuration, otherwise it tries to overwrite `/etc/resolv.conf`.

### Security Hardening

Tailscale can be made to run in its own user and with just the capabilities it needs to operate. See the official knowledge base article for detail.

### VPN compatibility

The factual accuracy of this article or section is disputed.

Reason: Apart from style fixes, the preconditions when this work-around can be useful need to be made clear. tailscale recommends other setups, another practical user example uses fwmark to distinguish the traffic, which should be its primary intent. (Discuss in Talk:Tailscale)

Some VPN clients use packet marks (fwmarks) to identify and exclude traffic from their routing rules. Tailscale marks its packets with fwmark `524288` (`0x80000`).

To avoid routing conflicts, configure the VPN client to recognize and exclude packets marked by Tailscale. For example, with Proton VPN:

<syntaxhighlight lang="bash"> export PROTON_VPN_FWMARK=524288 protonvpn </syntaxhighlight>

This instructs Proton VPN to use the same fwmark as Tailscale, allowing Tailscale traffic to bypass Proton VPN routing and preventing interference between the two VPNs.

## Troubleshooting

### Tailscale crash on launch

After starting `tailscaled.service`, it may crash and get stuck on a restart loop. This may be due to the absence of the tun kernel module. To verify that this is indeed the case, view the logs of `tailscaled.service` via systemd

    # systemctl status tailscaled.service

Or, run the binary as root in your terminal

    # /usr/sbin/tailscaled

The following, or similar error may appear in systemctl status or by running the binary:

    ...is CONFIG_TUN enabled in your kernel? modprobe tun failed with: modprobe: FATAL: Module tun not found in directory /lib/modules/5.17.4-arch1-1 kernel/drivers/net/tun.ko found on disk, but not for current kernel; are you in middle of a system update and haven't rebooted? found: /lib/modules/5.17.8-arch1-1/kernel/drivers/net/tun.ko.zst wgengine.NewUserspaceEngine(tun "tailscale0") error: tstun.New("tailscale0"): no such device

If so, simply reboot your system and observe if `tailscaled.service` is active instead of loaded with systemctl status.

## See also

- https://tailscale.com/
- https://github.com/juanfont/headscale

Category:

- Virtual Private Network

Hidden category:

- Pages or sections flagged with Template:Accuracy

Tailscale
Add topic