diff --git a/app/lib/system/network.js b/app/lib/system/network.js index d48d4cfb1cb9e507d3b9899f066332e198cdcaeb..ff7df89621197701b917a8ca8b53c1323f80ec33 100644 --- a/app/lib/system/network.js +++ b/app/lib/system/network.js @@ -5,6 +5,7 @@ const os = require('os'); const Q = require('q'); const _ = require('underscore'); const upnp = require('nnupnp'); +const ddos = require('ddos'); const http = require('http'); const express = require('express'); const morgan = require('morgan'); @@ -99,6 +100,14 @@ module.exports = { })); } + // DDOS protection + const whitelist = interfaces.map(i => i.ip); + if (whitelist.indexOf('127.0.0.1') === -1) { + whitelist.push('127.0.0.1'); + } + const ddosInstance = new ddos({ whitelist }); + app.use(ddosInstance.express); + // CORS for **any** HTTP request app.use(cors()); @@ -165,6 +174,8 @@ module.exports = { // Return API return { + getDDOS: () => ddosInstance, + closeConnections: () => co(function *() { for (let i = 0, len = httpServers.length; i < len; i++) { const httpServer = httpServers[i].http; diff --git a/package.json b/package.json index 7ebd46995b21514a74172a9ab898868cbad3b31b..50de5902c75c35ac49c0aa70b9ca2bc759d1681f 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "commander": "2.9.0", "cors": "2.8.1", "daemonize2": "0.4.2", + "ddos": "0.1.16", "errorhandler": "1.4.3", "event-stream": "3.3.4", "express": "4.14.0", diff --git a/test/fast/ddos-test.js b/test/fast/ddos-test.js new file mode 100644 index 0000000000000000000000000000000000000000..a2c4f74f180372b020f553b7c66b881959c714b8 --- /dev/null +++ b/test/fast/ddos-test.js @@ -0,0 +1,39 @@ +"use strict"; +const should = require('should'); +const co = require('co'); +const limiter = require('../../app/lib/system/limiter'); +const toolbox = require('../integration/tools/toolbox'); +const user = require('../integration/tools/user'); +const bma = require('../../app/lib/streams/bma'); + +limiter.noLimit(); + +const s1 = toolbox.server({ + pair: { + pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', + sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP' + } +}); + +describe('DDOS', () => { + + before(() => co(function*() { + limiter.noLimit(); + yield s1.initWithDAL().then(bma).then((bmapi) => { + s1.bma = bmapi; + bmapi.openConnections(); + }); + })); + + it('should not be able to send more than 10 reqs/s', () => co(function*() { + try { + s1.bma.getDDOS().params.limit = 3; + s1.bma.getDDOS().params.burst = 3; + s1.bma.getDDOS().params.whitelist = []; + yield Array.from({ length: 4 }).map(() => s1.get('/blockchain/current')); + throw 'Wrong error thrown'; + } catch (e) { + e.should.have.property('statusCode').equal(429); + } + })); +});