Skip to content

Commit

Permalink
net: support blocklist for net.Server
Browse files Browse the repository at this point in the history
  • Loading branch information
theanarkh committed Nov 29, 2024
1 parent 4cf6fab commit 83871b6
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
3 changes: 3 additions & 0 deletions doc/api/net.md
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,9 @@ changes:
**Default:** `false`.
* `pauseOnConnect` {boolean} Indicates whether the socket should be
paused on incoming connections. **Default:** `false`.
* `blocklist` {net.BlockList} `blocklist` can be used for disabling inbound
access to specific IP addresses, IP ranges, or IP subnets. The IP is the
peer address of the accepted TCP socket, such as browser, reverse proxy.

* `connectionListener` {Function} Automatically set as a listener for the
[`'connection'`][] event.
Expand Down
17 changes: 16 additions & 1 deletion lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,13 @@ function Server(options, connectionListener) {
this.keepAlive = Boolean(options.keepAlive);
this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000);
this.highWaterMark = options.highWaterMark ?? getDefaultHighWaterMark();
if (options.blocklist) {
// TODO: use BlockList.isBlockList (https://github.com/nodejs/node/pull/56078)
if (!(options.blocklist instanceof module.exports.BlockList)) {
throw new ERR_INVALID_ARG_TYPE('options.blocklist', 'net.BlockList', options.blocklist);
}
this.blocklist = options.blocklist;
}
}
ObjectSetPrototypeOf(Server.prototype, EventEmitter.prototype);
ObjectSetPrototypeOf(Server, EventEmitter);
Expand Down Expand Up @@ -2239,7 +2246,15 @@ function onconnection(err, clientHandle) {
clientHandle.close();
return;
}

if (self.blocklist && typeof clientHandle.getpeername === 'function') {
const remoteInfo = { __proto__: null };
clientHandle.getpeername(remoteInfo);
const addressType = isIP(remoteInfo.address);
if (addressType && self.blocklist.check(remoteInfo.address, `ipv${addressType}`)) {
clientHandle.close();
return;
}
}
const socket = new Socket({
handle: clientHandle,
allowHalfOpen: self.allowHalfOpen,
Expand Down
19 changes: 19 additions & 0 deletions test/parallel/test-net-server-blocklist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

Check failure on line 1 in test/parallel/test-net-server-blocklist.js

View workflow job for this annotation

GitHub Actions / test-linux

--- stderr --- node:events:491 throw er; // Unhandled 'error' event ^ Error: bind EINVAL 127.0.0.1 at internalConnect (node:net:1066:18) at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18) at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1410:9) at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:111:8) Emitted 'error' event on Socket instance at: at emitErrorNT (node:internal/streams/destroy:170:8) at emitErrorCloseNT (node:internal/streams/destroy:129:3) at process.processTicksAndRejections (node:internal/process/task_queues:90:21) { errno: -22, code: 'EINVAL', syscall: 'bind', address: '127.0.0.1' } Node.js v24.0.0-pre Command: out/Release/node --test-reporter=spec --test-reporter-destination=stdout --test-reporter=./tools/github_reporter/index.js --test-reporter-destination=stdout /home/runner/work/node/node/test/parallel/test-net-server-blocklist.js

Check failure on line 1 in test/parallel/test-net-server-blocklist.js

View workflow job for this annotation

GitHub Actions / test-macOS

--- stderr --- node:events:491 throw er; // Unhandled 'error' event ^ Error: bind EINVAL 127.0.0.1 at internalConnect (node:net:1066:18) at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18) at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1410:9) at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:111:8) Emitted 'error' event on Socket instance at: at emitErrorNT (node:internal/streams/destroy:170:8) at emitErrorCloseNT (node:internal/streams/destroy:129:3) at process.processTicksAndRejections (node:internal/process/task_queues:90:21) { errno: -22, code: 'EINVAL', syscall: 'bind', address: '127.0.0.1' } Node.js v24.0.0-pre Command: out/Release/node --test-reporter=spec --test-reporter-destination=stdout --test-reporter=./tools/github_reporter/index.js --test-reporter-destination=stdout /Users/runner/work/node/node/test/parallel/test-net-server-blocklist.js
const common = require('../common');
const net = require('net');

const blocklist = new net.BlockList();
blocklist.addAddress('127.0.0.1');

const server = net.createServer({ blocklist }, common.mustNotCall());
server.listen(0, common.mustCall(() => {
const adddress = server.address();
const socket = net.connect({
localAddress: '127.0.0.1',
host: adddress.host,
port: adddress.port
});
socket.on('close', common.mustCall(() => {
server.close();
}));
}));

0 comments on commit 83871b6

Please sign in to comment.