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

Cidr ranges #7

Merged
merged 2 commits into from
Dec 17, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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