I've set up OpenClaw on EC2 multiple times now — for myself and for clients. And every single time I take over someone else's setup, I find the same thing: port 18789 wide open to the internet, no SSL, no reverse proxy, running as root.
Bitsight found over 30,000 exposed OpenClaw instances. Attackers aren't even bothering with prompt injection — they're connecting directly to the gateway WebSocket and getting full access.
This is how I deploy OpenClaw properly. Gateway on loopback, Nginx in front, SSL via Let's Encrypt, and EC2 security groups that only allow what's necessary. Takes about 30 minutes.
Why 0.0.0.0 Binding Will Get You Hacked
When you run through OpenClaw's onboarding wizard, it asks you about the gateway bind mode. A lot of people pick "LAN" because they want to access the dashboard from their browser. That binds the gateway to 0.0.0.0 — meaning every network interface on the machine.
On an EC2 instance, that means anyone on the internet can hit port 18789 directly. Your gateway is now a public endpoint. Even with token auth enabled, you're one misconfiguration away from someone controlling your AI agent, reading your sessions, and executing commands on your server.
The OpenClaw docs are clear about this: never expose the gateway unauthenticated on 0.0.0.0.
Here's what we're going to do instead:
Internet → Port 443 (HTTPS) → Nginx → 127.0.0.1:18789 → OpenClaw Gateway
The gateway only talks to localhost. Nginx handles SSL termination and proxies requests. Nothing else is exposed.
Prerequisites
- An AWS EC2 instance running Ubuntu 24.04 (t3.medium or bigger — OpenClaw needs at least 4GB RAM for comfortable operation)
- A domain name pointed to your EC2 instance's public IP (I'll use
openclaw.yourdomain.comas an example) - SSH access to your instance
- An API key from your LLM provider (Anthropic, OpenAI, Gemini, etc.)
Step 1: Install OpenClaw
SSH into your EC2 instance and install OpenClaw:
# Make sure Node 22+ is installed
node --version
# Install OpenClaw
curl -fsSL https://openclaw.ai/install.sh | bash
# Run the onboarding wizard
openclaw onboard --install-daemon
During onboarding, when it asks about the gateway bind mode, pick loopback. This is critical. It binds the gateway to 127.0.0.1 only.
If you've already set up OpenClaw with a different bind mode, fix it:
openclaw config set gateway.bind loopback
Verify it's running:
openclaw gateway status
You should see the gateway running on 127.0.0.1:18789. If you try to access http://your-ec2-ip:18789 from your browser right now, it should refuse the connection. That's exactly what we want.
Step 2: Set Up Gateway Authentication
Even though we're binding to loopback, set up token auth. Defense in depth:
# Generate a strong random token
TOKEN=$(openssl rand -hex 32)
echo "Your gateway token: $TOKEN"
echo "Save this somewhere safe."
# Set the token
openclaw config set gateway.auth.mode token
openclaw config set gateway.auth.token "$TOKEN"
Also configure trusted proxies so OpenClaw correctly reads the real client IP from Nginx:
openclaw config set gateway.trustedProxies '["127.0.0.1"]'
Without this, OpenClaw sees Nginx's IP for every request instead of the actual client IP. That breaks rate limiting and IP-based access controls.
Restart the gateway to apply changes:
sudo systemctl restart openclaw
Step 3: Install and Configure Nginx
sudo apt update
sudo apt install -y nginx
Create the Nginx config for OpenClaw:
sudo nano /etc/nginx/sites-available/openclaw
Paste this:
upstream openclaw_gateway {
server 127.0.0.1:18789;
}
server {
listen 80;
server_name openclaw.yourdomain.com;
# Redirect all HTTP to HTTPS (we'll set up SSL next)
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name openclaw.yourdomain.com;
# SSL certs will be added by Certbot in the next step
# ssl_certificate /etc/letsencrypt/live/openclaw.yourdomain.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/openclaw.yourdomain.com/privkey.pem;
location / {
proxy_pass http://openclaw_gateway;
proxy_http_version 1.1;
# WebSocket support — required for OpenClaw dashboard
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Pass real client IP to OpenClaw
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
# Longer timeouts for WebSocket connections
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
}
Replace openclaw.yourdomain.com with your actual domain.
Enable the site and test the config:
sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default # Remove default site
sudo nginx -t
sudo systemctl reload nginx
If nginx -t shows errors, fix them before moving on. Don't skip this.
Step 4: SSL with Let's Encrypt
Install Certbot and get your certificate:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d openclaw.yourdomain.com
Certbot will ask for your email, agree to terms, and then automatically modify your Nginx config to add the SSL certificate paths. It also sets up auto-renewal.
Verify auto-renewal works:
sudo certbot renew --dry-run
Now uncomment the SSL lines in your Nginx config (Certbot usually does this automatically, but double-check):
sudo nginx -t
sudo systemctl reload nginx
Test it: open https://openclaw.yourdomain.com in your browser. You should see the OpenClaw Control UI with a valid SSL certificate and no browser warnings.
Step 5: Configure OpenClaw for the Reverse Proxy
Since we're accessing the Control UI through a domain now (not localhost), OpenClaw needs to know about the allowed origin:
openclaw config set gateway.controlUi.allowedOrigins '["https://openclaw.yourdomain.com"]'
Watch out for a known gotcha: if you see an error about controlUI (capital UI), ignore that — the correct config key uses lowercase controlUi. This is a known bug in the error message as of version 2026.2.24.
Restart the gateway:
sudo systemctl restart openclaw
Step 6: systemd Service with Auto-Restart
If you used openclaw onboard --install-daemon, systemd should already be configured. But let's make sure it's set up properly for production:
sudo nano /etc/systemd/system/openclaw.service
It should look something like this:
[Unit]
Description=OpenClaw Gateway
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=ubuntu
Environment=NODE_ENV=production
ExecStart=/usr/local/bin/openclaw gateway --port 18789
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Key settings:
- Restart=always — if it crashes, systemd brings it back
- RestartSec=10 — waits 10 seconds before restart (avoids crash loops)
- User=ubuntu — don't run as root
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable openclaw
sudo systemctl start openclaw
Verify it's running:
sudo systemctl status openclaw
journalctl -u openclaw -f # Live logs
After a server reboot, OpenClaw will start automatically. Test this by running sudo reboot and checking after the instance comes back up.
Step 7: Lock Down EC2 Security Groups
Go to your AWS Console → EC2 → Security Groups → select the group attached to your instance.
Set inbound rules to:
| Port | Protocol | Source | Why |
|---|---|---|---|
| 22 | TCP | Your IP only | SSH access |
| 80 | TCP | 0.0.0.0/0 | HTTP → redirects to HTTPS |
| 443 | TCP | 0.0.0.0/0 | HTTPS (Nginx + SSL) |
That's it. Three ports. Everything else is blocked.
Specifically, make sure port 18789 is NOT in your security group rules. There's zero reason for it to be accessible from the internet since Nginx proxies everything through 443.
If you want to be extra careful with SSH, restrict port 22 to only your IP address instead of 0.0.0.0/0. You can find your IP at whatismyip.com.
Final Checklist
Run through this before you call it done:
- [ ]
openclaw gateway statusshows running on 127.0.0.1:18789 - [ ]
curl http://localhost:18789from the server returns a response - [ ]
curl http://YOUR_EC2_PUBLIC_IP:18789from your laptop returns connection refused - [ ]
https://openclaw.yourdomain.comloads the dashboard with valid SSL - [ ] WebSocket connection works (dashboard is interactive, not just static)
- [ ]
sudo systemctl status openclawshows active - [ ]
sudo reboot→ wait → OpenClaw comes back automatically - [ ] EC2 security group only has ports 22, 80, 443
- [ ]
openclaw security auditruns clean (or with only expected warnings)
What This Setup Looks Like
Internet
│
▼
┌──────────────────────┐
│ EC2 Security Group │
│ Only 22, 80, 443 │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Nginx (:443) │
│ SSL termination │
│ WebSocket proxy │
└──────────┬───────────┘
│ proxy_pass
▼
┌──────────────────────┐
│ OpenClaw Gateway │
│ 127.0.0.1:18789 │
│ Token auth enabled │
└──────────────────────┘
No exposed ports. SSL everywhere. Auto-restart on crash or reboot. Gateway only talks to localhost.
This is the same setup I run for myself and deploy for clients. Nothing fancy, just proper infrastructure that doesn't leave your AI agent exposed to the internet.
Need Help Setting This Up?
I deploy and maintain OpenClaw professionally — AWS, Docker, Nginx, Telegram, WhatsApp, multi-agent, the works.
150+ projects delivered. 100% job success rate. Top Rated Plus on Upwork.
→ Hire me on Upwork
→ Email: chaudhryasim5@gmail.com
Top comments (0)