diff --git a/doc/api/net.md b/doc/api/net.md index 7d8a27bf0b1769..513c405d80e66d 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -1713,6 +1713,11 @@ 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. This does not + work if the server is behind a reverse proxy, NAT, etc. because the address + checked against the block list is the address of the proxy, or the one + specified by the NAT. * `connectionListener` {Function} Automatically set as a listener for the [`'connection'`][] event. diff --git a/lib/net.js b/lib/net.js index 52085df6ba0574..ae4d536cd9840b 100644 --- a/lib/net.js +++ b/lib/net.js @@ -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); @@ -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, diff --git a/test/parallel/test-net-server-blocklist.js b/test/parallel/test-net-server-blocklist.js new file mode 100644 index 00000000000000..8f310bd6253039 --- /dev/null +++ b/test/parallel/test-net-server-blocklist.js @@ -0,0 +1,19 @@ +'use strict'; +const common = require('../common'); +const net = require('net'); + +const blockList = new net.BlockList(); +blockList.addAddress(common.localhostIPv4); + +const server = net.createServer({ blockList }, common.mustNotCall()); +server.listen(0, common.localhostIPv4, common.mustCall(() => { + const adddress = server.address(); + const socket = net.connect({ + localAddress: common.localhostIPv4, + host: adddress.address, + port: adddress.port + }); + socket.on('close', common.mustCall(() => { + server.close(); + })); +}));