How Do I Secure OpenClaw Gateway Port 18789? (Complete Protection Guide)
I wanted to access my OpenClaw Gateway from my laptop while sitting at a coffee shop. Simple enough, right? Just forward port 18789 through my router and connect remotely.
Wrong. That decision would have given anyone on the internet full access to all my agents, sessions, and workspace files.
Let me show you what I learned about securing OpenClaw Gateway’s WebSocket API, and why the “easy” solution is actually the most dangerous one.
The Problem: Gateway Is the Crown Jewel
When I first started with OpenClaw, I treated it like any other service running on my machine. I figured, “It’s just a local tool, what’s the risk?”
Then I read the documentation more carefully:
Gateway is the core. Every message in, every response out, every tool call flows through it.
That’s when it clicked. Gateway isn’t just another component—it’s the central hub that controls everything:
┌─────────────────────────────────────────────────────────┐│ OpenClaw System ││ ││ ┌─────────┐ ┌─────────┐ ┌─────────┐ ││ │ Agent 1 │ │ Agent 2 │ │ Agent 3 │ ││ └────┬────┘ └────┬────┘ └────┬────┘ ││ │ │ │ ││ └──────────────┼──────────────┘ ││ │ ││ ┌──────▼──────┐ ││ │ GATEWAY │◄── Port 18789 ││ │ (WebSocket)│ WebSocket API ││ └──────┬──────┘ ││ │ ││ ┌──────────────┼──────────────┐ ││ │ │ │ ││ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ││ │Sessions │ │Workspace│ │ Tools │ ││ │ Files │ │ Files │ │ │ ││ └─────────┘ └─────────┘ └─────────┘ ││ │└─────────────────────────────────────────────────────────┘Gateway runs a WebSocket API on port 18789. This API lets you connect your own interface or external integrations. But here’s the scary part: anyone with access to port 18789 has full control over your entire OpenClaw system.
My First (Terrible) Idea: Port Forwarding
I’ll be honest—my first instinct was to just forward the port through my router:
# What I THOUGHT about doing (DON'T DO THIS)# Router config: Forward external port 18789 → internal IP:18789Then I could connect from anywhere:
// What I imagined would workconst ws = new WebSocket('ws://my-home-ip:18789');This is exactly what the OpenClaw documentation warns against as one of the “Five Mistakes”:
Port 18789 exposed to the internet. Full access to all agents, sessions, and workspace files for anyone who finds it.
Think about what that means:
- All your agent conversations—exposed
- All your session data—exposed
- All your workspace files—exposed
- Anyone who finds your port can control your agents
A simple port scanner would find it within hours. Maybe minutes.
The Right Way: Two Secure Options
OpenClaw’s documentation is clear about the solution:
By default Gateway only listens on localhost. For remote access: VPN via Tailscale or an SSH tunnel. Exposing 18789 to the open internet means full access to all your data, sessions, and agents.
Let me walk you through both approaches.
Option 1: Tailscale VPN (Zero Configuration)
Tailscale creates a secure mesh network between your devices. It’s like having a private internet just for your machines.
Step 1: Install Tailscale
On your server (where OpenClaw Gateway runs):
# Ubuntu/Debiancurl -fsSL https://tailscale.com/install.sh | sh
# Start and authenticatesudo tailscale upOn your laptop:
# Same installation processcurl -fsSL https://tailscale.com/install.sh | shsudo tailscale upStep 2: Get Your Tailscale IP
tailscale ip# Output: 100.x.y.z (your Tailscale IP)Step 3: Configure Gateway to Listen on Tailscale Interface
By default, Gateway only listens on localhost. You need to bind it to your Tailscale IP:
# In your OpenClaw Gateway configurationserver: host: "100.x.y.z" # Your Tailscale IP port: 18789Or set it via environment variable:
export OPENCLAW_GATEWAY_HOST="100.x.y.z"Step 4: Connect from Your Laptop
Now, from your laptop (which is also on Tailscale):
// Use your server's Tailscale IPconst ws = new WebSocket('ws://100.x.y.z:18789');
ws.onopen = () => { console.log('Connected securely via Tailscale!');};Why This Works
┌──────────────────┐ ┌──────────────────┐│ Your Laptop │ │ Your Server ││ │ │ ││ ┌────────────┐ │ Tailscale │ ┌────────────┐ ││ │ Client │ │ Mesh VPN │ │ Gateway │ ││ │ │◄─┼────────────────────┼─►│ :18789 │ ││ └────────────┘ │ Encrypted │ └────────────┘ ││ │ Private │ ││ Tailscale IP: │ Network │ Tailscale IP: ││ 100.a.b.c │ │ 100.x.y.z │└──────────────────┘ └──────────────────┘ │ │ │ │ ▼ ▼ Internet (blocked) Internet (blocked) Port 18789 NOT exposed Port 18789 NOT exposedThe beauty of Tailscale:
- No port forwarding needed
- No firewall configuration
- End-to-end encryption
- Works behind NAT
- Zero configuration after initial setup
Option 2: SSH Tunnel (More Control)
If you prefer more control or can’t use Tailscale, SSH tunneling is the classic approach.
Step 1: Create the Tunnel
From your laptop:
# Basic tunnelssh -L 18789:localhost:18789 user@your-server-ip -N
# Or with key filessh -L 18789:localhost:18789 -i ~/.ssh/your-key user@your-server-ip -N
# Or in backgroundssh -L 18789:localhost:18789 user@your-server-ip -N -fThe -L flag creates local port forwarding:
18789= local port on your laptoplocalhost:18789= destination from the server’s perspective-N= don’t execute remote command (just forwarding)-f= run in background
Step 2: Connect Through the Tunnel
Now connect to localhost on your laptop:
// The tunnel forwards localhost:18789 to server:18789const ws = new WebSocket('ws://localhost:18789');
ws.onopen = () => { console.log('Connected through SSH tunnel!');};How SSH Tunneling Works
┌──────────────────┐ ┌──────────────────┐│ Your Laptop │ │ Your Server ││ │ │ ││ ┌────────────┐ │ SSH Tunnel │ ┌────────────┐ ││ │ Client │ │ (Encrypted) │ │ Gateway │ ││ │ localhost: │──┼────────────────────┼──│ :18789 │ ││ │ 18789 │ │ │ └────────────┘ ││ └────────────┘ │ │ ││ │ │ Port 22 only │ ▲ ││ │ │ exposed │ │ ││ ▼ │ │ localhost:18789 ││ Local forward │ │ (not exposed) │└──────────────────┘ └──────────────────┘Benefits of SSH tunneling:
- Uses existing SSH infrastructure
- Strong encryption
- Fine-grained access control via SSH keys
- Can tunnel multiple ports
Comparison: Which Should You Choose?
| Aspect | Tailscale | SSH Tunnel |
|---|---|---|
| Setup | Very easy | Moderate |
| Persistence | Automatic | Manual (or use autossh) |
| Multiple devices | Built-in | One tunnel per connection |
| Behind NAT | Works | Requires SSH server accessible |
| Access control | Tailscale admin | SSH key management |
| Cost | Free for personal | Free |
I use Tailscale for day-to-day work because it’s seamless. SSH tunnels are my backup when I’m on a network that blocks VPN traffic.
Common Mistakes to Avoid
Mistake 1: Binding to 0.0.0.0
# DON'T DO THISserver: host: "0.0.0.0" # Listens on ALL interfaces port: 18789This exposes Gateway on every network interface, including your public IP. Even with a firewall, it’s risky.
Mistake 2: Relying on “Security Through Obscurity”
# DON'T DO THIS# "I'll use a non-standard port, no one will find it"ssh -L 58789:localhost:18789 user@serverPort scanners find non-standard ports in minutes. This is not security.
Mistake 3: No Firewall Rules
Even with Tailscale or SSH, add firewall rules as defense in depth:
# Allow Tailscale traffic onlysudo ufw allow in on tailscale0 to any port 18789
# Or for SSH, only allow from specific IPssudo ufw allow from your-ip to any port 22
# Deny everything elsesudo ufw default deny incomingsudo ufw enableTesting Your Setup
Test 1: Verify Gateway Is Not Exposed
From an external network (use your phone’s mobile data):
# Should FAIL (connection refused/timeout)nc -zv your-public-ip 18789# Ortelnet your-public-ip 18789If this connects, you’ve exposed the port. Fix it immediately.
Test 2: Verify Secure Access Works
From your laptop (on Tailscale or with SSH tunnel active):
# Should succeednc -zv localhost 18789# Or for Tailscalenc -zv 100.x.y.z 18789Test 3: WebSocket Connection Test
const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:18789'); // or Tailscale IP
ws.on('open', () => { console.log('✓ Connection successful'); ws.close();});
ws.on('error', (err) => { console.error('✗ Connection failed:', err.message);});What I Do Now
My current setup:
- Tailscale installed on all devices that need OpenClaw access
- Gateway bound to Tailscale IP only (not 0.0.0.0)
- Firewall rules as backup protection
- SSH tunnel as fallback when Tailscale is blocked
This gives me secure remote access without exposing port 18789 to the internet.
Quick Reference
# Tailscale approachtailscale up # Connect to meshtailscale ip # Get your IPexport OPENCLAW_GATEWAY_HOST="100.x.y.z" # Configure Gateway
# SSH tunnel approachssh -L 18789:localhost:18789 user@server -N -f # Create tunnel# Then connect to localhost:18789
# Verify not exposednc -zv your-public-ip 18789 # Should failThe Bottom Line
Gateway is the core of your OpenClaw system. Every message, every response, every tool call flows through it. Port 18789 gives complete control over all your agents, sessions, and workspace files.
Never expose it directly to the internet.
Use Tailscale for zero-configuration security, or SSH tunnels for more control. Both keep your Gateway accessible while preventing unauthorized access.
The five minutes it takes to set up proper security is nothing compared to the risk of exposing your entire OpenClaw system to the world.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments