Skip to content

Chapter 9: Remote Access and Networking

Want to control your lobster from anywhere? This chapter covers remote access.

Prerequisite: You have completed Chapter 8: Gateway Operations and Gateway is running normally.

Gateway runs locally by default (127.0.0.1:18789). To access it from other devices, you need a "tunnel". Two-minute version: Tailscale is recommended — install it and one command gets you set up.

1. Which Option Should You Choose?

OptionBest ForDifficulty
Tailscale NetworkingMulti-device cross-network, best experience⭐⭐
SSH TunnelWorks anywhere you have SSH, most universal
LAN Direct ConnectWithin the same local network

Not sure which to pick? Start with Tailscale — automatic HTTPS, no manual port forwarding, multi-device sharing.

2. SSH Tunnel (Most Universal Method)

At a coffee shop and want to connect back to your home Gateway? One command sets up a tunnel:

bash
ssh -N -L 18789:127.0.0.1:18789 user@remote-host-ip

Open another terminal to verify:

bash
openclaw status --deep

Seeing the Gateway status means it's connected.

Tired of typing the long command every time? Configure SSH Config to simplify it

Edit ~/.ssh/config and add:

Host my-gateway
    HostName 172.27.187.184        # Replace with your remote host IP
    User jefferson                  # Replace with your username
    LocalForward 18789 127.0.0.1:18789
    IdentityFile ~/.ssh/id_rsa

Afterwards, just run:

bash
ssh -N my-gateway

Passwordless login: Copy your public key to the remote host so you never need to type a password again:

bash
ssh-copy-id -i ~/.ssh/id_rsa user@remote-host-ip

Token Authentication: If Gateway has authentication enabled, you also need to provide a token when connecting:

bash
# macOS
launchctl setenv OPENCLAW_GATEWAY_TOKEN "your-token"

# Linux
export OPENCLAW_GATEWAY_TOKEN="your-token"

Or write it to a config file to persist it:

json5
{
  gateway: {
    mode: "remote",
    remote: {
      url: "ws://127.0.0.1:18789",
      token: "your-token",
    },
  },
}

SSH tunneling transparently forwards traffic, so the URL remains ws://127.0.0.1:18789.

Auto-start tunnel on boot (macOS LaunchAgent)

Save as ~/Library/LaunchAgents/ai.openclaw.ssh-tunnel.plist:

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>ai.openclaw.ssh-tunnel</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/ssh</string>
        <string>-N</string>
        <string>my-gateway</string>
    </array>
    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Load it:

bash
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/ai.openclaw.ssh-tunnel.plist

Common management commands:

bash
ps aux | grep "ssh -N my-gateway" | grep -v grep  # Check if running
lsof -i :18789                                      # Check port
launchctl kickstart -k gui/$UID/ai.openclaw.ssh-tunnel  # Restart
launchctl bootout gui/$UID/ai.openclaw.ssh-tunnel       # Stop
Auto-start tunnel on boot (Linux systemd)

Create ~/.config/systemd/user/openclaw-tunnel.service:

ini
[Unit]
Description=OpenClaw SSH Tunnel
After=network-online.target

[Service]
ExecStart=/usr/bin/ssh -N -L 18789:127.0.0.1:18789 my-gateway
Restart=always
RestartSec=10

[Install]
WantedBy=default.target
bash
systemctl --user enable --now openclaw-tunnel
systemctl --user status openclaw-tunnel

Tailscale makes all your devices feel like they're on the same local network — phones, laptops, VPS can all access Gateway directly, with automatic HTTPS and no manual port forwarding needed.

3.1 Quickest Start: Tailscale Serve

Configure Tailscale Serve via CLI:

bash
openclaw config set gateway.bind loopback
openclaw config set gateway.tailscale.mode serve
openclaw gateway restart

After restarting, access from any device within your tailnet: https://<your-MagicDNS-address>/

Or equivalently, one command:

bash
openclaw gateway --tailscale serve

Prerequisite: Tailscale must be installed and you must be logged in with tailscale up, and HTTPS must be enabled on your tailnet.

Can Serve mode skip the token?

Yes. After setting gateway.auth.allowTailscale: true, devices within the tailnet can access the Control UI and WebSocket without a token — Tailscale identity headers authenticate automatically.

