Use headscale Replace tailscale
Headscale is open source, self-hosted implementation of the Tailscale control server, You can use headscale to replace tailscale. (headscale version > 0.22.3)
DOWNLOADS & BUILD INSTALL
# headscale version > 0.22.3
git clone [email protected]:juanfont/headscale.git
cd headscale
go mod tidy
go build ./cmd/headscale
useradd headscale
mkdir /usr/local/headscale
cp headscale /usr/local/headscale/
chown headscale:headscale /usr/local/headscale/
GENERATE PRIVATE KEY
/usr/local/headscale/headscale generate private-key > headscale/data/private.key
/usr/local/headscale/headscale generate private-key > headscale/data/noise_private.key
CONFIGURATION
/usr/local/headscale/config.yaml
# The url clients will connect to.
# Typically this will be a domain like:
#
# https://myheadscale.example.com:443
#
server_url: https://<IPADDRESS>:8080
# Address to listen to / bind to on the server
listen_addr: 0.0.0.0:8080
# Address to listen to /metrics, you may want
# to keep this endpoint private to your internal
# network
metrics_listen_addr: 127.0.0.1:9090
# Address to listen for gRPC.
grpc_listen_addr: 127.0.0.1:50443
# Allow the gRPC admin interface to run in INSECURE
grpc_allow_insecure: false
# The Noise section includes specific configuration for the
# TS2021 Noise protocol
noise:
private_key_path: /usr/local/headscale/data/noise_private.key
# List of IP prefixes to allocate tailaddresses from.
prefixes:
v4: 100.65.0.0/16
allocation: sequential
# DERP server configuration (if using an embedded DERP server)
derp:
server:
enabled: false
region_id: 999
region_code: "headscale"
region_name: "Headscale Embedded DERP"
stun_listen_addr: "0.0.0.0:3478"
private_key_path: /usr/local/headscale/data/private.key
automatically_add_embedded_derp_region: true
# List of externally available DERP maps encoded in JSON
urls:
- https://controlplane.tailscale.com/derpmap/default
# Paths to local DERP map files (if any)
paths: []
# Auto-update DERP map
auto_update_enabled: true
update_frequency: 24h
# 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
database:
type: sqlite3
sqlite:
path: /usr/local/headscale/data/db.sqlite
### TLS configuration ###
# Use already defined certificates:
tls_cert_path: "/usr/local/headscale/data/ssl/server.crt"
tls_key_path: "/usr/local/headscale/data/ssl/server.key"
log:
format: text
level: info
# DNS configuration
dns_config:
override_local_dns: false
nameservers:
- 1.1.1.1
magic_dns: false
base_domain: example.com
# Unix socket used for the CLI to connect without authentication
unix_socket: /usr/local/headscale/headscale.sock
unix_socket_permission: "0770"
# Logtail configuration (if using)
logtail:
enabled: false
# Randomize client port for WireGuard traffic
randomize_client_port: false
SYSTEMD
/lib/systemd/system/headscale.service
[Unit]
After=syslog.target
After=network.target
Description=headscale coordination server for Tailscale
X-Restart-Triggers=/usr/local/headscale/config.yaml
[Service]
Type=simple
User=headscale
Group=headscale
ExecStart=/usr/local/headscale/headscale -c /usr/local/headscale/config.yaml serve
Restart=always
RestartSec=5
WorkingDirectory=/usr/local/headscale
ReadWritePaths=/usr/local/headscale /var/run
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_CHOWN
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_CHOWN
LockPersonality=true
NoNewPrivileges=true
PrivateDevices=true
PrivateMounts=true
PrivateTmp=true
ProcSubset=pid
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHome=yes
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=strict
RemoveIPC=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
RuntimeDirectory=headscale
RuntimeDirectoryMode=0750
StateDirectory=headscale
StateDirectoryMode=0750
SystemCallArchitectures=native
SystemCallFilter=@chown
SystemCallFilter=@system-service
SystemCallFilter=~@privileged
UMask=0077
[Install]
WantedBy=multi-user.target
RUN HEADSCALE
test:
/usr/local/headscale/headscale -c /usr/local/headscale/config.yaml serve
with systemd:
systemctl start headscale.service
CONNECT
create user
/usr/local/headscale/headscale -c /usr/local/headscale/config.yaml user create default
/usr/local/headscale/headscale -c /usr/local/headscale/config.yaml user list
client login server
# linux & macos
sudo tailscale up --operator=default --login-server http://<IPADDRESS>:8080
# windows
tailscale login --login-server http://<IPADDRESS>:8080
server register
headscale nodes register --user USERNAME --key mkey:xx...xxx
# check node
/usr/local/headscale/headscale -c /usr/local/headscale/config.yaml -c config.yaml nodes list