Skip to content
This repository has been archived by the owner on Nov 28, 2018. It is now read-only.

Commit

Permalink
Merge pull request #7 from baminteractive/cidr-ranges
Browse files Browse the repository at this point in the history
Cidr ranges
  • Loading branch information
ryanbillingsley committed Dec 17, 2014
2 parents f27e552 + d036557 commit 7f7016b
Show file tree
Hide file tree
Showing 4 changed files with 644 additions and 625 deletions.
1 change: 1 addition & 0 deletions .jshintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test/coverage/**
12 changes: 0 additions & 12 deletions .travis.yml

This file was deleted.

254 changes: 129 additions & 125 deletions lib/ipfilter.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
/*!
* Dwolla - IP Filter
* Copyright(c) 2012 Dwolla Inc.
* Express - IP Filter
* Copyright(c) 2014 Bradley and Montgomery Inc.
* MIT Licensed
*/

'use strict';

/**
* Module dependencies.
*/
var _ = require('lodash')
, iputil = require('ip')
, Netmask = require('netmask').Netmask;
var _ = require('lodash'),
iputil = require('ip'),
Netmask = require('netmask').Netmask;

/**
* node-ipfilter:
* express-ipfilter:
*
* IP Filtering middleware;
* IP Filtering middleware;
*
* Examples:
*
Expand All @@ -39,125 +40,128 @@ var _ = require('lodash')
* @param {Object} options
* @api public
*/
module.exports = function ipfilter(ips, opts) {
ips = ips || false;

var logger = function(message){ console.log(message);};
var settings = _.defaults( opts || {}, {
mode: 'deny'
, log: true
, logF: logger
, errorCode: 401
, errorMessage: 'Unauthorized'
, allowPrivateIPs: false
, cidr: false
, ranges: false
, excluding: []
});

var getClientIp = function(req) {
var ipAddress;

var forwardedIpsStr = req.headers['x-forwarded-for'];

if (forwardedIpsStr) {
var forwardedIps = forwardedIpsStr.split(',');
ipAddress = forwardedIps[0];
}

if (!ipAddress) {
ipAddress = req.connection.remoteAddress;
}

if(!ipAddress){
return "";
}

if(ipAddress.indexOf(':') !== -1){
ipAddress = ipAddress.split(':')[0];
}

return ipAddress;
};

var matchClientIp = function(ip){
var mode = settings.mode.toLowerCase()
, allowedIp = false
, notBannedIp = false
, isPrivateIpOkay = false; // Normalize mode

if(settings.cidr){
for(var i = 0; i < ips.length; i++){

var block = new Netmask(ips[i]);

if(block.contains(ip)){
allowedIp = (mode == 'allow');
break;
}else{
notBannedIp = (mode == 'deny');
isPrivateIpOkay = settings.allowPrivateIPs && iputil.isPrivate(ip);
module.exports = function ipfilter(ips, opts) {
ips = ips || false;

var logger = function(message){ console.log(message);};
var settings = _.defaults( opts || {}, {
mode: 'deny',
log: true,
logF: logger,
errorCode: 401,
errorMessage: 'Unauthorized',
allowPrivateIPs: false,
cidr: false,
ranges: false,
excluding: []
});

var getClientIp = function(req) {
var ipAddress;

var forwardedIpsStr = req.headers['x-forwarded-for'];

if (forwardedIpsStr) {
var forwardedIps = forwardedIpsStr.split(',');
ipAddress = forwardedIps[0];
}

if (!ipAddress) {
ipAddress = req.connection.remoteAddress;
}

if(!ipAddress){
return '';
}

if(ipAddress.indexOf(':') !== -1){
ipAddress = ipAddress.split(':')[0];
}
}
}else if(settings.ranges){
var filteredSet = _.filter(ips,function(ipSet){
if(ipSet.length > 1){
var startIp = iputil.toLong(ipSet[0]);
var endIp = iputil.toLong(ipSet[1]);
var longIp = iputil.toLong(ip);
return longIp >= startIp && longIp <= endIp;

return ipAddress;
};

var matchClientIp = function(ip){
var mode = settings.mode.toLowerCase(),
allowedIp = false,
notBannedIp = false,
isPrivateIpOkay = false; // Normalize mode

if(settings.cidr){
for(var i = 0; i < ips.length; i++){

var block = new Netmask(ips[i]);

if(block.contains(ip)){
allowedIp = (mode === 'allow');
if(mode === 'deny'){
notBannedIp = false;
}
break;
}else{
notBannedIp = (mode === 'deny');
isPrivateIpOkay = settings.allowPrivateIPs && iputil.isPrivate(ip);
}
}
}else if(settings.ranges){
var filteredSet = _.filter(ips,function(ipSet){
if(ipSet.length > 1){
var startIp = iputil.toLong(ipSet[0]);
var endIp = iputil.toLong(ipSet[1]);
var longIp = iputil.toLong(ip);
return longIp >= startIp && longIp <= endIp;
}else{
return ip === ipSet[0];
}
});

allowedIp = (mode === 'allow' && filteredSet.length > 0);
notBannedIp = (mode === 'deny' && filteredSet.length === 0);
isPrivateIpOkay = settings.allowPrivateIPs && iputil.isPrivate(ip) && !(mode === 'deny' && filteredSet.length > 0);
}else{
return ip == ipSet[0];
allowedIp = (mode === 'allow' && ips.indexOf(ip) !== -1);
notBannedIp = (mode === 'deny' && ips.indexOf(ip) === -1);
isPrivateIpOkay = settings.allowPrivateIPs && iputil.isPrivate(ip) && !(mode === 'deny' && ips.indexOf(ip) !== -1);
}
});

allowedIp = (mode == 'allow' && filteredSet.length > 0);
notBannedIp = (mode == 'deny' && filteredSet.length === 0);
isPrivateIpOkay = settings.allowPrivateIPs && iputil.isPrivate(ip) && !(mode == 'deny' && filteredSet.length > 0);
}else{
allowedIp = (mode == 'allow' && ips.indexOf(ip) !== -1);
notBannedIp = (mode == 'deny' && ips.indexOf(ip) === -1);
isPrivateIpOkay = settings.allowPrivateIPs && iputil.isPrivate(ip) && !(mode == 'deny' && ips.indexOf(ip) !== -1);
}

return allowedIp || notBannedIp || isPrivateIpOkay;
};

return function(req, res, next) {
if(settings.excluding.length > 0){
var results = _.filter(settings.excluding,function(exclude){
var regex = new RegExp(exclude);
return regex.test(req.url);
});

if(results.length > 0){
if(settings.log){
console.log('Access granted for excluded path: ' + results[0]);

return allowedIp || notBannedIp || isPrivateIpOkay;
};

return function(req, res, next) {
if(settings.excluding.length > 0){
var results = _.filter(settings.excluding,function(exclude){
var regex = new RegExp(exclude);
return regex.test(req.url);
});

if(results.length > 0){
if(settings.log){
console.log('Access granted for excluded path: ' + results[0]);
}
return next();
}
}

var ip = getClientIp(req);
// If no IPs were specified, skip
// this middleware
if(!ips || !ips.length) { return next(); }

if(matchClientIp(ip,req)) {
// Grant access
if(settings.log) {
settings.logF('Access granted to IP address: ' + ip);
}

return next();
}

// Deny access
if(settings.log) {
settings.logF('Access denied to IP address: ' + ip);
}
return next();
}
}

var ip = getClientIp(req);
// If no IPs were specified, skip
// this middleware
if(!ips || !ips.length) { return next(); }

if(matchClientIp(ip,req)) {
// Grant access
if(settings.log) {
settings.logF('Access granted to IP address: ' + ip);
}

return next();
}

// Deny access
if(settings.log) {
settings.logF('Access denied to IP address: ' + ip);
}

res.statusCode = settings.errorCode;
return res.end(settings.errorMessage);
};
};

res.statusCode = settings.errorCode;
return res.end(settings.errorMessage);
};
};
Loading

0 comments on commit 7f7016b

Please sign in to comment.