From d955cd62626a88874eb62ac00e0698dc9ca0cb62 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 17 Jun 2026 19:44:17 +0000 Subject: [PATCH] docs: replace gRPC remote-control with HTTP API The remote CLI speaks HTTP to the API URL now; drop the gRPC port, grpc_listen_addr, and #grpc anchors. --- docs/about/faq.md | 2 +- docs/ref/api.md | 29 ++++++++++++--------------- docs/ref/integration/reverse-proxy.md | 5 +---- docs/setup/requirements.md | 3 --- mkdocs.yml | 4 ++-- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/docs/about/faq.md b/docs/about/faq.md index 09792653..d4a85018 100644 --- a/docs/about/faq.md +++ b/docs/about/faq.md @@ -160,7 +160,7 @@ indicates which part of the policy is invalid. Follow these steps to fix your po !!! warning "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](../ref/api.md#grpc) is not sufficient. You may use + minimal config to [control Headscale via remote CLI](../ref/api.md#remote-control) is not sufficient. You may use `headscale -c /path/to/config.yaml` to specify the path to an alternative configuration file. ## How can I migrate back to the recommended IP prefixes? diff --git a/docs/ref/api.md b/docs/ref/api.md index 4337da13..5e3677f8 100644 --- a/docs/ref/api.md +++ b/docs/ref/api.md @@ -1,10 +1,10 @@ # API -Headscale provides a [HTTP REST API](#rest-api) and a [gRPC interface](#grpc) which may be used to integrate a [web -interface](integration/web-ui.md), [remote control Headscale](#setup-remote-control) or provide a base for custom +Headscale provides a [HTTP REST API](#rest-api) which may be used to integrate a [web +interface](integration/web-ui.md), [remote control Headscale](#remote-control) 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 +The API requires 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: ```shell @@ -58,15 +58,14 @@ Headscale server at `/swagger` for details. https://headscale.example.com/api/v1/auth/register ``` -## gRPC +## Remote control -The gRPC interface can be used to control a Headscale instance from a remote machine with the `headscale` binary. +The `headscale` binary can control a Headscale instance from a remote machine over the HTTP API. ### Prerequisite - A workstation to run `headscale` (any supported platform, e.g. Linux). -- A Headscale server with gRPC enabled. -- Connections to the gRPC port (default: `50443`) are allowed. +- The Headscale server reachable over HTTP(S). - Remote access requires an encrypted connection via TLS. - An [API key](#api) to authenticate with the Headscale server. @@ -88,19 +87,20 @@ The gRPC interface can be used to control a Headscale instance from a remote mac ```yaml title="config.yaml" cli: - address: : + address: api_key: ``` === "Environment variables" ```shell - export HEADSCALE_CLI_ADDRESS=":" + export HEADSCALE_CLI_ADDRESS="" export HEADSCALE_CLI_API_KEY="" ``` - This instructs the `headscale` binary to connect to a remote instance at `:`, instead of - connecting to the local instance. + This instructs the `headscale` binary to connect to a remote instance at `` (e.g. + `https://headscale.example.com`), instead of connecting to the local instance. A bare host without a scheme is + assumed to be `https`. 1. Test the connection by listing all nodes: @@ -113,15 +113,12 @@ The gRPC interface can be used to control a Headscale instance from a remote mac ### Behind a proxy -It's possible to run the gRPC remote endpoint behind a reverse proxy, like Nginx, and have it run on the _same_ port as Headscale. - -While this is _not a supported_ feature, an example on how this can be set up on -[NixOS is shown here](https://github.com/kradalby/dotfiles/blob/4489cdbb19cddfbfae82cd70448a38fde5a76711/machines/headscale.oracldn/headscale.nix#L61-L91). +The remote CLI uses the same HTTP API as everything else, so it works through the reverse proxy already in front of +Headscale with no extra setup. ### Troubleshooting - Make sure you have the _same_ Headscale version on your server and workstation. -- Ensure that connections to the gRPC port are allowed. - Verify that your TLS certificate is valid and trusted. - If you don't have access to a trusted certificate (e.g. from Let's Encrypt), either: - Add your self-signed certificate to the trust store of your OS _or_ diff --git a/docs/ref/integration/reverse-proxy.md b/docs/ref/integration/reverse-proxy.md index 723ef634..2729786a 100644 --- a/docs/ref/integration/reverse-proxy.md +++ b/docs/ref/integration/reverse-proxy.md @@ -69,7 +69,6 @@ on inbound requests with sanitized values. Headscale picks the first valid IP ad - A reverse proxy adds another layer of complexity that needs to be able to handle the [Tailscale Control Protocol](#websocket) properly. Be sure to test your setup without a reverse proxy before raising an issue. - STUN (used along with the [embedded DERP server](../derp.md)) requires udp/3478 to be served publicly. -- [gRPC](../api.md#grpc) (used to remote control Headscale) may not be proxied. ## Reverse proxy specific configuration @@ -84,14 +83,12 @@ is [assumed](../../setup/requirements.md): - Service for Tailscale clients is served via HTTPS on port 443. - The reverse proxy redirects HTTP to HTTPS and is terminating TLS. - Both Headscale and the reverse proxy are running on the same host. -- [Metrics](../debug.md#metrics-and-debug-endpoint) and [gRPC](../api.md#grpc) are not proxied, those are available via - localhost. +- [Metrics](../debug.md#metrics-and-debug-endpoint) are not proxied, those are available via localhost. ```yaml title="config.yaml" hl_lines="1" server_url: https:// listen_addr: 127.0.0.1:8080 metrics_listen_addr: 127.0.0.1:9090 -grpc_listen_addr: 127.0.0.1:50443 trusted_proxies: - 127.0.0.1/32 - ::1/128 diff --git a/docs/setup/requirements.md b/docs/setup/requirements.md index 6c11386c..da84ae85 100644 --- a/docs/setup/requirements.md +++ b/docs/setup/requirements.md @@ -26,9 +26,6 @@ The ports in use vary with the intended scenario and enabled features. Some of t - udp/3478 - Expose publicly: yes - STUN, required if the [embedded DERP server](../ref/derp.md) is enabled -- tcp/50443 - - Expose publicly: yes - - Only required if the gRPC interface is used to [remote-control Headscale](../ref/api.md#grpc). - tcp/9090 - Expose publicly: no - [Metrics and debug endpoint](../ref/debug.md#metrics-and-debug-endpoint) diff --git a/mkdocs.yml b/mkdocs.yml index 1d08b833..c360bd40 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -87,8 +87,8 @@ plugins: iOS-client.md: usage/connect/apple.md#ios oidc.md: ref/oidc.md ref/exit-node.md: ref/routes.md - ref/remote-cli.md: ref/api.md#grpc - remote-cli.md: ref/api.md#grpc + ref/remote-cli.md: ref/api.md#remote-control + remote-cli.md: ref/api.md#remote-control reverse-proxy.md: ref/integration/reverse-proxy.md tls.md: ref/tls.md web-ui.md: ref/integration/web-ui.md