From 2e1652d77200fe95eb00b25d6f1d4ae26bedfd17 Mon Sep 17 00:00:00 2001 From: prathamesh0 <42446521+prathamesh0@users.noreply.github.com> Date: Thu, 4 May 2023 16:33:29 +0530 Subject: [PATCH] Block connections with blacklisted multiaddrs (#373) * Block connections from blacklisted multiaddrs in relay node * Block connections from blacklisted multiaddrs in peer nodes * Block dials for blacklisted multiaddrs * Update package version --- lerna.json | 2 +- packages/cache/package.json | 2 +- packages/cli/package.json | 6 ++--- packages/cli/src/peer.ts | 22 +++++++++++++++++++ packages/cli/src/server.ts | 2 ++ packages/codegen/package.json | 4 ++-- .../src/templates/package-template.handlebars | 10 ++++----- packages/graph-node/package.json | 10 ++++----- packages/ipld-eth-client/package.json | 4 ++-- packages/peer/package.json | 2 +- packages/peer/src/cli/relay.ts | 20 +++++++++++++++++ packages/peer/src/peer.ts | 11 +++++++++- packages/peer/src/relay.ts | 15 +++++++++---- packages/peer/src/utils/index.ts | 11 ++++++++++ packages/solidity-mapper/package.json | 4 ++-- packages/test/package.json | 2 +- packages/tracing-client/package.json | 2 +- packages/util/package.json | 8 +++---- packages/util/src/config.ts | 6 +++++ 19 files changed, 110 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 1908dec8..20c0681e 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "0.2.40", + "version": "0.2.41", "npmClient": "yarn", "useWorkspaces": true, "command": { diff --git a/packages/cache/package.json b/packages/cache/package.json index 65ab0905..af61cf7d 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/cache", - "version": "0.2.40", + "version": "0.2.41", "description": "Generic object cache", "main": "dist/index.js", "scripts": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 08df74ba..d1b5ba78 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/cli", - "version": "0.2.40", + "version": "0.2.41", "main": "dist/index.js", "license": "AGPL-3.0", "scripts": { @@ -11,8 +11,8 @@ "chat": "DEBUG='vulcanize:*, laconic:*' node dist/chat.js" }, "dependencies": { - "@cerc-io/peer": "^0.2.40", - "@cerc-io/util": "^0.2.40", + "@cerc-io/peer": "^0.2.41", + "@cerc-io/util": "^0.2.41", "@ethersproject/providers": "^5.4.4", "@graphql-tools/utils": "^9.1.1", "@ipld/dag-cbor": "^8.0.0", diff --git a/packages/cli/src/peer.ts b/packages/cli/src/peer.ts index f32fe709..45e3fb0d 100644 --- a/packages/cli/src/peer.ts +++ b/packages/cli/src/peer.ts @@ -6,6 +6,8 @@ import { hideBin } from 'yargs/helpers'; import yargs from 'yargs'; import debug from 'debug'; +import fs from 'fs'; +import path from 'path'; import { PeerInitConfig, @@ -19,6 +21,7 @@ const log = debug('vulcanize:peer'); interface Arguments { relayMultiaddr: string; + denyMultiaddrs?: string; maxConnections: number; dialTimeout: number; maxRelayConnections: number; @@ -38,7 +41,22 @@ export class PeerCmd { peerIdObj = readPeerId(argv.peerIdFile); } + let denyMultiaddrsList: string[] = []; + if (argv.denyMultiaddrs) { + const denyMultiaddrsFilePath = path.resolve(argv.denyMultiaddrs); + + if (!fs.existsSync(denyMultiaddrsFilePath)) { + console.log(`File at given path ${denyMultiaddrsFilePath} not found, exiting`); + process.exit(); + } + + console.log(`Reading blacklisted multiaddr(s) from file ${denyMultiaddrsFilePath}`); + const denyMultiaddrsListObj = fs.readFileSync(denyMultiaddrsFilePath, 'utf-8'); + denyMultiaddrsList = JSON.parse(denyMultiaddrsListObj); + } + const peerNodeInit: PeerInitConfig = { + denyMultiaddrs: denyMultiaddrsList, maxConnections: argv.maxConnections, dialTimeout: argv.dialTimeout, maxRelayConnections: argv.maxRelayConnections, @@ -73,6 +91,10 @@ function _getArgv (): any { describe: 'Multiaddr of the primary relay node for this peer', demandOption: true }, + denyMultiaddrs: { + type: 'string', + describe: 'Blacklisted multiaddr(s) list file path (json)' + }, maxConnections: { type: 'number', describe: 'Max number of connections for a peer' diff --git a/packages/cli/src/server.ts b/packages/cli/src/server.ts index bfe06ee5..7130fb82 100644 --- a/packages/cli/src/server.ts +++ b/packages/cli/src/server.ts @@ -173,6 +173,7 @@ export class ServerCmd { port: relayConfig.port ?? RELAY_DEFAULT_PORT, announceDomain: relayConfig.announce, relayPeers: relayConfig.relayPeers ?? [], + denyMultiaddrs: relayConfig.denyMultiaddrs ?? [], dialTimeout: relayConfig.dialTimeout ?? DIAL_TIMEOUT, pingInterval: relayConfig.pingInterval ?? DEFAULT_PING_INTERVAL, redialInterval: relayConfig.redialInterval ?? RELAY_REDIAL_INTERVAL, @@ -198,6 +199,7 @@ export class ServerCmd { const peerNodeInit: PeerInitConfig = { pingInterval: peerConfig.pingInterval, pingTimeout: peerConfig.pingTimeout, + denyMultiaddrs: peerConfig.denyMultiaddrs, maxRelayConnections: peerConfig.maxRelayConnections, relayRedialInterval: peerConfig.relayRedialInterval, maxConnections: peerConfig.maxConnections, diff --git a/packages/codegen/package.json b/packages/codegen/package.json index 590fbe0f..5c51d4d6 100644 --- a/packages/codegen/package.json +++ b/packages/codegen/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/codegen", - "version": "0.2.40", + "version": "0.2.41", "description": "Code generator", "private": true, "main": "index.js", @@ -20,7 +20,7 @@ }, "homepage": "https://github.com/cerc-io/watcher-ts#readme", "dependencies": { - "@cerc-io/util": "^0.2.40", + "@cerc-io/util": "^0.2.41", "@graphql-tools/load-files": "^6.5.2", "@poanet/solidity-flattener": "https://github.com/vulcanize/solidity-flattener.git", "@solidity-parser/parser": "^0.13.2", diff --git a/packages/codegen/src/templates/package-template.handlebars b/packages/codegen/src/templates/package-template.handlebars index bf7a9705..cb0d2373 100644 --- a/packages/codegen/src/templates/package-template.handlebars +++ b/packages/codegen/src/templates/package-template.handlebars @@ -42,12 +42,12 @@ "dependencies": { "@apollo/client": "^3.3.19", "@ethersproject/providers": "^5.4.4", - "@cerc-io/cli": "^0.2.40", - "@cerc-io/ipld-eth-client": "^0.2.40", - "@cerc-io/solidity-mapper": "^0.2.40", - "@cerc-io/util": "^0.2.40", + "@cerc-io/cli": "^0.2.41", + "@cerc-io/ipld-eth-client": "^0.2.41", + "@cerc-io/solidity-mapper": "^0.2.41", + "@cerc-io/util": "^0.2.41", {{#if (subgraphPath)}} - "@cerc-io/graph-node": "^0.2.40", + "@cerc-io/graph-node": "^0.2.41", {{/if}} "apollo-type-bigint": "^0.1.3", "debug": "^4.3.1", diff --git a/packages/graph-node/package.json b/packages/graph-node/package.json index 2156a935..cb3730b5 100644 --- a/packages/graph-node/package.json +++ b/packages/graph-node/package.json @@ -1,10 +1,10 @@ { "name": "@cerc-io/graph-node", - "version": "0.2.40", + "version": "0.2.41", "main": "dist/index.js", "license": "AGPL-3.0", "devDependencies": { - "@cerc-io/solidity-mapper": "^0.2.40", + "@cerc-io/solidity-mapper": "^0.2.41", "@ethersproject/providers": "^5.4.4", "@graphprotocol/graph-ts": "^0.22.0", "@nomiclabs/hardhat-ethers": "^2.0.2", @@ -51,9 +51,9 @@ "dependencies": { "@apollo/client": "^3.3.19", "@cerc-io/assemblyscript": "0.19.10-watcher-ts-0.1.2", - "@cerc-io/cache": "^0.2.40", - "@cerc-io/ipld-eth-client": "^0.2.40", - "@cerc-io/util": "^0.2.40", + "@cerc-io/cache": "^0.2.41", + "@cerc-io/ipld-eth-client": "^0.2.41", + "@cerc-io/util": "^0.2.41", "@types/json-diff": "^0.5.2", "@types/yargs": "^17.0.0", "bn.js": "^4.11.9", diff --git a/packages/ipld-eth-client/package.json b/packages/ipld-eth-client/package.json index c44ab26a..5c9bbcd1 100644 --- a/packages/ipld-eth-client/package.json +++ b/packages/ipld-eth-client/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/ipld-eth-client", - "version": "0.2.40", + "version": "0.2.41", "description": "IPLD ETH Client", "main": "dist/index.js", "scripts": { @@ -20,7 +20,7 @@ "homepage": "https://github.com/cerc-io/watcher-ts#readme", "dependencies": { "@apollo/client": "^3.7.1", - "@cerc-io/cache": "^0.2.40", + "@cerc-io/cache": "^0.2.41", "cross-fetch": "^3.1.4", "debug": "^4.3.1", "ethers": "^5.4.4", diff --git a/packages/peer/package.json b/packages/peer/package.json index 400c45e0..44e8d97a 100644 --- a/packages/peer/package.json +++ b/packages/peer/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/peer", - "version": "0.2.40", + "version": "0.2.41", "description": "libp2p module", "main": "dist/index.js", "exports": "./dist/index.js", diff --git a/packages/peer/src/cli/relay.ts b/packages/peer/src/cli/relay.ts index 00702f13..9ade76ce 100644 --- a/packages/peer/src/cli/relay.ts +++ b/packages/peer/src/cli/relay.ts @@ -20,6 +20,7 @@ interface Arguments { announce?: string; peerIdFile?: string; relayPeers?: string; + denyMultiaddrs?: string; dialTimeout: number; pingInterval: number; redialInterval: number; @@ -31,6 +32,7 @@ async function main (): Promise { const argv: Arguments = _getArgv(); let peerIdObj: PeerIdObj | undefined; let relayPeersList: string[] = []; + let denyMultiaddrsList: string[] = []; if (argv.peerIdFile) { const peerIdFilePath = path.resolve(argv.peerIdFile); @@ -55,12 +57,26 @@ async function main (): Promise { relayPeersList = JSON.parse(relayPeersListObj); } + if (argv.denyMultiaddrs) { + const denyMultiaddrsFilePath = path.resolve(argv.denyMultiaddrs); + + if (!fs.existsSync(denyMultiaddrsFilePath)) { + console.log(`File at given path ${denyMultiaddrsFilePath} not found, exiting`); + process.exit(); + } + + console.log(`Reading blacklisted multiaddr(s) from file ${denyMultiaddrsFilePath}`); + const denyMultiaddrsListObj = fs.readFileSync(denyMultiaddrsFilePath, 'utf-8'); + denyMultiaddrsList = JSON.parse(denyMultiaddrsListObj); + } + const relayNodeInit: RelayNodeInitConfig = { host: argv.host, port: argv.port, peerIdObj, announceDomain: argv.announce, relayPeers: relayPeersList, + denyMultiaddrs: denyMultiaddrsList, dialTimeout: argv.dialTimeout, pingInterval: argv.pingInterval, redialInterval: argv.redialInterval, @@ -101,6 +117,10 @@ function _getArgv (): Arguments { alias: 'r', describe: 'Relay peer multiaddr(s) list file path (json)' }, + denyMultiaddrs: { + type: 'string', + describe: 'Blacklisted multiaddr(s) list file path (json)' + }, pingInterval: { type: 'number', describe: 'Interval to check relay peer connections using ping (ms)', diff --git a/packages/peer/src/peer.ts b/packages/peer/src/peer.ts index 608e1694..b1a4d102 100644 --- a/packages/peer/src/peer.ts +++ b/packages/peer/src/peer.ts @@ -43,7 +43,7 @@ import { P2P_WEBRTC_STAR_ID } from './constants.js'; import { PeerHearbeatChecker } from './peer-heartbeat-checker.js'; -import { debugInfoRequestHandler, dialWithRetry, getConnectionsInfo, getPseudonymForPeerId, getSelfInfo, wsPeerFilter } from './utils/index.js'; +import { debugInfoRequestHandler, dialWithRetry, getConnectionsInfo, getPseudonymForPeerId, getSelfInfo, isMultiaddrBlacklisted, wsPeerFilter } from './utils/index.js'; import { ConnectionType, DebugPeerInfo, DebugRequest, PeerConnectionInfo, PeerSelfInfo } from './types/debug-info.js'; const log = debug('laconic:peer'); @@ -62,6 +62,7 @@ export interface PeerInitConfig { pingTimeout?: number; maxRelayConnections?: number; relayRedialInterval?: number; + denyMultiaddrs?: string[]; maxConnections?: number; minConnections?: number; dialTimeout?: number; @@ -78,6 +79,7 @@ export class Peer { _relayRedialInterval?: number; _maxRelayConnections?: number; + _denyMultiaddrs?: string[]; _debugInfoEnabled?: boolean; @@ -114,6 +116,7 @@ export class Peer { async init (initOptions: PeerInitConfig, peerIdObj?: PeerIdObj): Promise { this._relayRedialInterval = initOptions.relayRedialInterval; + this._denyMultiaddrs = initOptions.denyMultiaddrs; this._maxRelayConnections = initOptions.maxRelayConnections; this._debugInfoEnabled = initOptions.enableDebugInfo; const pingTimeout = initOptions.pingTimeout ?? DEFAULT_PING_TIMEOUT; @@ -164,6 +167,7 @@ export class Peer { connectionManager: { maxDialsPerPeer: MAX_CONCURRENT_DIALS_PER_PEER, autoDial: false, + deny: initOptions.denyMultiaddrs, maxConnections: initOptions.maxConnections ?? MAX_CONNECTIONS, minConnections: initOptions.minConnections ?? MIN_CONNECTIONS, dialTimeout: initOptions.dialTimeout ?? DIAL_TIMEOUT, @@ -467,6 +471,11 @@ export class Peer { let isRelayPeer = false; for (const multiaddr of peer.multiaddrs) { + if (isMultiaddrBlacklisted(this._denyMultiaddrs ?? [], multiaddr)) { + log(`Ignoring blacklisted node with multiaddr ${multiaddr.toString()}`); + return; + } + if (this.isRelayPeerMultiaddr(multiaddr.toString())) { isRelayPeer = true; break; diff --git a/packages/peer/src/relay.ts b/packages/peer/src/relay.ts index 52d57649..c1a254a1 100644 --- a/packages/peer/src/relay.ts +++ b/packages/peer/src/relay.ts @@ -28,7 +28,7 @@ import { DEBUG_INFO_TOPIC } from './constants.js'; import { PeerHearbeatChecker } from './peer-heartbeat-checker.js'; -import { debugInfoRequestHandler, dialWithRetry, getConnectionsInfo, getPseudonymForPeerId, getSelfInfo } from './utils/index.js'; +import { debugInfoRequestHandler, dialWithRetry, getConnectionsInfo, getPseudonymForPeerId, getSelfInfo, isMultiaddrBlacklisted } from './utils/index.js'; import { PeerIdObj } from './peer.js'; import { SelfInfo, ConnectionInfo } from './types/debug-info.js'; @@ -40,6 +40,7 @@ export interface RelayNodeInitConfig { peerIdObj?: PeerIdObj; announceDomain?: string; relayPeers: string[]; + denyMultiaddrs: string[]; dialTimeout: number; pingInterval: number; pingTimeout?: number; @@ -94,7 +95,8 @@ export async function createRelayNode (init: RelayNodeInitConfig): Promise { +async function _dialRelayPeers (node: Libp2p, relayPeersList: string[], denyMultiaddrs: string[], maxDialRetry: number, redialInterval: number): Promise { relayPeersList.forEach(async (relayPeer) => { const relayMultiaddr = multiaddr(relayPeer); + if (isMultiaddrBlacklisted(denyMultiaddrs, relayMultiaddr)) { + log(`Ignoring blacklisted node with multiaddr ${relayMultiaddr.toString()}`); + return; + } + await dialWithRetry( node, relayMultiaddr, diff --git a/packages/peer/src/utils/index.ts b/packages/peer/src/utils/index.ts index 079df0d9..fb1e023e 100644 --- a/packages/peer/src/utils/index.ts +++ b/packages/peer/src/utils/index.ts @@ -84,6 +84,17 @@ export const getPseudonymForPeerId = (peerId: string): string => { }); }; +/** + * Method to check if the given multiaddr is part of a blacklist + * @param blacklist + * @param multiaddr + */ +export const isMultiaddrBlacklisted = (blacklist: string[], multiaddr: Multiaddr): boolean => { + return blacklist.some(maString => { + return multiaddr.toString().startsWith(maString); + }); +}; + /** * Handler for pubsub debug info request * @param peerId diff --git a/packages/solidity-mapper/package.json b/packages/solidity-mapper/package.json index b425f33d..70056a1c 100644 --- a/packages/solidity-mapper/package.json +++ b/packages/solidity-mapper/package.json @@ -1,10 +1,10 @@ { "name": "@cerc-io/solidity-mapper", - "version": "0.2.40", + "version": "0.2.41", "main": "dist/index.js", "license": "AGPL-3.0", "devDependencies": { - "@cerc-io/ipld-eth-client": "^0.2.40", + "@cerc-io/ipld-eth-client": "^0.2.41", "@ethersproject/abi": "^5.3.0", "@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-waffle": "^2.0.1", diff --git a/packages/test/package.json b/packages/test/package.json index df72d018..bccd6bcc 100644 --- a/packages/test/package.json +++ b/packages/test/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/test", - "version": "0.2.40", + "version": "0.2.41", "main": "dist/index.js", "license": "AGPL-3.0", "private": true, diff --git a/packages/tracing-client/package.json b/packages/tracing-client/package.json index 3c254f6e..dbf56fd2 100644 --- a/packages/tracing-client/package.json +++ b/packages/tracing-client/package.json @@ -1,6 +1,6 @@ { "name": "@cerc-io/tracing-client", - "version": "0.2.40", + "version": "0.2.41", "description": "ETH VM tracing client", "main": "dist/index.js", "scripts": { diff --git a/packages/util/package.json b/packages/util/package.json index d21a59ec..6aaec2e2 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,11 +1,11 @@ { "name": "@cerc-io/util", - "version": "0.2.40", + "version": "0.2.41", "main": "dist/index.js", "license": "AGPL-3.0", "dependencies": { "@apollo/utils.keyvaluecache": "^1.0.1", - "@cerc-io/solidity-mapper": "^0.2.40", + "@cerc-io/solidity-mapper": "^0.2.41", "@ethersproject/providers": "^5.4.4", "@graphql-tools/schema": "^9.0.10", "@graphql-tools/utils": "^9.1.1", @@ -37,8 +37,8 @@ "yargs": "^17.0.1" }, "devDependencies": { - "@cerc-io/cache": "^0.2.40", - "@cerc-io/ipld-eth-client": "^0.2.40", + "@cerc-io/cache": "^0.2.41", + "@cerc-io/ipld-eth-client": "^0.2.41", "@nomiclabs/hardhat-waffle": "^2.0.1", "@types/express": "^4.17.14", "@types/fs-extra": "^9.0.11", diff --git a/packages/util/src/config.ts b/packages/util/src/config.ts index e8adf44d..01bd4e82 100644 --- a/packages/util/src/config.ts +++ b/packages/util/src/config.ts @@ -53,6 +53,9 @@ export interface RelayConfig { // Relay peer multiaddr(s) list relayPeers?: string[]; + // Blacklisted multiaddr(s) list + denyMultiaddrs?: string[]; + // Timeout (ms) for dial to relay peers dialTimeout?: number; @@ -101,6 +104,9 @@ export interface PeerConfig { // Redial interval (ms) to relay node on connection failure relayRedialInterval?: number; + // Blacklisted multiaddr(s) list + denyMultiaddrs?: string[]; + // Max number of connections for a peer maxConnections?: number;