How to Set Up an OpenClaw SSH Tunnel for Remote Gateway Access
OpenClaw runs over 500,000 gateway instances across 82 countries, and a large share of those gateways sit on remote servers that operators need to reach from a laptop or desktop. An SSH tunnel forwards the gateway's WebSocket port from that remote machine to localhost, so OpenClaw.app connects as if the gateway were running locally.
What an OpenClaw SSH Tunnel Does
OpenClaw hit 500,000 running instances across 82 countries by April 2026, according to OpenClawVPS.io's ecosystem report. A significant portion of those gateways run on VPS hosts, home servers, or office machines that operators access from a different network. The SSH tunnel bridges that gap.
The OpenClaw gateway listens on a default WebSocket port, serving connections that the CLI and desktop app use for health checks and status commands. When the gateway runs on a remote machine, your local client can't reach that port directly. An SSH tunnel creates a secure, encrypted path: your local machine forwards traffic to the remote host's gateway port through an SSH connection.
Once the tunnel is active, every local tool that connects to the gateway's WebSocket endpoint on localhost reaches the remote gateway transparently. No code changes, no firewall rules, no VPN. The SSH connection handles encryption and authentication in one layer.
This architecture follows a principle the OpenClaw remote gateway docs call the safest default: keep gateway.bind set to loopback so the gateway never listens on a public interface, then use SSH or Tailscale to reach it from outside. That way the gateway port is never exposed to the open internet, even on a VPS with a public IP.
The gateway port is configurable through gateway.port, the --port flag, or the OPENCLAW_GATEWAY_PORT environment variable. If you change it on the remote machine, match that port in your SSH configuration.
How to Configure SSH and Copy Your Key
Start by setting up key-based authentication so the tunnel can connect without a password prompt. This is required for any persistent or automated connection.
Copy your public key to the remote machine:
ssh-copy-id -i ~/.ssh/id_rsa user@remote-host
Test with ssh user@remote-host to confirm you can log in without entering a password. If you use a different key file, adjust the -i path accordingly.
Next, add an SSH config entry that defines the tunnel. Edit ~/.ssh/config:
Host remote-gateway
HostName 203.0.113.42
User deploy
LocalForward 18789 127.0.0.1:18789
IdentityFile ~/.ssh/id_rsa
Replace 203.0.113.42 with your server's IP address and deploy with the SSH username. The LocalForward directive tells SSH to forward the gateway port from the remote machine's loopback interface to the same port on your local machine.
Test the tunnel manually:
ssh -N remote-gateway
The -N flag tells SSH not to execute a remote command, just hold the tunnel open. While this runs, open a second terminal and verify the connection:
openclaw status
If you see a healthy status response, the tunnel works. The gateway on the remote machine is now reachable from your local OpenClaw installation. Press Ctrl+C in the first terminal to close the tunnel when you're done testing.
For servers that restrict root login (which is good practice), create a dedicated user on the remote machine. The tunnel only needs the ability to connect via SSH; it doesn't need sudo access or a login shell.
Make the Tunnel Persistent with a LaunchAgent
A manual SSH session dies when you close the terminal or your laptop sleeps. For a gateway you rely on daily, you need the tunnel to start at boot and restart on failure.
On macOS, LaunchAgents handle this. Save the following plist file to ~/Library/LaunchAgents/ai.openclaw.ssh-tunnel.plist:
<?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>remote-gateway</string>
</array>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
The KeepAlive key tells launchd to restart SSH whenever it exits, whether from a network interruption, server reboot, or sleep/wake cycle. RunAtLoad starts the tunnel as soon as you log in.
Load it with:
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/ai.openclaw.ssh-tunnel.plist
From this point, the tunnel survives reboots and reconnects after network drops. You never need to remember to start it.
To force a restart (for example, after changing your SSH config):
launchctl kickstart -k gui/$UID/ai.openclaw.ssh-tunnel
To stop and unload the tunnel entirely:
launchctl bootout gui/$UID/ai.openclaw.ssh-tunnel
On Linux, you can achieve the same with a systemd user service or autossh. The concept is identical: run ssh -N remote-gateway as a persistent, auto-restarting process.
Persist OpenClaw agent output across remote sessions
generous storage workspace storage, no credit card. Fastio's MCP server gives OpenClaw agents persistent file access, semantic search, and ownership transfer.
Connect OpenClaw.app to the Remote Gateway
With the tunnel running, configure OpenClaw to use it. You have two paths depending on whether you prefer the CLI or the desktop app.
CLI configuration: Set the gateway mode to remote and point it at the local tunnel endpoint:
openclaw config set gateway.remote.token "your-gateway-token"
Or edit the config file directly to specify the full remote block:
{
"gateway": {
"mode": "remote",
"remote": {
"url": "ws://127.0.0.1:18789",
"token": "your-gateway-token"
}
}
}
The token authenticates your client to the remote gateway. Generate one on the server with openclaw gateway token create or use the token displayed during initial gateway setup.
Desktop app: OpenClaw.app includes a built-in Remote over SSH mode accessible through the Settings menu. This mode manages the SSH tunnel automatically, handling connection setup, transport selection, and reconnection without a separate LaunchAgent. It also supports remote status checks, WebChat forwarding, and Voice Wake forwarding through the macOS menu bar.
For most users, the app's built-in mode is the simplest path. The manual LaunchAgent approach gives you more control: you can customize SSH options, add ProxyJump for bastion hosts, or share the tunnel with other tools on your machine. Pick whichever fits your workflow. Either way, once your agents have remote access, a persistent workspace keeps their output organized and searchable across sessions.
You can also authenticate with a password instead of a token by setting gateway.remote.password, though token-based auth is the better practice for automated and persistent connections.
Tailscale as an SSH Tunnel Alternative
SSH tunnels work anywhere you have SSH access, but they add a layer of configuration that teams can avoid. Tailscale creates a WireGuard-based mesh VPN where every device gets a stable IP on your private tailnet. Once both your client machine and the gateway server are on the same tailnet, the gateway is directly reachable without any port forwarding.
The OpenClaw docs recommend keeping gateway.bind set to loopback even with Tailscale, then using Tailscale Serve to expose the Control UI to tailnet members over HTTPS. This way the gateway never binds to a public interface.
Configure OpenClaw for direct tailnet access:
{
"gateway": {
"mode": "remote",
"remote": {
"transport": "direct",
"url": "ws://100.64.0.5:18789",
"token": "your-gateway-token"
}
}
}
Replace 100.64.0.5 with the tailnet IP of your gateway machine.
When gateway.auth.allowTailscale is enabled, the gateway trusts Tailscale identity headers for the Control UI and WebSocket authentication. HTTP API calls still require a token or password, but the day-to-day app connection works without credential management.
When to choose each approach:
- SSH tunnels work from any machine with SSH access, require no additional software, and let you add ProxyJump for bastion hosts or multi-hop setups
- Tailscale simplifies multi-device access for teams, provides stable IPs that survive server reboots, and eliminates tunnel configuration entirely
- Both keep the gateway on loopback, which is the security posture the OpenClaw docs recommend
For a solo developer with one remote server, SSH tunnels are sufficient and dependency-free. For teams sharing a gateway across laptops and workstations, Tailscale reduces the coordination overhead.
Fastio fits naturally alongside either approach. Once your agents have remote gateway access, they need somewhere to persist output, share files with collaborators, and hand off completed work. A Fastio workspace gives OpenClaw agents generous storage with built-in semantic search, file versioning, and ownership transfer through the MCP server. Agents write to the workspace via the Fastio MCP tools, and humans review the output in the same browser-based interface.
How to Fix Stale Connections and Port Conflicts
SSH tunnels are reliable once configured, but a few common issues trip people up during setup and after network changes.
Check if the tunnel is running:
ps aux | grep "ssh -N remote-gateway" | grep -v grep
If no process appears, the tunnel isn't active. Check LaunchAgent status with launchctl list | grep openclaw.
Verify the port is forwarded:
lsof -i :<gateway-port>
Replace <gateway-port> with the port from your SSH config's LocalForward line. This shows which process holds that port locally. If something other than SSH occupies it (for example, a local OpenClaw gateway you forgot to stop), you'll get a bind error when the tunnel starts.
Stale connections after network changes: When your laptop switches networks or wakes from sleep, the SSH connection may hang without cleanly disconnecting. The LaunchAgent's KeepAlive directive handles this by restarting SSH, but sometimes the old process lingers. Force a clean restart:
launchctl kickstart -k gui/$UID/ai.openclaw.ssh-tunnel
Gateway unreachable despite active tunnel: Confirm the remote gateway is actually running. SSH into the server directly and check:
ssh remote-gateway
Once connected, check whether the gateway process is running. If it stopped, restart it on the server. The tunnel can only forward traffic to a listening process.
Port mismatch: If you changed the gateway port on the remote machine, update the LocalForward line in ~/.ssh/config to match. Both sides of the forward need to agree on the port number.
SSH key issues: If ssh-copy-id didn't work (some servers disable password auth entirely), manually append your public key to ~/.ssh/authorized_keys on the remote machine. Verify file permissions: the .ssh directory should be 700 and authorized_keys should be 600.
Frequently Asked Questions
How do I connect to a remote OpenClaw gateway?
Add a LocalForward entry in your SSH config that maps the remote gateway's default port to the same port on localhost, then run the tunnel with "ssh -N remote-gateway". OpenClaw.app also has a built-in Remote over SSH mode in Settings that manages the tunnel automatically.
How do I keep an OpenClaw SSH tunnel running permanently?
On macOS, create a LaunchAgent plist at ~/Library/LaunchAgents/ai.openclaw.ssh-tunnel.plist with KeepAlive and RunAtLoad enabled. Load it with launchctl bootstrap, and the tunnel starts at login and restarts on failure. On Linux, use a systemd user service or autossh.
Can I use Tailscale instead of SSH for OpenClaw remote access?
Yes. Tailscale creates a WireGuard mesh VPN that gives both machines stable IPs on the same network. Set the gateway config to direct transport mode with the tailnet IP. Tailscale is the better option for teams accessing a shared gateway from multiple devices.
What port does the OpenClaw gateway use?
The gateway uses a default WebSocket port documented in the official remote gateway guide at docs.openclaw.ai/gateway/remote. You can change it through the gateway.port config key, the --port CLI flag, or the OPENCLAW_GATEWAY_PORT environment variable. Match the port in your SSH LocalForward directive if you change it.
How do I check if my OpenClaw SSH tunnel is active?
Run "lsof -i" filtered to the gateway port to see if SSH holds the local forward. You can also run a gateway status command through the CLI, which connects through the tunnel and returns the gateway's health. If the command succeeds, the tunnel is working.
Related Resources
Persist OpenClaw agent output across remote sessions
generous storage workspace storage, no credit card. Fastio's MCP server gives OpenClaw agents persistent file access, semantic search, and ownership transfer.