● Node.js · In-process firewall

Stop bots, scrapers, and zero-day probes. Keep the traffic that matters.

A firewall for Node.js apps, included in SecureNow. Blocks known-bad IPs — bots, scanners, credential stuffers, vulnerability probes — from a feed refreshed hourly. Your own blocks and rate limits apply in about 10 seconds. Runs inside your app — no Cloudflare account, no AWS WAF, no load balancer rules, no network reconfiguration. One flag on your start command.

14 days. No credit card. Every feature. Then $99 per app per month.

Known-bad IPs blockedHourly refreshYour blocks live in ~10sSub-ms overheadFails open
The problem

Running a Node.js app in 2026 means fighting bots every day.

Scrapers rack up your bandwidth bill. Zero-day scanners probe for CVEs hours after they drop. Credential stuffers hammer your login. And the usual fix — a heavy-handed WAF — often takes out Googlebot and GPTBot along with the attackers, tanking your SEO and AI visibility.

🧑‍💻
@apidev
2d ago

“Woke up to a $3,400 egress bill. Turns out someone was scraping our API endpoints for 72 hours straight. Cloudflare didn't catch it because they rotated IPs every 2 minutes.”

Scraping costs
🚀
@indiefounder
5d ago

“Got probed for a CVE that dropped 6 hours ago. My app isn't even vulnerable, but the logs are now 90% attack noise. How are small teams supposed to keep up?”

Zero-day bots
🛠️
@devopsgal
1w ago

“Enabled a WAF and lost 40% of my Google traffic overnight. Turns out it was blocking Googlebot and GPTBot as 'bots'. AI crawlers are how people find us now.”

WAF tanked SEO
⚙️
@backend_eng
3d ago

“Spent the weekend writing a custom IP blocker after credential-stuffing attacks hit our login 400k times. I shouldn't have to build a bot filter from scratch in 2026.”

Credential stuffing
📉
@scrapedtodeath
6h ago

“LLM scrapers are pounding our docs at 200 req/sec with no throttle, no robots.txt respect. We pay the bandwidth, they train on our content. There has to be a middle ground.”

Rogue LLM scrapers
🏢
@saas_cto
4d ago

“Vulnerability scanners are 70% of our 4xx traffic. Our error dashboards are useless — real customer issues are drowning in /wp-admin and /.env probes.”

Scanner noise

Illustrative — based on common community complaints.

How it works

A preload. A blocklist. An allowlist. That's it.

1

Node preload, zero code change

Add one flag to your start command: node -r securenow/firewall-only app.js. Node loads the firewall module before your app — no imports, no middleware, no refactor.

2

Blocklist pulled & cached locally

On startup the firewall pulls the known-bad IP feed from the SecureNow API, then caches it in memory for O(1) lookups. A background worker checks for changes every ~10 seconds and re-syncs the full list hourly — your app never blocks on a network call.

3

Bad IPs rejected before your handlers run

A tiny hook on Node's HTTP layer checks the client IP against the blocklist. Matches are rejected with 403 in microseconds. Everyone else passes through untouched.

4

Fails open — never your downtime

If the blocklist fetch ever fails (network, DNS, our CDN), the firewall logs a warning and stops filtering. Your app keeps serving traffic normally. Protection is additive — it can never take you down.

Three levels

Three levels of protection. All on your box.

Every level runs inside your app or on the same host. No Cloudflare account. No AWS WAF setup. No load balancer rules. No ops ticket. No network reconfiguration. One runtime config setting flips each extra layer on, or let the universal SecureNow prompt do it for you.

1
Level 1

HTTP 403

Sub-ms per request

Default · app-level · zero config

When to use

The default. Start your app with the firewall preload and this is already running.

How it blocks

A tiny hook on Node's HTTP server intercepts requests from blocked IPs and responds with 403 before any of your handlers, middleware, or framework routing runs.

  • Pure app-level — no OS privileges, no root, no CAP_NET_ADMIN
  • Runs inside your Node process, so it works on a bare VPS, Docker, Kubernetes, Fly.io, Render, Railway and Heroku (hosts without file mounts read credentials from SECURENOW_CREDENTIALS)
  • Zero configuration outside your app — no Cloudflare account, no AWS WAF, no load balancer rules
