Created
March 20, 2014 19:58
-
-
Save crimeminister/9672525 to your computer and use it in GitHub Desktop.
Express middleware for IP-based access control
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var _ = require('lodash'); | |
var keystone = require('keystone'); | |
var range_check = require('range_check'); | |
var util = require('util'); | |
/** | |
* | |
*/ | |
exports.ipRangeRestrict = function (req, res, next) { | |
// Require that ALLOWED_IP_RANGES be set in the environment. | |
if (_.isUndefined(process.env.ALLOWED_IP_RANGES)) { | |
throw 'Allowed IP range is not defined'; | |
} | |
var allowedRanges = process.env.ALLOWED_IP_RANGES.split(/\s+|,/); | |
// Regular expression for matching IPv4 CIDR ranges. | |
var cidr = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(\d|[1-2]\d|3[0-2]))$/; | |
// The set of allowed ranges has to be separated by space or comma | |
// characters. | |
allowedRanges = _(allowedRanges) | |
.filter(function (range) { | |
return _.isString(range) && range.match(cidr); | |
}) | |
.value(); | |
// Using req.ips requires that express 'trust proxy' setting is | |
// true. When it *is* set the value for ips is extracted from the | |
// X-Forwarded-For request header. The originating IP address is | |
// the last one in the array. | |
var requestIP = (req.ips.length > 0) ? req.ips.slice().pop() : req.ip; | |
// Deny the request if request IP is not in one of the allowed | |
// IP address range. | |
var requestAllowed = range_check.in_range(req.ip, allowedRanges); | |
if (!requestAllowed) { | |
var msg = '-> blocked request from %s (not in allowed IP range)'; | |
console.log(util.format(msg, req.ip)); | |
// Display error page to the user | |
var title = 'Sorry, your request is not authorized (403)'; | |
var message = 'Requests from outside permitted IP range are not allowed'; | |
res.status(403).render('errors/403', { | |
title: title, | |
message: message | |
}); | |
} | |
next(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment