Added support for X-forwarded-for and host blacklisting

pull/2/head
Jim Heising 2014-08-27 10:03:21 -07:00
parent 61cbd07c95
commit 7dd6defa73
3 changed files with 48 additions and 14 deletions

View File

@ -5,3 +5,4 @@ exports.proxy_request_timeout_ms = 10000; // The lenght of time we'll wait for a
exports.max_request_length = 100000; // The maximum length of characters allowed for a request or a response.
exports.enable_rate_limiting = true;
exports.max_requests_per_second = 10; // The maximum number of requests per second to allow from a given IP.
exports.blacklist_hostname_regex = /^(10\.|192\.|localhost$)/i; // Good for limiting access to internal IP addresses and hosts.

View File

@ -1,12 +1,13 @@
{
"name": "thingproxy.freeboard.io",
"version": "0.0.1",
"description": "A simple forward proxy server for processing API calls to servers that don't send CORS headers or support HTTPS.",
"main": "server.js",
"author": "Jim Heising <jim@buglabs.net>",
"license": "MIT",
"dependencies": {
"request": "2.40.0",
"tokenthrottle": "1.1.0"
}
"name": "thingproxy.freeboard.io",
"version": "0.0.1",
"description": "A simple forward proxy server for processing API calls to servers that don't send CORS headers or support HTTPS.",
"main": "server.js",
"author": "Jim Heising <jim@buglabs.net>",
"license": "MIT",
"dependencies": {
"request": "2.40.0",
"tokenthrottle": "1.1.0",
"public-address": "^0.1.1"
}
}

View File

@ -4,6 +4,17 @@ var url = require("url");
var request = require("request");
var throttle = require("tokenthrottle")({rate: config.max_requests_per_second});
var publicAddressFinder = require("public-address");
var publicIP;
// Get our public IP address
publicAddressFinder(function(err, data){
if(!err && data)
{
publicIP = data.address;
}
});
function addCORSHeaders(req, res)
{
if (req.method.toUpperCase() === "OPTIONS")
@ -75,11 +86,30 @@ function processRequest(req, res)
return writeResponse(res, 404, "relative URLS are not supported");
}
// Naughty, naughty— deny requests to blacklisted hosts
if(config.blacklist_hostname_regex.test(remoteURL.hostname))
{
return writeResponse(res, 400, "naughty, naughty...");
}
// We only support http and https
if (remoteURL.protocol != "http:" && remoteURL.protocol !== "https:") {
return writeResponse(res, 400, "only http and https are supported");
}
if(publicIP)
{
// Add an X-Forwarded-For header
if(req.headers["x-forwarded-for"])
{
req.headers["x-forwarded-for"] += ", " + publicIP;
}
else
{
req.headers["x-forwarded-for"] = req.clientIP + ", " + publicIP;
}
}
var proxyRequest = request({
url: remoteURL,
headers: req.headers,
@ -140,17 +170,19 @@ http.createServer(function (req, res) {
return writeResponse(res, 200);
}
var remoteIP = getClientAddress(req);
var clientIP = getClientAddress(req);
req.clientIP = clientIP;
// Log our request
if(config.enable_logging)
{
console.log("%s %s %s", (new Date()).toJSON(), remoteIP, req.method, req.url);
console.log("%s %s %s", (new Date()).toJSON(), clientIP, req.method, req.url);
}
if(config.enable_rate_limiting)
{
throttle.rateLimit(remoteIP, function(err, limited) {
throttle.rateLimit(clientIP, function(err, limited) {
if (limited)
{
return writeResponse(res, 429, "enhance your calm");