# Install and configure the Tailscale VPN service

Install Tailscale on your PC and log in with your account.

Once you create an account in Tailscale, you can generate API keys in the admin console.

<figure><img src="/files/jRvsxMWnRVAEL71n2b8A" alt=""><figcaption></figcaption></figure>

Generate the Auth Keys. There are options to:

* Generate a key that gets deactivated after authorising one device
* Generate a key that can authorise many devices.

<div align="left"><figure><img src="/files/iCnK6w4Atv76VcbZOlyp" alt="" width="563"><figcaption></figcaption></figure></div>

Enable 'Reusable' to specify an expiry date.

<figure><img src="/files/j0sBBRZjT1z55rAjRknu" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**Note:**

* Before you begin, ensure the device's time is correct (timedatectl); otherwise, enable ntp sync.
  {% endhint %}

Below is an example script for installation. One can modify the version to be installed, as well as the location where the key is stored, if needed.&#x20;

{% embed url="<https://pkgs.tailscale.com/stable/#static>" %}

{% hint style="info" %}
**Note:**

* Ensure the device has an active internet connection when installing.
  {% endhint %}

```xml-doc
#!/bin/bash
set -e

# Enable debugging if DEBUG=1
if [ "${DEBUG:-0}" = "1" ]; then
  set -x
fi

# Tailscale settings
TS_VER="1.90.5"
TS_ARCH="arm64"
TS_TGZ="tailscale_${TS_VER}_${TS_ARCH}.tgz"
TS_URL="https://pkgs.tailscale.com/stable/${TS_TGZ}"
SERIAL_FILE="/home/root/rexusb/serial"

# Standard locations
BIN_DIR="/usr/bin"
STATE_DIR="/var/lib/tailscale"
SOCKET_DIR="/run/tailscale"
SYSTEMD_SERVICE="/etc/systemd/system/tailscaled.service"
DEFAULTS_FILE="/etc/default/tailscaled"

# Hardcoded auth key - replace with your actual key
AUTHKEY="tskey-auth-kDBxyp1FBu11CNT4"

log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1"; }
fail() { log "? $1"; exit 1; }

log "Creating required directories..."
mkdir -p "$STATE_DIR" "$SOCKET_DIR"

cd /tmp || fail "Could not change to /tmp"

log "Downloading ${TS_TGZ}..."
wget -q "$TS_URL" -O "$TS_TGZ" || fail "Failed to download Tailscale package"

log "Extracting package..."
tar -xzf "$TS_TGZ" || fail "Failed to extract Tailscale package"

TS_EXTRACTED_DIR=$(find . -maxdepth 1 -type d -name "tailscale_*_${TS_ARCH}" | head -n1)
[ -z "$TS_EXTRACTED_DIR" ] && fail "Could not find extracted Tailscale directory"
TS_EXTRACTED_DIR=${TS_EXTRACTED_DIR#./}

log "Installing tailscale binaries to $BIN_DIR..."
cp "$TS_EXTRACTED_DIR/tailscale" "$BIN_DIR/tailscale"
cp "$TS_EXTRACTED_DIR/tailscaled" "$BIN_DIR/tailscaled"
chmod +x "$BIN_DIR/tailscale" "$BIN_DIR/tailscaled"

[ ! -f "$SERIAL_FILE" ] && fail "Serial file not found: $SERIAL_FILE"

HOSTNAME=$(tr -d '\n\r' < "$SERIAL_FILE")
[ -z "$HOSTNAME" ] && fail "Hostname is empty!"

# Sanitize hostname
SANITIZED_HOSTNAME=$(echo "$HOSTNAME" | tr -cd 'a-zA-Z0-9')
[ "$SANITIZED_HOSTNAME" != "$HOSTNAME" ] && log "Sanitized hostname: $SANITIZED_HOSTNAME"
HOSTNAME="$SANITIZED_HOSTNAME"
[ ${#HOSTNAME} -gt 63 ] && HOSTNAME="${HOSTNAME:0:63}"

# Defaults file
log "Creating /etc/default/tailscaled..."
cat <<EOF > "$DEFAULTS_FILE"
# Extra options for tailscaled
#TAILSCALED_OPTS=""
EOF

# Fixed systemd service with CAP_SETGID
log "Creating systemd service at $SYSTEMD_SERVICE..."
cat <<EOF > "$SYSTEMD_SERVICE"
[Unit]
Description=Tailscale node agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
EnvironmentFile=-/etc/default/tailscaled
ExecStart=/usr/bin/tailscaled \$TAILSCALED_OPTS --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
KillMode=process
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID

[Install]
WantedBy=multi-user.target
EOF

log "Reloading systemd and starting tailscaled..."
systemctl daemon-reexec || log "daemon-reexec failed, continuing"
systemctl daemon-reload || fail "Failed to reload systemd"
systemctl enable tailscaled.service || fail "Failed to enable service"
systemctl restart tailscaled.service || fail "Failed to start service"

# Wait for socket
MAX_WAIT=30
for i in $(seq 1 $MAX_WAIT); do
  if [ -S /run/tailscale/tailscaled.sock ]; then
    log "✓ Socket ready after $i seconds"
    break
  fi
  log "Waiting for tailscaled to initialize... ($i/$MAX_WAIT)"
  sleep 1
  systemctl is-active --quiet tailscaled.service || fail "tailscaled died"
  [ $i -eq $MAX_WAIT ] && fail "Timeout waiting for tailscaled socket"
done

log "Running tailscale up..."
# Disable Tailscale DNS management so we can use public DNS
tailscale --socket=/run/tailscale/tailscaled.sock up --authkey $AUTHKEY --ssh --hostname $HOSTNAME --accept-dns=false

# --- Permanent DNS fix ---
log "Configuring permanent DNS..."
cat <<EOF > /etc/resolv.conf
# Managed manually to avoid Tailscale overwrite
nameserver 8.8.8.8
nameserver 1.1.1.1
EOF
chmod 644 /etc/resolv.conf
log "DNS configured: $(cat /etc/resolv.conf)"

log "Installation complete!"
log "Check Tailscale status: tailscale --socket=/run/tailscale/tailscaled.sock status"

```

#### Example:

<figure><img src="/files/PT67KTxEFgL1ZrEw96vP" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.influxtechnology.com/support_guides/rexgen-series-product-manuals/rexgen-oem-product-manual/rexgen-oem-product-manual/how-to-with-rexgen-oem/install-and-configure-the-tailscale-vpn-service.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