Note: HTTP API endpoints such as /v1/* and /tools/invoke still require token authentication.

If untrusted code might run on the host, it is recommended to disable this:

json5
{
  gateway: {
    auth: { allowTailscale: false },
  },
}
Need public internet access? Use Tailscale Funnel

Funnel exposes Gateway to the public internet — password authentication must be configured:

json5
{
  gateway: {
    bind: "loopback",
    tailscale: { mode: "funnel" },
    auth: {
      mode: "password",
      password: "replace-with-strong-password",
    },
  },
}

CLI equivalent:

bash
openclaw gateway --tailscale funnel --auth password

Use the environment variable OPENCLAW_GATEWAY_PASSWORD for the password rather than hardcoding it in the config file.

Funnel requirements: Tailscale v1.38.3+, MagicDNS, HTTPS, only ports 443/8443/10000 are supported, macOS requires the open-source client.

Skip Serve/Funnel and bind directly to the Tailnet IP
json5
{
  gateway: {
    bind: "tailnet",
    auth: {
      mode: "token",
      token: "your-token",
    },
  },
}

Access URL: http://<tailscale-ip>:18789/ (note: 127.0.0.1:18789 is not available in this mode)

Reference docs: Tailscale Serve · Tailscale Funnel

Common deployment architecture reference

Architecture 1: VPS online 24/7, laptop as remote control

Laptop frequently sleeping with the lid closed? Run Gateway on a VPS or home server:

Cloud server 24/7 deployment architecture: Gateway deployed on VPS, laptop connects remotely via SSH tunnel

mermaid
flowchart LR

A["VPS / Home Server
Gateway(24h Online)
Loopback Bind"]

B["Your Laptop
Remote Control"]

B -->|SSH / Tailscale Tunnel| A

Recommended: Gateway bind: "loopback" + Tailscale Serve or SSH tunnel.


Architecture 2: Desktop + Laptop

macOS users can use OpenClaw.app's built-in "Remote over SSH" mode directly: Settings → General → "OpenClaw runs" → select "Remote over SSH". The app manages the SSH tunnel automatically.


Architecture 3: Laptop is your primary machine, other devices access occasionally

Use Tailscale Serve to expose the Control UI; keep Gateway on loopback binding.

How do messages flow from chat apps to nodes?
Telegram message

Gateway receives message

Gateway runs Agent, decides whether to call node tools

Gateway calls node via WebSocket (node.* RPC)

Node returns result

Gateway replies to Telegram

Key point: nodes do not run Gateway — they are peripheral devices connected via WebSocket. Only one Gateway runs per host (unless using --profile for isolation).

4. Credentials and Authentication

One-line rule: Explicit parameters (--token, --password) take highest priority, followed by environment variables, then the config file.

When using --url to override the connection address, credentials from the config file are not carried over automatically — you must also pass --token or --password.

Full credential priority table

Local mode:

Token: --token > OPENCLAW_GATEWAY_TOKEN > gateway.auth.token > gateway.remote.token
Password: --password > OPENCLAW_GATEWAY_PASSWORD > gateway.auth.password > gateway.remote.password

Remote mode:

Token: gateway.remote.token > OPENCLAW_GATEWAY_TOKEN > gateway.auth.token
Password: --password > OPENCLAW_GATEWAY_PASSWORD > gateway.remote.password > gateway.auth.password

Other details:

  • gateway.remote.token / gateway.remote.password are client credentials and do not control server-side authentication
  • When gateway.auth.token is configured via SecretRef but resolution fails, authentication fails immediately (no fallback, to avoid masking configuration errors)
  • Remote probe/status strictly uses gateway.remote.token and does not fall back to the local token
  • Legacy CLAWDBOT_GATEWAY_* environment variables are only kept for backward compatibility

5. Security Best Practices

Golden rule: Keep Gateway on loopback binding unless you are certain you need to expose it externally.

ConfigurationRecommendation
Gateway bindingloopback + SSH or Tailscale Serve (most secure)
Non-loopback bindingToken or password authentication is required
Plaintext ws://Loopback only; private networks require OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1
TLS fingerprint pinningUse gateway.remote.tlsFingerprint to pin certificates for remote wss://
Tailscale ServeCan set allowTailscale: true to skip token; HTTP API still requires authentication
FunnelMust use password authentication (automatically enforced)
Browser controlTreat as operator-level access — tailnet-only, pair nodes with care
Secure configuration for cross-machine browser control

Run the node (node host) on the machine where the browser is located, with both machines on the same tailnet. Gateway proxies browser operations to the node via WebSocket — no additional Serve URL is needed. Avoid using Funnel for browser control — node pairing permissions are equivalent to operator access.

Can't connect? Troubleshooting

SSH tunnel troubleshooting:

bash
ps aux | grep "ssh -N" | grep -v grep  # Check if tunnel is running
lsof -i :18789                          # Check if port is in use
openclaw status                         # Manually test connection

Common issues:

SymptomPossible CauseSolution
connection refusedTunnel not established or Gateway not runningCheck SSH tunnel and Gateway status
401 UnauthorizedToken mismatchCheck that OPENCLAW_GATEWAY_TOKEN matches the Gateway configuration
Tailscale Serve inaccessibleHTTPS not enabledEnable HTTPS in the Tailscale admin console
Funnel fails to startPassword not configured or Tailscale version too oldSet auth.mode: "password" and upgrade Tailscale
--url parameter authentication fails--url does not reuse config file credentialsAlso pass --token or --password

Verify remote connection:

bash
# Via SSH tunnel
ssh -N -L 18789:127.0.0.1:18789 my-gateway &
openclaw status --deep

# Via Tailscale
openclaw gateway status --url ws://<tailscale-ip>:18789 --token your-token

Summary

Your ScenarioRecommended Option
Just need SSH, simplest optionSSH tunnel + loopback
Multi-device cross-network, best experienceTailscale Serve + loopback
Need public internet accessTailscale Funnel + password
Same local networkLAN binding + token authentication

Licensed under CC BY-NC-SA 4.0