Config(always on)
2
Level 2

TCP Drop

Microseconds — no HTTP parse

Opt-in · app-level · deeper

When to use

When you want to skip HTTP parsing entirely for blocked IPs — ideal for high-traffic APIs getting hammered by scrapers.

How it blocks

Destroys the TCP socket as soon as a connection from a blocked IP is accepted, before any HTTP is parsed: zero bytes sent back, and your app never sees the request. Applies your global IP/CIDR blocks; route-scoped rules and rate limits stay at Level 1. It sees the connection's source address, so it helps when clients connect to your Node process directly, not through a proxy or load balancer (Level 1 handles those). Use securenow 8.25.0+.

  • Still runs entirely inside your Node process — no OS-level setup
  • Attackers see a hard connection reset, not a 403 — less feedback for scanners
  • Reduces TLS / HTTP parse overhead under bot storms
Configconfig.firewall.tcp: true
3
Level 3

OS Firewall (iptables / nftables)

Kernel-path — effectively free

Opt-in · kernel-level · Linux

When to use

Maximum-depth protection when you're running on Linux and can grant root / CAP_NET_ADMIN to your app.

How it blocks

Manages a dedicated SECURENOW_BLOCK chain in iptables (ip6tables for IPv6), or a securenow nft table where iptables is missing (8.25.0+). Packets from blocked IPs are DROPPED at the kernel — they never reach user space, let alone your Node process. Applies your global IP/CIDR blocks; route-scoped rules and rate limits stay at Level 1. Like Level 2 it acts on the connection's source address, so it protects direct client connections. Use securenow 8.25.0+.

  • Still runs on the same box as your app — no external service, no network reconfiguration
  • Falls back to nftables where iptables is missing (8.25.0+)
  • Works alongside Layer 1 and Layer 2 — they stack
Configconfig.firewall.iptables: true
🧠

Don't want to pick? The AI prompt handles it.

The onboarding wizard generates a Cursor / Claude prompt that asks what environment you run in (a PaaS like Render or Fly.io, Linux VPS with root, container, etc.) and enables the right levels automatically. You usually only touch runtime config when you want advanced TCP, kernel, or cloud WAF layers.

Benefits

Real protection, no collateral damage.

Six reasons teams turn the firewall on first — often before they wire up tracing at all.

🛡️

Known-bad IPs, refreshed hourly

Active bots, scanners, credential stuffers, and zero-day vulnerability probes — pooled from attack telemetry across the SecureNow network and curated open-source feeds.

🕐

Refreshed hourly

New threats are ingested, deduplicated, and pushed to your firewall within ~60 minutes of first being observed in the wild.

💸

Bandwidth & infra savings

Known-bad scrapers and bot swarms are rejected before they reach your handlers. Lower CDN bills, less CPU, smaller egress — often the firewall pays for itself.

🤖

You decide who's trusted

There's no built-in crawler allowlist. The firewall blocks IPs on the known-bad feed and your own lists. Add the crawler, monitor, or partner IPs you rely on with securenow trusted add and they stay off the blocklist.

⚡

Zero tracing, zero overhead

No OTel, no traces, no logs, no request-body capture. Just the IP blocklist preloaded as a Node hook — sub-millisecond check per request, fails open if ever unreachable.

🔌

No SDK plugging

You don't wire anything into your app code. One flag on your start command and you're protected — works with Express, Next.js, NestJS, Fastify, Nuxt 3, Koa, Hono, Hapi, h3, and more.

🤖

No built-in crawler allowlist. You decide who's trusted.

The firewall blocks IPs on the known-bad feed and your own blocklist. It doesn't ship a list of Googlebot, GPTBot, or ClaudeBot ranges, so if an IP you rely on — a crawler, an uptime monitor, a partner — ever lands on a list, check it and mark it trusted. Trusted IPs stay off the blocklist your app syncs.

securenow firewall test-ip <ip>securenow trusted add <ip>securenow trusted
Install

Two minutes, three commands.

Pick your framework, copy the snippet, start your app. The blocklist loads on startup — you're protected before the first request hits your handlers.

1Install the package
Terminal
npm install --save securenow@latest
npx securenow version
2Connect runtime credentials - the app and runtime API key are created and saved for you
Terminal
npx securenow login
npx securenow app connect
npx securenow firewall status

