diff --git a/docker-compose.yml b/docker-compose.yml index 8ce610d6a..55f4640e0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,7 +22,7 @@ services: "dist/index.js", "gateway", "--bind", - "${CLAWDBOT_GATEWAY_BIND:-lan}", + "${CLAWDBOT_GATEWAY_BIND:-loopback}", "--port", "${CLAWDBOT_GATEWAY_PORT:-18789}" ] diff --git a/fly.private.toml b/fly.private.toml index 1c5e99b13..06fdf939f 100644 --- a/fly.private.toml +++ b/fly.private.toml @@ -22,7 +22,8 @@ primary_region = "iad" # change to your closest region NODE_OPTIONS = "--max-old-space-size=1536" [processes] - app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan" + # Default bind is loopback (127.0.0.1) - appropriate for private deployment. + app = "node dist/index.js gateway --allow-unconfigured --port 3000" # NOTE: No [http_service] block = no public ingress allocated. # The gateway will only be accessible via: diff --git a/fly.toml b/fly.toml index fc19990fd..8793710cc 100644 --- a/fly.toml +++ b/fly.toml @@ -15,7 +15,9 @@ primary_region = "iad" # change to your closest region NODE_OPTIONS = "--max-old-space-size=1536" [processes] - app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan" + # Default bind is loopback (127.0.0.1). For public access, add: --bind lan --token YOUR_SECRET + # WARNING: Using --bind lan exposes your gateway to internet scanners (Shodan). + app = "node dist/index.js gateway --allow-unconfigured --port 3000" [http_service] internal_port = 3000 diff --git a/src/cli/gateway-cli/run.ts b/src/cli/gateway-cli/run.ts index cb26aa98d..ba08a27c8 100644 --- a/src/cli/gateway-cli/run.ts +++ b/src/cli/gateway-cli/run.ts @@ -256,6 +256,17 @@ async function runGatewayCommand(opts: GatewayRunOpts) { return; } + // Warn when binding to non-loopback even with auth + if (bind !== "loopback" && hasSharedSecret) { + gatewayLog.warn( + [ + `Gateway binding to ${bind} (network-accessible).`, + "Ensure this is intentional. The gateway may be discoverable via internet scanners.", + "For local-only access, use --bind loopback or omit the --bind flag.", + ].join("\n"), + ); + } + try { await runGatewayLoop({ runtime: defaultRuntime, diff --git a/src/commands/doctor-security.ts b/src/commands/doctor-security.ts index 856b18bfb..a22073e3f 100644 --- a/src/commands/doctor-security.ts +++ b/src/commands/doctor-security.ts @@ -60,6 +60,7 @@ export async function noteSecurityWarnings(cfg: MoltbotConfig) { warnings.push( `- CRITICAL: Gateway bound to ${bindDescriptor} without authentication.`, ` Anyone on your network (or internet if port-forwarded) can fully control your agent.`, + ` Your gateway is discoverable via internet scanners (Shodan, Censys).`, ` Fix: ${formatCliCommand("moltbot config set gateway.bind loopback")}`, ...authFixLines, ); @@ -67,6 +68,7 @@ export async function noteSecurityWarnings(cfg: MoltbotConfig) { // Auth is configured, but still warn about network exposure warnings.push( `- WARNING: Gateway bound to ${bindDescriptor} (network-accessible).`, + ` The gateway may be discoverable via internet scanners (Shodan, Censys).`, ` Ensure your auth credentials are strong and not exposed.`, ); }