How to Block IP Addresses in Express.js

Updated: December 28, 2023 By: Guest Contributor Post a comment

Blocking specific IP addresses in your Express.js application can be crucial for security and traffic management. There are multiple methods to achieve this, each with its benefits and drawbacks. Below, we’ll explore three different solutions to block IP addresses in Express.js.

Solution 1: Middleware Function

Using a custom middleware function in Express.js allows you to block IP addresses by adding the function into your request handling pipeline. This approach is simple and straightforward.

  • Identify the IP addresses that you want to block.
  • Create a new middleware function that checks if the incoming request’s IP address matches any in the blocked list.
  • If a match is found, respond with an appropriate error message and status code, such as 403 Forbidden. Otherwise, continue processing the request.
  • Add the middleware function early in your application’s middleware stack to reject the disallowed requests as soon as possible.
const express = require('express');
const app = express();

const blockedIPs = ['123.45.67.89', '98.76.54.32'];

const ipFilterMiddleware = (req, res, next) => {
  const clientIp = req.ip;
  if (blockedIPs.includes(clientIp)) {
    res.status(403).send('Access denied');
  } else {
    next();
  }
};

app.use(ipFilterMiddleware);

app.get('/', (req, res) => {
  res.send('Welcome!');
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Pros:

  • Simple to implement and easy to understand.
  • Highly flexible and customizable as per application needs.
  • No additional dependencies required.

Cons:

  • Not very scalable for a large list of IP addresses.
  • Requires manual updating of the blocked IP list.

Solution 2: Using express-ipfilter

The express-ipfilter package is a middleware for IP filtering. It allows you to use globs, CIDR (Classless Inter-Domain Routing) ranges, and array of IPs for blocking and allows the creation of white lists or black lists.

  • Install the express-ipfilter package using npm.
  • Include the ipfilter middleware in your application specifying the list of disallowed IPs or ranges.
  • Configure the middleware to block by setting the mode to ‘deny’ and providing an error handler.
  • Add the configured ipfilter middleware to your application.
const express = require('express');
const ipfilter = require('express-ipfilter').IpFilter;
const app = express();

const blockedIPs = ['123.45.67.89', '98.76.54.32'];
const ipFilter = ipfilter(blockedIPs, { mode: 'deny' });

app.use(ipFilter);

app.use((err, req, res, next) => {
  if (err instanceof ipfilter.IpDeniedError) {
    res.status(403).send('Access denied');
  } else {
    next(err);
  }
});

app.get('/', (req, res) => {
  res.send('Welcome!');
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Pros:

  • Support for a variety of IP formats and ranges.
  • Ability to easily switch between allow and deny lists.
  • Error handling is more robust with specific instances.

Cons:

  • Dependency on a third-party package.
  • Potential overhead of keeping the package up-to-date with security patches.

Solution 3: Reverse Proxy Blocking

Using a reverse proxy like Nginx or HAProxy in front of your Express.js application can provide a centralized way to block IP addresses, offering performance and security benefits.

  • Set up a reverse proxy server in front of your Express.js application.
  • Configure the reverse proxy to block requests from specific IP addresses before they reach your Express.js server.
  • Restart or reload the reverse proxy server configuration to activate the changes.
# Nginx configuration example
deny 123.45.67.89;
deny 98.76.54.32;
allow all;

# HAProxy configuration example
acl blocked_ips src 123.45.67.89 98.76.54.32
deny if blocked_ips

Pros:

  • Offloads the blocking logic from the Express.js application, which can improve performance.
  • Centralized blocking for multiple applications behind the reverse proxy.
  • Better suited for handling a large number of IP blocks and complex configurations.

Cons:

  • Requires setting up and maintaining a separate reverse proxy server.
  • More complex configuration that might require advanced networking knowledge.

Conclusion

Blocking IP addresses in an Express.js application can be performed through various methods depending on the needs and scale of the application. Simple middleware functions offer flexibility and ease of use, while reverse proxy solutions deliver performance and centralized management advantages. Third-party middleware packages can also be a compromise, providing robust feature sets with minimal configuration. It’s crucial to evaluate the pros and cons of each approach to select the most suitable method for your specific use case.