Adding an IP Firewall to NestJS Without Cloudflare

NestJS sits on top of Express or Fastify. Either way, the SecureNow preload adds a 500k-IP firewall in one line — no DNS changes.

Lhoussine
May 9, 2026·5 min read

Adding an IP Firewall to NestJS Without Cloudflare

NestJS apps run on Node.js with an HTTP adapter — Express by default, Fastify if you've configured it. Either way, the SecureNow preload adds a managed IP firewall in one line, no DNS changes required.

For broader context see the SecureNow Firewall page.

The one-line setup

npm install securenow

# In your start command:
node -r securenow/firewall-only dist/main.js

In a Dockerfile:

CMD ["node", "-r", "securenow/firewall-only", "dist/main.js"]

In a process manager (PM2):

// ecosystem.config.js
module.exports = {
  apps: [{
    name: 'nestjs-app',
    script: 'dist/main.js',
    node_args: '-r securenow/firewall-only',
  }],
};

The firewall sits at the HTTP server level — below NestJS, below Express/Fastify. Bad IPs get a 403 before any NestJS code runs.

What you get out of the box

  • 500k known-bad IPs (AbuseIPDB feed)
  • Hourly refresh
  • Auto-allowlist for Googlebot, Bingbot, GPTBot, ClaudeBot, PerplexityBot
  • Sub-millisecond per-request overhead
  • Fail-open on backend unreachability
  • Free at any traffic level

Hand-rolled NestJS Middleware (alternative)

If you want application-layer control:

// src/firewall/firewall.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

const blocklist = new Set<string>();
// ... load from file or feed

@Injectable()
export class FirewallMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    const ip = (req.headers['x-forwarded-for'] as string)?.split(',')[0]?.trim()
      || req.socket.remoteAddress;
    if (ip && blocklist.has(ip)) {
      return res.status(403).send('Forbidden');
    }
    next();
  }
}

Apply globally:

// src/app.module.ts
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { FirewallMiddleware } from './firewall/firewall.middleware';

@Module({ /* ... */ })
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(FirewallMiddleware).forRoutes('*');
  }
}

The catch: maintaining a 50k-entry blocklist as code is impractical. Either pull from a feed periodically or use the SecureNow preload, which handles the feed for you.

Verifying

npx securenow firewall status

Returns the current blocklist size and last refresh time. To check a specific IP:

npx securenow firewall test-ip 185.220.101.42

Returns whether that IP would be blocked or allowed by the current ruleset.

Combining with NestJS Throttler

Run them together — different layers:

  • SecureNow firewall: blocks known-bad IPs (reputation-based)
  • NestJS Throttler: rate limits all IPs (rate-based)

Both run automatically; one is a preload, the other is a Module. No conflict.

When to use a CDN-level firewall instead

If you have:

  • Layer-3/4 attacks (SYN floods, UDP amplification)
  • Sophisticated bot traffic that mimics browsers perfectly
  • DDoS protection requirements (uptime-critical traffic)

Move the IP firewall to your CDN (Cloudflare, AWS Shield, Imperva). Application-layer firewall handles 80% of attacks but not all.

Related

Frequently Asked Questions

Does NestJS need special configuration for the firewall?

No. NestJS runs on Node.js with an Express (default) or Fastify HTTP adapter. The SecureNow preload sits below both, so the firewall works without NestJS-specific setup.

What if I'm running NestJS in a Docker container?

Add the preload to your CMD or ENTRYPOINT. For example: `CMD ["node", "-r", "securenow/firewall-only", "dist/main.js"]`.

Will this work with NestJS microservices (gRPC, NATS)?

Yes for HTTP transports. For pure gRPC/NATS microservices, the IP-firewall layer doesn't apply — those don't have an HTTP server. Use the application-layer security observability instead.

Can I customize the blocklist?

Yes. Add per-app rules from the SecureNow dashboard, CLI (`securenow blocklist add <ip>`), or API. The 500k base list refreshes hourly; your custom additions sync within ~10 seconds.

Recommended reading

Adding Backend Tracing to a Sentry Stack with OpenTelemetry

If your team uses Sentry for frontend errors and needs backend distributed tracing without doubling the Sentry bill, here's the OpenTelemetry path that doesn't make you choose.

May 9
How to Block Bot Traffic in Express With No Extra Infra

Five approaches to bot blocking in Express, ranked by effort vs. effectiveness. From a 5-line allowlist to a full IP-reputation firewall — all without Cloudflare, AWS WAF, or any new infrastructure.

May 9
How to Block Bot Traffic in Fastify With No Extra Infra

Fastify hooks (onRequest) and the SecureNow preload both work cleanly. Here's the production setup for IP blocking and user-agent filtering.

May 9