Browser opens, then you pick or create an app. SecureNow connects the firewall by default. The runtime API key lands in .securenow/runtime.json (auto-gitignored). It authenticates telemetry ingestion and firewall sync. No env var needed.

Already have a runtime API key? npx securenow api-key set snk_live_...

3Preload the firewall in your start command
package.json
"start": "node -r securenow/firewall-only app.js"

Or skip package.json and run directly: node -r securenow/firewall-only app.js

Start your app and watch for [securenow] Firewall: synced N global blocked IPs— that line means the blocklist is live.
Prefer AI setup? Start free trial — the onboarding wizard generates a ready-to-paste Cursor / Claude prompt that wires everything up for you.
CLI

Block an IP. Check the firewall. From your terminal.

Everything the firewall does is scriptable. Use it in CI, cron jobs, incident response playbooks, or straight from your shell.

securenow run --firewall-only app.js

Start your app with the firewall preloaded — no tracing, no OTel, just the blocklist.

securenow firewall status

Show whether the firewall is active, how many IPs are loaded, and when the blocklist was last refreshed.

securenow firewall test-ip 203.0.113.42

Check whether a specific IP would be blocked by the current blocklist — without actually sending a request.

securenow blocklist

List every IP currently in your personal blocklist (added on top of the global feed).

securenow blocklist add 198.51.100.7 --reason "brute-forced login"

Manually block an IP. Your running apps pick it up in about 10 seconds.

securenow blocklist add 203.0.113.0/24 --route /api/auth/register --mode exact --method POST --env production --duration 24h

Block a range on one route and method only, in one environment, for a day. Every other page keeps working for those addresses.

securenow ratelimit from-text "rate limit POST /api/auth/login to 5 attempts per minute per IP" --yes

Add a rate limit in plain English. Count per IP, per session cookie, per API key header, or globally.

securenow firewall hits --since 1h

See what every block and rate limit actually stopped, per rule and per IP.

securenow blocklist unblock <id> --reason "reviewed safe"

Stop enforcing a block while preserving the block report, history, and audit trail.

securenow trusted add 192.0.2.10 --label "office VPN"

Trust known-safe office, CI, monitor, or VPN traffic without enabling restrictive deny-by-default allowlist mode.

securenow trusted

List your trusted IPs. Trusted IPs are left out of the blocklist your app syncs.

Guides

Configuration

Every knob, every default.

