DEV Community

Asim Hayat
Asim Hayat

Posted on

Stop Exposing Port 18789: How I Secure OpenClaw on AWS EC2 with Nginx and SSL

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
Enter fullscreen mode Exit fullscreen mode

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.com as 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Verify it's running:

openclaw gateway status
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

Also configure trusted proxies so OpenClaw correctly reads the real client IP from Nginx:

openclaw config set gateway.trustedProxies '["127.0.0.1"]'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Step 3: Install and Configure Nginx

sudo apt update
sudo apt install -y nginx
Enter fullscreen mode Exit fullscreen mode

Create the Nginx config for OpenClaw:

sudo nano /etc/nginx/sites-available/openclaw
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Now uncomment the SSL lines in your Nginx config (Certbot usually does this automatically, but double-check):

sudo nginx -t
sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

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"]'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Verify it's running:

sudo systemctl status openclaw
journalctl -u openclaw -f  # Live logs
Enter fullscreen mode Exit fullscreen mode

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 status shows running on 127.0.0.1:18789
  • [ ] curl http://localhost:18789 from the server returns a response
  • [ ] curl http://YOUR_EC2_PUBLIC_IP:18789 from your laptop returns connection refused
  • [ ] https://openclaw.yourdomain.com loads the dashboard with valid SSL
  • [ ] WebSocket connection works (dashboard is interactive, not just static)
  • [ ] sudo systemctl status openclaw shows active
  • [ ] sudo reboot → wait → OpenClaw comes back automatically
  • [ ] EC2 security group only has ports 22, 80, 443
  • [ ] openclaw security audit runs 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  │
└──────────────────────┘
Enter fullscreen mode Exit fullscreen mode

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)