Document · Network Access · 9 min read
Enable HTTPS over Tailscale for Kaptain
Put Tailscale Serve in front of Kaptain so browser traffic uses a trusted HTTPS URL on your tailnet hostname, while Kaptain keeps listening only on localhost.
What this enables
Kaptain starts on the local machine and is safest when it is reachable only from the same machine or from trusted devices over Tailscale. Tailscale already encrypts traffic between devices in the tailnet, but browsers still treat plain http:// URLs as not HTTPS. Tailscale Serve gives the browser a normal https:// URL for Kaptain without exposing anything beyond the tailnet.
Use the full Tailscale MagicDNS name, such as kaptain-box.example.ts.net. A bare machine name such as https://kaptain-box is not enough for a Tailscale-issued certificate.
Requirements
- Tailscale is installed and signed in on the Kaptain machine.
- The device you use to open Kaptain is signed in to the same tailnet and has access to the Kaptain machine.
- MagicDNS is enabled in the Tailscale admin console.
- HTTPS Certificates are enabled in the Tailscale admin console.
- Kaptain has completed setup, so it has an access code for browser pairing.
Kaptain's Network Access mode stays on Localhost only for this setup. Tailscale Serve connects to Kaptain over loopback, and Kaptain's network ACL rejects loopback callers while it is in Tailscale mode.
Find the Tailscale name for the Kaptain machine
- Open the Tailscale admin console.
- Go to Machines.
- Open the Kaptain machine.
- Copy its full MagicDNS name, for example
kaptain-box.example.ts.net.
You can also find the tailnet DNS name on the DNS page in the admin console. The full name is the machine name plus the tailnet DNS name.
Set up Tailscale Serve
Tailscale Serve is the way to put HTTPS in front of Kaptain. Kaptain keeps listening on 127.0.0.1:8810 in plain HTTP; tailscaled terminates TLS for the tailnet hostname and forwards the request to that local port.
1. Start Kaptain and confirm it answers locally
kaptain start
kaptain status
kaptain status prints the UI URL. Open http://localhost:8810 on the Kaptain machine and confirm the interface loads before going further.
2. Publish it with Tailscale Serve
In a terminal on the Kaptain machine:
tailscale serve 8810
Serve prints the HTTPS URL it is now handling for this machine, for example https://kaptain-box.example.ts.net/. That URL is reachable only from devices in the same tailnet. Keep the command running, or use Tailscale's own background/service option so the proxy survives closing the terminal.
Note the port: the browser now uses the standard HTTPS port on the tailnet hostname. It does not use 8810. Port 8810 stays private to the Kaptain machine.
Allow the tailnet hostname in Kaptain
Kaptain checks the Host header on every request and rejects values it does not recognise, which is what stops a hostile web page from resolving its own name to 127.0.0.1 and talking to your Kaptain. Through Serve the browser sends the MagicDNS name, so that name has to be on the list or Kaptain answers 421 Misdirected Request.
There is no setting for this in the interface. Edit kaptain.json in the Kaptain data directory:
- Linux —
~/.local/share/kaptain/kaptain.json - macOS —
~/Library/Application Support/Kaptain/kaptain.json - Windows —
%LOCALAPPDATA%\Kaptain\kaptain.json
Add the full MagicDNS name to allowed_hosts, leaving network_mode alone:
{
"network_mode": "localhost",
"allowed_hosts": ["kaptain-box.example.ts.net"]
}
Then restart Kaptain so it reloads the file:
kaptain stop
kaptain start
100.64.0.0/10 range — including tailscaled's own Serve proxy, which connects over loopback. The two setups are alternatives, not layers.Kaptain itself does not serve TLS
Kaptain's server speaks plain HTTP. It has no certificate configuration, and it does not read cert.pem or key.pem from any folder. Running tailscale cert to produce certificate files and dropping them next to Kaptain has no effect: Kaptain will keep answering on http:// and an https://…:8810 URL will fail to connect.
If you do not want to run Serve, the alternative is plain HTTP over the tailnet: set Network Access to Tailscale in Settings, restart, and open http://<tailscale-ip>:8810 from another device in the tailnet. Traffic is still encrypted device-to-device by Tailscale itself; the browser just does not display an HTTPS indicator, and browser features that require a secure context are unavailable.
Verify the connection
- Open the HTTPS URL from another trusted Tailscale device.
- Confirm the browser shows HTTPS for the full MagicDNS name.
- Enter this Kaptain's access code (
chynj_…) when the pairing screen asks for it. - Open Settings and make a harmless change before entering any new provider key.
- If the page returns "Host header is not allowed", the MagicDNS name is missing from
allowed_hostsor Kaptain has not been restarted since you added it. - If the page does not load at all, check that
tailscale serveis still running and that the second device is connected to the tailnet.
Certificate renewal
With Tailscale Serve, Tailscale obtains and renews the certificate for the tailnet hostname itself. There are no certificate files to copy into Kaptain and nothing to re-run before expiry. Renewal requires that HTTPS Certificates stay enabled for the tailnet and that the machine keeps its MagicDNS name.