headwire

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: BSD-3-Clause

README

Headwire app icon
Headwire

Headwire statically configures WireGuard peers with support for NAT traversal using DERP relays. It is experimental.

Initial connections will happen over DERP, then upgrade to a direct path if one is found:

$ headwire ping 100.64.0.2
pong from 100.64.0.2 via relay:1 in 122ms
pong from 100.64.0.2 via relay:1 in 118ms
pong from 100.64.0.2 via 203.0.113.10:41198 in 1ms

Headwire is built using Tailscale's open-source data plane libraries. See this blog post for background.

Features

  • establish direct connections where possible
  • fall back to relayed connections
  • continue using ordinary WireGuard peers
  • a macOS app

Configuration Example

Run your own DERP servers. Tailscale runs "free rate-limited DERP relays" for Tailcat, see its DERP map.

[DERPRegion]
ID = 1
Nodes = derp1.example.com, derp2.example.com

[Interface]
PrivateKey = <base64 private key from headwire genkey>
Address = 100.64.0.1/32
HomeDERP = 1

[Peer]
PublicKey = <peer base64 public key>
DiscoKey = <peer base64 disco key>
AllowedIPs = 100.64.0.2/32, 10.20.0.0/16
HomeDERP = 1
  • Every peer has a WireGuard PublicKey.
  • Ordinary WireGuard peers use a fixed Endpoint.
  • Headwire peers have a DiscoKey and HomeDERP region.
  • See the more complete example.

Usage

Install a release from the project releases page, then create a configuration:

sudo install -d -o root -g "$(id -g root)" -m 755 /etc/headwire
sudo install -o root -g "$(id -g root)" -m 600 /dev/null /etc/headwire/main.conf
sudoedit /etc/headwire/main.conf
sudo headwire check

Run Headwire:

sudo headwire run

Or as a service:

sudo systemctl enable --now headwire
sudo systemctl status headwire

CLI Reference

usage: headwire <command>

Commands:
  show [FIELD]           status of the running node, --help lists fields
  ip [-1|-4|-6]          local addresses of the running node
  ping IP                disco-ping up to 10 times, stopping at a direct response
  check [NAME | FILE]    validate the configuration (default: main)
  genkey                 print a new private key
  pubkey                 read a private key on stdin, print its WireGuard public key
  discokey               read a private key on stdin, print its discovery public key
  genpsk                 print a new preshared key
  netcheck [NAME | FILE] probe connectivity to configured relay regions
  version                print the build version
  run [NAME | FILE]      run the node on a TUN interface (root, default: main)

NAME selects /etc/headwire/NAME.conf, any other argument is a file.
Use help COMMAND or COMMAND --help for command-specific help.

Configuration Reference

Section Key Meaning
[Interface] PrivateKey required
Address * required, one or more IPv4 or IPv6 addresses
ListenPort UDP port number, 0 or omitted picks a random one
MTU defaults to 1280
DNS * addresses are nameservers, other entries search domains
HomeDERP this node's relay region
AllowIn * default inbound policy for peers that set none
[Peer] PublicKey required
DiscoKey makes this a discovery peer
AllowedIPs * valid routes and sources, overlaps go to the longest prefix
PresharedKey optional
Endpoint fixed host:port, a static candidate for a discovery peer
HomeDERP relay region the peer is reached through
MasqueradeAddress * source address for packets sent to this peer
AllowIn * replaces the [Interface] policy for this peer
[DERPRegion] ID required, 1-65535
Nodes required, relay hostnames in preference order

A key marked * may be repeated or given as a comma-separated list.

AllowIn is any, none, or PROTO[/PORT[-PORT]], optionally followed by to self|any|IP|CIDR. PROTO is tcp, udp, sctp, icmp or a protocol number, and only the first three take ports. The default is any. Examples:

AllowIn = tcp/22, icmp
AllowIn = udp/5000-5100 to self

This project is not associated with Tailscale Inc. or WireGuard.

Tailscale is a registered trademark of Tailscale Inc.

WireGuard is a registered trademark of Jason A. Donenfeld.

Directories

Path Synopsis
bridge
apple command
The C ABI an Apple NetworkExtension provider links, built with -buildmode=c-archive by build.sh.
The C ABI an Apple NetworkExtension provider links, built with -buildmode=c-archive by build.sh.
cmd
headwire command
Command headwire connects statically configured WireGuard peers, using tailscale.com's magicsock for DERP relaying and NAT traversal.
Command headwire connects statically configured WireGuard peers, using tailscale.com's magicsock for DERP relaying and NAT traversal.
internal
apple
Package apple is the lifecycle behind the C ABI in bridge/apple: an Apple NetworkExtension provider prepares a configuration, applies the returned settings to the system, then starts the engine on the utun descriptor the system gave it.
Package apple is the lifecycle behind the C ABI in bridge/apple: an Apple NetworkExtension provider prepares a configuration, applies the returned settings to the system, then starts the engine on the utun descriptor the system gave it.
cli
Package cli is the headwire command line shared by every program: the headwire binary adds run, and Headwire.app adds its profile and GUI verbs.
Package cli is the headwire command line shared by every program: the headwire binary adds run, and Headwire.app adds its profile and GUI verbs.
config
Package config parses and validates headwire's INI configuration: an Interface section, optional repeated [DERPRegion] sections forming a static DERP map, and repeated Peer sections.
Package config parses and validates headwire's INI configuration: an Interface section, optional repeated [DERPRegion] sections forming a static DERP map, and repeated Peer sections.
discokey
Package discokey derives a node's discovery key from its node private key.
Package discokey derives a node's discovery key from its node private key.
engine
Package engine drives tailscale.com's wgengine and magicsock from a static headwire configuration: no control plane, no LocalBackend.
Package engine drives tailscale.com's wgengine and magicsock from a static headwire configuration: no control plane, no LocalBackend.
status
Package status is the status socket's field vocabulary, shared by the client that builds a request and the engine that answers it.
Package status is the status socket's field vocabulary, shared by the client that builds a request and the engine that answers it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL