Node.js Integration
Express and Fastify middleware for IP blocking. Step-by-step setup guide with code examples.
186,817 IPs
8,269 reports
Free API
Quick Install
Sign in to get your API key for 1,000 req/day and profile attribution.
Copy the middleware file below into your project. No npm packages needed:
curl -sL https://bl.ipwhois.net/api/nodejs/plugin -o middleware/ipwhois-guard.js
Zero dependencies. Uses built-in fetch (Node 18+). In-memory cache with automatic cleanup. Or just copy the code from below.
Requires:
Node.js 18+
npm
What does it do?
Express/Fastify middleware that checks every request against the IPWhois.net Blacklist. Blocks malicious IPs and optionally reports brute-force attempts. Uses in-memory cache so blacklisted IPs are only checked once per hour.
Block
Returns 403 for blacklisted IPs on any route you protect with the middleware.
Report
Reports blocked IPs back to the blacklist via the report API function.
Express Middleware
No additional packages required (Node 18+ has built-in fetch).
middleware/ipwhois-guard.js
const cache = new Map();
const CACHE_TTL = 3600000; // 1 hour
const MIN_CONFIDENCE = 90;
async function ipwhoisGuard(req, res, next) {
const ip = (req.headers['x-forwarded-for'] || '').split(',')[0].trim()
|| req.socket.remoteAddress || req.ip;
const cached = cache.get(ip);
if (cached && Date.now() - cached.ts < CACHE_TTL) {
if (cached.blocked) return res.status(403).json({ error: 'Blocked' });
return next();
}
try {
const r = await fetch(
`https://bl.ipwhois.net/api/check?ip=${encodeURIComponent(ip)}`,
{ signal: AbortSignal.timeout(3000) }
);
const data = await r.json();
const blocked = data.listed && (data.confidence || 0) >= MIN_CONFIDENCE;
cache.set(ip, { blocked, ts: Date.now() });
if (blocked) return res.status(403).json({ error: 'Blocked' });
} catch (err) {
// API down = allow traffic (fail open)
}
next();
}
// Clean expired cache entries every 10 min
setInterval(() => {
const now = Date.now();
for (const [ip, entry] of cache) {
if (now - entry.ts > CACHE_TTL) cache.delete(ip);
}
}, 600000);
module.exports = ipwhoisGuard;
Usage with Express
app.js
const express = require('express');
const ipwhoisGuard = require('./middleware/ipwhois-guard');
const app = express();
// Protect specific routes
app.use('/login', ipwhoisGuard);
app.use('/admin', ipwhoisGuard);
app.use('/api', ipwhoisGuard);
// Or protect everything
// app.use(ipwhoisGuard);
app.listen(3000);
Report Function
Report malicious IPs back to the blacklist. Call this when you detect attacks (failed logins, suspicious requests, etc.):
async function reportToIPWhois(ip, type = 'brute-force', message = '') {
try {
await fetch('https://bl.ipwhois.net/api/report', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ ip, type, message, source: 'waf' }),
signal: AbortSignal.timeout(5000)
});
} catch (err) {
// Report failure is non-critical
}
}
// Example: report after 5 failed login attempts
const loginFails = new Map();
app.post('/login', (req, res) => {
const ip = req.ip;
const fails = (loginFails.get(ip) || 0) + 1;
loginFails.set(ip, fails);
if (fails >= 5) {
reportToIPWhois(ip, 'brute-force', `Login: ${fails} failed attempts`);
}
// ... your login logic
});
Troubleshooting
- fetch is not defined: Requires Node.js 18+. For older versions:
npm install node-fetchandconst fetch = require('node-fetch'). - Getting 127.0.0.1: Set
app.set('trust proxy', true)in Express for correct IP behind Nginx/Cloudflare. - Memory growth: The cleanup interval prevents unbounded growth. For high-traffic apps, replace the Map with Redis.
- ESM imports: Use
import ipwhoisGuard from './middleware/ipwhois-guard.js'for ES modules. - Fastify: Use
fastify.addHook('onRequest', ipwhoisGuard)instead of Express middleware.