Browse Source

Use spaces for indentation

master
digital dreamer 10 years ago
parent
commit
80daa05d40
  1. 17
      package.json
  2. 96
      settings.json
  3. 240
      twister-proxy.js

17
package.json

@ -5,19 +5,20 @@ @@ -5,19 +5,20 @@
"author": "digital dreamer <digitaldreamer@email.cz>",
"dependencies":
{
"express": ">=2.5.x",
"cors": "*",
"log-timestamp": ">=0.1.1"
"express": ">=2.5.x",
"cors": "*",
"log-timestamp": ">=0.1.1"
},
"repository": {
"repository":
{
"type": "git",
"url": "https://github.com/digital-dreamer/twister-proxy.git"
},
"licenses":
[
{
"type": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
{
"type": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
]
}

96
settings.json

@ -1,65 +1,65 @@ @@ -1,65 +1,65 @@
{
"Server":
{
"ssl_key_file": "insert/path/to/your/server-key-file",
"ssl_certificate_file": "insert/path/to/your/ssl-certificate",
"enable_https": false,
"https_port": 443,
"http_port": 80
"ssl_key_file": "insert/path/to/your/server-key-file",
"ssl_certificate_file": "insert/path/to/your/ssl-certificate",
"enable_https": false,
"https_port": 443,
"http_port": 80
},
"RPC":
{
"host": "localhost",
"port": 28332,
"user": "user",
"password": "pwd"
"host": "localhost",
"port": 28332,
"user": "user",
"password": "pwd"
},
"CallLimits":
[
{
"name": "getbestblockhash",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "getinfo",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "listwalletusers",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "getblock",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "dhtget",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "listusernamespartial",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "gettrendinghashtags",
"maxPerMinute": null,
"maxPerMinutePerIP": null
}
{
"name": "getbestblockhash",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "getinfo",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "listwalletusers",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "getblock",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "dhtget",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "listusernamespartial",
"maxPerMinute": null,
"maxPerMinutePerIP": null
},
{
"name": "gettrendinghashtags",
"maxPerMinute": null,
"maxPerMinutePerIP": null
}
],
"LogAsAttackThreshold":
{
"callsOverLimits": 30,
"invalidRequests": 30,
"forbiddenCalls": 30
"callsOverLimits": 30,
"invalidRequests": 30,
"forbiddenCalls": 30
}
}

240
twister-proxy.js

@ -21,21 +21,21 @@ if(settings.Server.enable_https) @@ -21,21 +21,21 @@ if(settings.Server.enable_https)
{
try
{
var privateKey = fs.readFileSync(settings.Server.ssl_key_file).toString();
var privateKey = fs.readFileSync(settings.Server.ssl_key_file).toString();
}
catch(e)
{
console.log("Error: unable to load SSL key. Please edit setting.json and put the correct path to your SSL private key file into \"ssl_key_file.\"");
process.exit(1);
console.log("Error: unable to load SSL key. Please edit setting.json and put the correct path to your SSL private key file into \"ssl_key_file.\"");
process.exit(1);
}
try
{
var certificate = fs.readFileSync(settings.Server.ssl_certificate_file).toString();
var certificate = fs.readFileSync(settings.Server.ssl_certificate_file).toString();
}
catch(e)
{
console.log("Error: unable to load SSL certificate. Please edit setting.json and put the correct path to your SSL certificate file into \"ssl_certificate_file.\"");
process.exit(1);
console.log("Error: unable to load SSL certificate. Please edit setting.json and put the correct path to your SSL certificate file into \"ssl_certificate_file.\"");
process.exit(1);
}
var credentials = {key: privateKey, cert: certificate};
}
@ -67,8 +67,8 @@ CounterInstance = function() @@ -67,8 +67,8 @@ CounterInstance = function()
this.callsRemaining={};
for (x in maxCallsPerMinutePerIP)
{
if(maxCallsPerMinutePerIP[x]!==null)
this.callsRemaining[x]=maxCallsPerMinutePerIP[x];
if(maxCallsPerMinutePerIP[x]!==null)
this.callsRemaining[x]=maxCallsPerMinutePerIP[x];
}
}
@ -80,30 +80,30 @@ app.get("*", function(request, response) @@ -80,30 +80,30 @@ app.get("*", function(request, response)
{
if(settings.Server.enable_https&&request.protocol=="http")
{
if(settings.Server.https_port==443)
secureUrl="https://"+request.host+request.path;
else
secureUrl="https://"+request.host+":"+settings.Server.https_port+request.path;
response.writeHead(302, {"Location": secureUrl});
response.end();
return;
if(settings.Server.https_port==443)
secureUrl="https://"+request.host+request.path;
else
secureUrl="https://"+request.host+":"+settings.Server.https_port+request.path;
response.writeHead(302, {"Location": secureUrl});
response.end();
return;
}
request.headers.Authorization = auth;
var webProxy = http.request({host: settings.RPC.host, port: settings.RPC.port, method: request.method, path: request.path, headers: request.headers}, function (proxy_res)
{
proxy_res.pipe(response, {end: true});
proxy_res.pipe(response, {end: true});
});
webProxy.on("error", function(error)
{
if(!connectionErrorMessageDisplayed)
{
console.log("Error: cannot connect to twisterd.\nSee Troubleshooting section in README.md for instructions.");
connectionErrorMessageDisplayed=true;
}
response.send(502);
if(!connectionErrorMessageDisplayed)
{
console.log("Error: cannot connect to twisterd.\nSee Troubleshooting section in README.md for instructions.");
connectionErrorMessageDisplayed=true;
}
response.send(502);
});
request.pipe(webProxy, {end: true});
@ -122,82 +122,82 @@ app.post("/", function(request, response) @@ -122,82 +122,82 @@ app.post("/", function(request, response)
request.addListener("end", function()
{
var remoteIP = request.connection.remoteAddress;
if(perIPCounter[remoteIP]===undefined)
{
perIPCounter[remoteIP]=new CounterInstance();
}
try
{
bodyJson=JSON.parse(request.rawBody);
rpcMethod=bodyJson.method;
}
catch(e)
{
perIPCounter[remoteIP].invalidRequests++;
invalidRequestCounter++;
return;
}
if(maxCallsPerMinute[rpcMethod]===undefined)
{
perIPCounter[remoteIP].forbiddenCalls++;
forbiddenCallCounter++;
return;
}
if(maxCallsPerMinute[rpcMethod]!==null)
{
if(callsRemaining[rpcMethod]<1)
{
droppedCallsCounter[rpcMethod]++;
return;
}
else
{
callsRemaining[rpcMethod]--;
}
}
if(maxCallsPerMinutePerIP[rpcMethod]!==null)
{
if(perIPCounter[remoteIP].callsRemaining[rpcMethod]<1)
{
perIPCounter[remoteIP].overLimit++;
return;
}
else
{
perIPCounter[remoteIP].callsRemaining[rpcMethod]--;
}
}
var rpcProxy = http.request({host: settings.RPC.host, port: settings.RPC.port, method: request.method, headers: request.headers}, function(proxy_res)
{
proxy_res.on("data", function(chunk)
{
response.write(chunk, "binary");
});
proxy_res.on("end", function(chunk)
{
response.end();
});
proxy_res.on("error", function(error)
{
if(!connectionErrorMessageDisplayed)
{
console.log("Error: cannot connect to twisterd.\nSee Troubleshooting section in README.md for instructions.");
connectionErrorMessageDisplayed=true;
}
response.send(502);
});
response.writeHead(proxy_res.statusCode, proxy_res.headers);
});
rpcProxy.write(request.rawBody, "binary");
rpcProxy.end();
var remoteIP = request.connection.remoteAddress;
if(perIPCounter[remoteIP]===undefined)
{
perIPCounter[remoteIP]=new CounterInstance();
}
try
{
bodyJson=JSON.parse(request.rawBody);
rpcMethod=bodyJson.method;
}
catch(e)
{
perIPCounter[remoteIP].invalidRequests++;
invalidRequestCounter++;
return;
}
if(maxCallsPerMinute[rpcMethod]===undefined)
{
perIPCounter[remoteIP].forbiddenCalls++;
forbiddenCallCounter++;
return;
}
if(maxCallsPerMinute[rpcMethod]!==null)
{
if(callsRemaining[rpcMethod]<1)
{
droppedCallsCounter[rpcMethod]++;
return;
}
else
{
callsRemaining[rpcMethod]--;
}
}
if(maxCallsPerMinutePerIP[rpcMethod]!==null)
{
if(perIPCounter[remoteIP].callsRemaining[rpcMethod]<1)
{
perIPCounter[remoteIP].overLimit++;
return;
}
else
{
perIPCounter[remoteIP].callsRemaining[rpcMethod]--;
}
}
var rpcProxy = http.request({host: settings.RPC.host, port: settings.RPC.port, method: request.method, headers: request.headers}, function(proxy_res)
{
proxy_res.on("data", function(chunk)
{
response.write(chunk, "binary");
});
proxy_res.on("end", function(chunk)
{
response.end();
});
proxy_res.on("error", function(error)
{
if(!connectionErrorMessageDisplayed)
{
console.log("Error: cannot connect to twisterd.\nSee Troubleshooting section in README.md for instructions.");
connectionErrorMessageDisplayed=true;
}
response.send(502);
});
response.writeHead(proxy_res.statusCode, proxy_res.headers);
});
rpcProxy.write(request.rawBody, "binary");
rpcProxy.end();
});
});
@ -212,38 +212,38 @@ setInterval(function() @@ -212,38 +212,38 @@ setInterval(function()
{
for(method in maxCallsPerMinute)
{
callsRemaining[method] = maxCallsPerMinute[method];
if(droppedCallsCounter[method]!==0)
{
console.log("Dropped "+droppedCallsCounter[method]+" calls to "+method+" over the limit of "+maxCallsPerMinute[method]);
droppedCallsCounter[method] = 0;
}
callsRemaining[method] = maxCallsPerMinute[method];
if(droppedCallsCounter[method]!==0)
{
console.log("Dropped "+droppedCallsCounter[method]+" calls to "+method+" over the limit of "+maxCallsPerMinute[method]);
droppedCallsCounter[method] = 0;
}
};
if(invalidRequestCounter!==0)
{
console.log("Received "+invalidRequestCounter+" invalid POST requests.");
invalidRequestCounter = 0;
console.log("Received "+invalidRequestCounter+" invalid POST requests.");
invalidRequestCounter = 0;
}
if(forbiddenCallCounter!==0)
{
console.log("Denied "+forbiddenCallCounter+" attempts to access forbidden API calls.");
forbiddenCallCounter = 0;
console.log("Denied "+forbiddenCallCounter+" attempts to access forbidden API calls.");
forbiddenCallCounter = 0;
}
for(ip in perIPCounter)
{
if(perIPCounter[ip].overLimit>=settings.LogAsAttackThreshold.callsOverLimits)
{
console.log("IP "+ip+" tried to send "+perIPCounter[ip].overLimit+" calls more than the limits allow.");
};
if(perIPCounter[ip].invalidRequests>=settings.LogAsAttackThreshold.invalidRequests)
{
console.log("IP "+ip+" sent "+perIPCounter[ip].invalidRequests+" invalid request that couldn't be parsed.");
};
if(perIPCounter[ip].forbiddenCalls>=settings.LogAsAttackThreshold.forbiddenCalls)
{
console.log("IP "+ip+" tried to send "+perIPCounter[ip].forbiddenCalls+" calls to forbidden functions.");
};
if(perIPCounter[ip].overLimit>=settings.LogAsAttackThreshold.callsOverLimits)
{
console.log("IP "+ip+" tried to send "+perIPCounter[ip].overLimit+" calls more than the limits allow.");
};
if(perIPCounter[ip].invalidRequests>=settings.LogAsAttackThreshold.invalidRequests)
{
console.log("IP "+ip+" sent "+perIPCounter[ip].invalidRequests+" invalid request that couldn't be parsed.");
};
if(perIPCounter[ip].forbiddenCalls>=settings.LogAsAttackThreshold.forbiddenCalls)
{
console.log("IP "+ip+" tried to send "+perIPCounter[ip].forbiddenCalls+" calls to forbidden functions.");
};
}
perIPCounter = {};

Loading…
Cancel
Save