Install Tailscale DERP server for increased privacy and lower latency.
Operating system.
$ lsb_release --all
No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04 LTS Release: 22.04 Codename: jammy
Firewall service
Install dynamically managed firewall daemon.
$ sudo apt install firewalld
Inspect network interfaces.
$ ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128 ens3 UP 192.0.2.113/23
Inspect public zone.
$ sudo firewall-cmd --list-all --zone public
public (active) target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Add external interface to public zone.
$ sudo firewall-cmd --add-interface ens3 --zone public
success
Allow incoming connections on HTTP, HTTPS, STUN ports to DERP server.
$ sudo firewall-cmd --add-port 80/tcp --add-port 443/tcp --add-port 3478/udp --zone public
success
Inspect public zone.
$ sudo firewall-cmd --list-all --zone public
public (active) target: default icmp-block-inversion: no interfaces: ens3 sources: services: dhcpv6-client ssh ports: 80/tcp 443/tcp 3478/udp protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Install Go programming language
Do not install golang
package which provides Go 1.18, as DERP server requires Go 1.19.
Open Go download page and follow these instructions.
$ wget --output-document /opt/go1.19.4.linux-amd64.tar.gz https://go.dev/dl/go1.19.4.linux-amd64.tar.gz
$ sudo rm -rf /usr/local/go && sudo tar --directory /usr/local --extract --gzip --file /opt/go1.19.4.linux-amd64.tar.gz
Join Tailscale network
Open Tailscale download page and follow these instructions.
Install dependencies.
$ sudo apt install wget
Download package signing key.
$ sudo wget --output-document /usr/share/keyrings/tailscale-archive-keyring.gpg https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg
Download repository definition.
$ sudo wget --output-document /etc/apt/sources.list.d/tailscale.list https://pkgs.tailscale.com/stable/ubuntu/jammy.tailscale-keyring.list
Update package index.
$ sudo apt update
Install Tailscale.
$ sudo apt install tailscale
Connect your machine to your Tailscale network.
$ sudo tailscale up
This step is important as we want to ensure that this DERP server will serve verified clients.
Install DERP server
Create derp
user that will be used to run service.
$ sudo useradd --system --create-home --home-dir /opt/derp --shell /bin/bash derp
Ensure that it can execute Go binaries.
$ echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee -a /opt/derp/.profile
Verify that assumption.
$ sudo -u derp -i go version
go version go1.19.4 linux/amd64
Install DERP server.
$ sudo -u derp -i go install tailscale.com/cmd/derper@main
go: downloading github.com/mitchellh/go-ps v1.0.0 go: downloading github.com/fxamacker/cbor/v2 v2.4.0 go: downloading github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 go: downloading github.com/x448/float16 v0.8.4 go: downloading filippo.io/edwards25519 v1.0.0-rc.1 go: downloading go4.org/netipx v0.0.0-20220725152314-7e7bdc8411bf
Display help information.
$ sudo -u derp -i /opt/derp/go/bin/derper --help
Usage of /opt/derp/go/bin/derper: -a string server HTTPS listen address, in form ":port", "ip:port", or for IPv6 "[ip]:port". If the IP is omitted, it defaults to all interfaces. (default ":443") -accept-connection-burst int burst limit for accepting new connection (default 9223372036854775807) -accept-connection-limit float rate limit for accepting new connection (default +Inf) -bootstrap-dns-names string optional comma-separated list of hostnames to make available at /bootstrap-dns -c string config file path -certdir string directory to store LetsEncrypt certs, if addr's port is :443 (default "/opt/derp/.cache/tailscale/derper-certs") -certmode string mode for getting a cert. possible options: manual, letsencrypt (default "letsencrypt") -derp whether to run a DERP server. The only reason to set this false is if you're decommissioning a server but want to keep its bootstrap DNS functionality still running. (default true) -dev run in localhost development mode -hostname string LetsEncrypt host name, if addr's port is :443 (default "derp.tailscale.com") -http-port int The port on which to serve HTTP. Set to -1 to disable. The listener is bound to the same IP (if any) as specified in the -a flag. (default 80) -mesh-psk-file string if non-empty, path to file containing the mesh pre-shared key file. It should contain some hex string; whitespace is trimmed. -mesh-with string optional comma-separated list of hostnames to mesh with; the server's own hostname can be in the list -stun whether to run a STUN server. It will bind to the same IP (if any) as the --addr flag value. (default true) -stun-port int The UDP port on which to serve STUN. The listener is bound to the same IP (if any) as specified in the -a flag. (default 3478) -unpublished-bootstrap-dns-names string optional comma-separated list of hostnames to make available at /bootstrap-dns and not publish in the list -verify-clients verify clients to this DERP server through a local tailscaled instance.
Ensure that it can open required ports as regular user.
$ sudo setcap 'cap_net_bind_service=+ep' /opt/derp/go/bin/derper
Create systemd service.
$ sudo tee /etc/systemd/system/derper.service <<'EOF' [Unit] Description=DERP Server After=network.target [Service] User=derp Group=derp Environment=DOMAIN=derper.example.org Environment=DIRECTORY=/opt/derp ExecStart=/bin/bash -c "${DIRECTORY}/go/bin/derper -c ${DIRECTORY}/derp.conf --hostname ${DOMAIN} --verify-clients" Restart=always [Install] WantedBy=multi-user.target EOF
[Unit] Description=DERP Server After=network.target [Service] User=derp Group=derp Environment=DOMAIN=derper.example.org Environment=DIRECTORY=/opt/derp ExecStart=/bin/bash -c "${DIRECTORY}/go/bin/derper -c ${DIRECTORY}/derp.conf --hostname ${DOMAIN} --verify-clients" Restart=always [Install] WantedBy=multi-user.target
Reload systemd configuration.
$ sudo systemctl daemon-reload
Enable DERP server.
$ systemctl enable --now derper
Created symlink /etc/systemd/system/multi-user.target.wants/derper.service → /etc/systemd/system/derper.service.
Check service status.
$ sudo systemctl status derper
● derper.service - DERP Server Loaded: loaded (/etc/systemd/system/derper.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2022-12-30 21:58:32 CET; 2s ago Main PID: 12625 (derper) Tasks: 4 (limit: 2242) Memory: 2.0M CPU: 7ms CGroup: /system.slice/derper.service └─12625 /opt/derp/go/bin/derper -c /opt/derp/derp.conf --hostname derper.example.org --verify-clients Dec 30 21:58:32 derper.example.org systemd[1]: Started DERP Server. Dec 30 21:58:32 derper.example.org bash[12625]: 2022/12/30 21:58:32 derper: serving on :443 with TLS Dec 30 21:58:32 derper.example.org bash[12625]: 2022/12/30 21:58:32 running STUN server on [::]:3478
Add DERP map to your Access Control policy.
// Example/default ACLs for unrestricted connections. { // Declare static groups of users beyond those in the identity service. "groups": { "group:example": ["user1@example.com", "user2@example.com"], }, // Declare convenient hostname aliases to use in place of IP addresses. "hosts": { "example-host-1": "100.100.100.100", }, // Access control lists. "acls": [ // Match absolutely everything. // Comment this section out if you want to define specific restrictions. {"action": "accept", "users": ["*"], "ports": ["*:*"]}, ], "ssh": [ // Allow all users to SSH into their own devices in check mode. // Comment this section out if you want to define specific restrictions. { "action": "check", "src": ["autogroup:members"], "dst": ["autogroup:self"], "users": ["autogroup:nonroot", "root"], }, ], "derpMap": { "OmitDefaultRegions": true, "Regions": { "900": { "RegionID": 900, "RegionCode": "kraken", "Nodes": [ { "Name": "derper", "RegionID": 900, "HostName": "derper.example.org", }, ], }, }, }, }
That is all, inspect machine status to see latency from your own Tailscale relay (DERP) server.