The firewall is driven by runtime credentials, not hand-managed env vars. Since v8, npx securenow login links the app, enables its firewall by default, and saves the runtime API key in .securenow/runtime.json. Firewall settings live under config.firewall in that same file (the SDK doesn't read SECURENOW_FIREWALL_* env vars), so nothing below is strictly required. In practice the universal SecureNow onboarding prompt sets these for you based on your environment - this table is only here if you want to read what each setting does or tune it by hand.

SettingDefaultDescription
apiKey.securenow/runtime.jsonScoped snk_live_ runtime API key. Since v8, `npx securenow login` or `npx securenow app connect` links the selected app, enables its firewall by default, and saves this key to .securenow/runtime.json. The same key authenticates telemetry ingestion and firewall sync.
config.firewall.apiUrlhttps://api.securenow.aiAPI endpoint the firewall syncs against. Override only for self-hosted / enterprise instances.
config.firewall.tcpfalseSet to true to enable Level 2 (TCP socket drop). Still app-level — no OS privileges required.
config.firewall.iptablesfalseSet to true to enable Level 3 (kernel iptables / nftables). Linux only — needs root or CAP_NET_ADMIN.
config.firewall.cloudnullOptional cloud WAF sync: 'cloudflare', 'aws', or 'gcp'. Pushes your global IP/CIDR blocks to that provider.
config.networking.trustedProxies[]Behind Cloudflare, a CDN or a load balancer with a public address, list it here so the firewall sees the visitor's IP instead of the proxy's: exact IPs, IPv4 or IPv6 CIDRs (IPv6 ranges 8.25.0+), or "cloudflare" for Cloudflare's edge ranges. Private and loopback proxies are trusted by default; clients can't pick their IP through X-Forwarded-For.
config.firewall.rateLimitStorenullA redis:// or rediss:// URL so PM2 cluster workers or several servers share rate-limit counters. Unset = each process counts on its own.
config.firewall.failModeopenWhat to do if the blocklist fetch fails. open = let traffic through (no downtime); closed = reject everything until recovery.
config.firewall.statusCode403HTTP status code returned for Layer 1 blocks. 403 Forbidden by default; some prefer 444 or 429.
config.firewall.versionCheckInterval10Seconds between lightweight version checks. This is why a new block or rate limit applies in about 10 seconds.
config.firewall.syncInterval3600Seconds between safety-net full blocklist re-syncs (hourly by default).
config.firewall.logtrueSet to false to silence the firewall's startup / status / block log lines.
SECURENOW_CREDENTIALS—One of the two environment variables the SDK reads. The runtime credentials JSON (raw or base64) for hosts that cannot mount a file, such as Railway, Render, Heroku or Fly.io. Print it with `npx securenow credentials runtime --env production --format env`. Takes precedence over credential files.
SECURENOW_DISABLED—The other environment variable the SDK reads. Set to 1 to turn SecureNow, firewall included, off for one process (for example in test runs).
✨

You shouldn't need to read this table.

Run npx securenow login, then paste the universal SecureNow setup prompt into Codex, Claude Code, Cursor, or Windsurf. It detects your framework, keeps runtime secrets in .securenow/runtime.json, updates the right files, and verifies the firewall, logs, traces, and body capture.

Same subscription

Want to know what those blocked requests were doing?

Your SecureNow subscription also includes full production security: see the user, route, and session behind every request — not just the IP — and let your coding agent investigate production directly from Claude Code, Codex, or Cursor. One preload switch moves firewall-only mode into full SecureNow. Same account. Same blocklist. Same price.

Questions teams ask before dropping it in.

How much does the firewall cost?
The firewall is part of SecureNow's one plan: $99 per app per month, every feature included. The same subscription covers the hourly blocklist, the securenow/firewall-only preload, full OTel tracing, logs, body capture, and AI-powered forensics. Every account starts with a 14-day free trial — every app, every feature, no credit card. There is no free tier: after the trial, the firewall pauses with everything else until you subscribe.
How is this different from Cloudflare / a WAF?
Cloudflare-class WAFs run at the edge and charge per request. SecureNow runs inside your Node process and has no per-request charges — it's part of the flat per-app price. Works even on bare VPS / Fly.io / Render where you have no edge WAF.
Does the firewall slow down my app?
Per-request overhead is sub-millisecond — a single in-memory set lookup against the cached blocklist. There is zero OTel / tracing overhead in firewall-only mode (we skip the OTel SDK entirely). For latency-sensitive services, firewall-only is the recommended entry point.
What frameworks are supported?
Any Node.js HTTP server: Express, Next.js, NestJS, Fastify, Nuxt 3, Koa, Hono, Hapi, h3, Polka, Micro, Feathers, and raw http.createServer. For Next.js / Nuxt, use NODE_OPTIONS='-r securenow/firewall-only' next start (or equivalent).
Will the firewall block Googlebot or AI crawlers?
The firewall blocks IPs on the known-bad feed and your own blocklist; it has no rule that targets crawlers as such. It also has no built-in crawler allowlist, so a crawler can be blocked if its IP lands on a list or it trips a rate limit you set. Check an IP with securenow firewall test-ip, and add the crawler, monitor, or partner IPs you rely on with securenow trusted add — trusted IPs are kept off the blocklist your app syncs.
Can I add my own blocked / allowed IPs?
Yes - the firewall includes a personal blocklist and scoped trusted entries. Manage them with securenow blocklist add / securenow trusted add, or from the dashboard. Your personal lists layer on top of the global feed.
What else does the subscription include?
The firewall tells you an IP was blocked. The rest of SecureNow — same subscription, same price — tells you what it was doing: the user, route, and session behind every request, full traces and logs, attack detection, and AI investigations you can run from Claude Code, Codex, or Cursor — ask who attacked your login and get the IPs, targeted accounts, and evidence in seconds. See pricing for details.

Block the bots. Keep the signal.

Known-bad IPs, refreshed hourly. Your own blocks live in about 10 seconds. 14 days free, then $99 per app per month.