From 947c6ef11c568a9d15380037d69164124f749b5e Mon Sep 17 00:00:00 2001 From: Max <82761650+MaxMustermann2@users.noreply.github.com> Date: Wed, 11 May 2022 05:15:13 +0000 Subject: [PATCH] [p2p]: feat: allow disable scan of private ips (#4151) * [p2p]: feat: allow disable scan of private ips Add a command line flag `--p2p.no-private-ip-scan` or config file option in P2P `DisablePrivateIPScan` to stop node operators from receiving netscan abuse emails. Fixes #4036, #4046 and #3788. After this change, node operators should not need to use `iptables` to firewall out RFC1918 traffic. * [p2p] fix: Cascade disallow private scan --- cmd/harmony/config_migrations.go | 9 +++++ cmd/harmony/default.go | 13 +++---- cmd/harmony/flags.go | 10 ++++++ cmd/harmony/flags_test.go | 53 ++++++++++++++++++----------- cmd/harmony/main.go | 13 +++---- internal/configs/harmony/harmony.go | 13 +++---- p2p/discovery/option.go | 14 ++++++-- p2p/host.go | 20 ++++++----- rosetta/infra/harmony-mainnet.conf | 3 +- rosetta/infra/harmony-pstn.conf | 3 +- 10 files changed, 100 insertions(+), 51 deletions(-) diff --git a/cmd/harmony/config_migrations.go b/cmd/harmony/config_migrations.go index e273dcfbb..815373705 100644 --- a/cmd/harmony/config_migrations.go +++ b/cmd/harmony/config_migrations.go @@ -229,4 +229,13 @@ func init() { confTree.Set("Version", "2.5.1") return confTree } + + migrations["2.5.1"] = func(confTree *toml.Tree) *toml.Tree { + if confTree.Get("P2P.DisablePrivateIPScan") == nil { + confTree.Set("P2P.DisablePrivateIPScan", defaultConfig.P2P.DisablePrivateIPScan) + } + + confTree.Set("Version", "2.5.2") + return confTree + } } diff --git a/cmd/harmony/default.go b/cmd/harmony/default.go index aced45267..7b8a838d7 100644 --- a/cmd/harmony/default.go +++ b/cmd/harmony/default.go @@ -5,7 +5,7 @@ import ( nodeconfig "github.com/harmony-one/harmony/internal/configs/node" ) -const tomlConfigVersion = "2.5.1" // bump from 2.5.0 for AccountSlots +const tomlConfigVersion = "2.5.2" // bump from 2.5.1 for DisablePrivateIPScan const ( defNetworkType = nodeconfig.Mainnet @@ -25,11 +25,12 @@ var defaultConfig = harmonyconfig.HarmonyConfig{ }, Network: getDefaultNetworkConfig(defNetworkType), P2P: harmonyconfig.P2pConfig{ - Port: nodeconfig.DefaultP2PPort, - IP: nodeconfig.DefaultPublicListenIP, - KeyFile: "./.hmykey", - DiscConcurrency: nodeconfig.DefaultP2PConcurrency, - MaxConnsPerIP: nodeconfig.DefaultMaxConnPerIP, + Port: nodeconfig.DefaultP2PPort, + IP: nodeconfig.DefaultPublicListenIP, + KeyFile: "./.hmykey", + DiscConcurrency: nodeconfig.DefaultP2PConcurrency, + MaxConnsPerIP: nodeconfig.DefaultMaxConnPerIP, + DisablePrivateIPScan: false, }, HTTP: harmonyconfig.HttpConfig{ Enabled: true, diff --git a/cmd/harmony/flags.go b/cmd/harmony/flags.go index 1550cab17..0151c1533 100644 --- a/cmd/harmony/flags.go +++ b/cmd/harmony/flags.go @@ -60,6 +60,7 @@ var ( p2pDHTDataStoreFlag, p2pDiscoveryConcurrencyFlag, legacyKeyFileFlag, + p2pDisablePrivateIPScanFlag, maxConnPerIPFlag, } @@ -551,6 +552,11 @@ var ( Usage: "the pubsub's DHT discovery concurrency num (default with raw libp2p dht option)", DefValue: defaultConfig.P2P.DiscConcurrency, } + p2pDisablePrivateIPScanFlag = cli.BoolFlag{ + Name: "p2p.no-private-ip-scan", + Usage: "disable scanning of private ip4/6 addresses by DHT", + DefValue: defaultConfig.P2P.DisablePrivateIPScan, + } maxConnPerIPFlag = cli.IntFlag{ Name: "p2p.security.max-conn-per-ip", Usage: "maximum number of connections allowed per node", @@ -587,6 +593,10 @@ func applyP2PFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) { if cli.IsFlagChanged(cmd, maxConnPerIPFlag) { config.P2P.MaxConnsPerIP = cli.GetIntFlagValue(cmd, maxConnPerIPFlag) } + + if cli.IsFlagChanged(cmd, p2pDisablePrivateIPScanFlag) { + config.P2P.DisablePrivateIPScan = cli.GetBoolFlagValue(cmd, p2pDisablePrivateIPScanFlag) + } } // http flags diff --git a/cmd/harmony/flags_test.go b/cmd/harmony/flags_test.go index ad686d162..2f755cee5 100644 --- a/cmd/harmony/flags_test.go +++ b/cmd/harmony/flags_test.go @@ -58,11 +58,12 @@ func TestHarmonyFlags(t *testing.T) { ServerPort: nodeconfig.DefaultDNSPort, }, P2P: harmonyconfig.P2pConfig{ - Port: 9000, - IP: defaultConfig.P2P.IP, - KeyFile: defaultConfig.P2P.KeyFile, - DiscConcurrency: 5, - MaxConnsPerIP: 5, + Port: 9000, + IP: defaultConfig.P2P.IP, + KeyFile: defaultConfig.P2P.KeyFile, + DiscConcurrency: 5, + MaxConnsPerIP: 5, + DisablePrivateIPScan: false, }, HTTP: harmonyconfig.HttpConfig{ Enabled: true, @@ -375,30 +376,44 @@ func TestP2PFlags(t *testing.T) { args: []string{"--p2p.port", "9001", "--p2p.keyfile", "./key.file", "--p2p.dht.datastore", defDataStore}, expConfig: harmonyconfig.P2pConfig{ - Port: 9001, - IP: nodeconfig.DefaultPublicListenIP, - KeyFile: "./key.file", - DHTDataStore: &defDataStore, - MaxConnsPerIP: 10, + Port: 9001, + IP: nodeconfig.DefaultPublicListenIP, + KeyFile: "./key.file", + DHTDataStore: &defDataStore, + MaxConnsPerIP: 10, + DisablePrivateIPScan: false, }, }, { args: []string{"--port", "9001", "--key", "./key.file"}, expConfig: harmonyconfig.P2pConfig{ - Port: 9001, - IP: nodeconfig.DefaultPublicListenIP, - KeyFile: "./key.file", - MaxConnsPerIP: 10, + Port: 9001, + IP: nodeconfig.DefaultPublicListenIP, + KeyFile: "./key.file", + MaxConnsPerIP: 10, + DisablePrivateIPScan: false, }, }, { args: []string{"--p2p.port", "9001", "--p2p.disc.concurrency", "5", "--p2p.security.max-conn-per-ip", "5"}, expConfig: harmonyconfig.P2pConfig{ - Port: 9001, - IP: nodeconfig.DefaultPublicListenIP, - KeyFile: "./.hmykey", - DiscConcurrency: 5, - MaxConnsPerIP: 5, + Port: 9001, + IP: nodeconfig.DefaultPublicListenIP, + KeyFile: "./.hmykey", + DiscConcurrency: 5, + MaxConnsPerIP: 5, + DisablePrivateIPScan: false, + }, + }, + { + args: []string{"--p2p.no-private-ip-scan"}, + expConfig: harmonyconfig.P2pConfig{ + Port: nodeconfig.DefaultP2PPort, + IP: nodeconfig.DefaultPublicListenIP, + KeyFile: "./.hmykey", + DiscConcurrency: nodeconfig.DefaultP2PConcurrency, + MaxConnsPerIP: nodeconfig.DefaultMaxConnPerIP, + DisablePrivateIPScan: true, }, }, } diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 3ff3cbd69..3b034e7f6 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -594,12 +594,13 @@ func createGlobalConfig(hc harmonyconfig.HarmonyConfig) (*nodeconfig.ConfigType, ConsensusPubKey: nodeConfig.ConsensusPriKey[0].Pub.Object, } myHost, err = p2p.NewHost(p2p.HostConfig{ - Self: &selfPeer, - BLSKey: nodeConfig.P2PPriKey, - BootNodes: hc.Network.BootNodes, - DataStoreFile: hc.P2P.DHTDataStore, - DiscConcurrency: hc.P2P.DiscConcurrency, - MaxConnPerIP: hc.P2P.MaxConnsPerIP, + Self: &selfPeer, + BLSKey: nodeConfig.P2PPriKey, + BootNodes: hc.Network.BootNodes, + DataStoreFile: hc.P2P.DHTDataStore, + DiscConcurrency: hc.P2P.DiscConcurrency, + MaxConnPerIP: hc.P2P.MaxConnsPerIP, + DisablePrivateIPScan: hc.P2P.DisablePrivateIPScan, }) if err != nil { return nil, errors.Wrap(err, "cannot create P2P network host") diff --git a/internal/configs/harmony/harmony.go b/internal/configs/harmony/harmony.go index 2889f9dcf..55b70e787 100644 --- a/internal/configs/harmony/harmony.go +++ b/internal/configs/harmony/harmony.go @@ -46,12 +46,13 @@ type NetworkConfig struct { } type P2pConfig struct { - Port int - IP string - KeyFile string - DHTDataStore *string `toml:",omitempty"` - DiscConcurrency int // Discovery Concurrency value - MaxConnsPerIP int + Port int + IP string + KeyFile string + DHTDataStore *string `toml:",omitempty"` + DiscConcurrency int // Discovery Concurrency value + MaxConnsPerIP int + DisablePrivateIPScan bool } type GeneralConfig struct { diff --git a/p2p/discovery/option.go b/p2p/discovery/option.go index 0afe6b8a2..cbadf5eae 100644 --- a/p2p/discovery/option.go +++ b/p2p/discovery/option.go @@ -11,9 +11,10 @@ import ( // DHTConfig is the configurable DHT options. // For normal nodes, only BootNodes field need to be specified. type DHTConfig struct { - BootNodes []string - DataStoreFile *string // File path to store DHT data. Shall be only used for bootstrap nodes. - DiscConcurrency int + BootNodes []string + DataStoreFile *string // File path to store DHT data. Shall be only used for bootstrap nodes. + DiscConcurrency int + DisablePrivateIPScan bool } // getLibp2pRawOptions get the raw libp2p options as a slice. @@ -40,6 +41,13 @@ func (opt DHTConfig) getLibp2pRawOptions() ([]libp2p_dht.Option, error) { opts = append(opts, libp2p_dht.Concurrency(opt.DiscConcurrency)) } + if opt.DisablePrivateIPScan { + // QueryFilter sets a function that approves which peers may be dialed in a query + // PublicQueryFilter returns true if the peer is suspected of being publicly accessible + // includes RFC1918 + some other ranges + a stricter definition for IPv6 + opts = append(opts, libp2p_dht.QueryFilter(libp2p_dht.PublicQueryFilter)) + } + return opts, nil } diff --git a/p2p/host.go b/p2p/host.go index 6895978c7..1db22e92d 100644 --- a/p2p/host.go +++ b/p2p/host.go @@ -80,12 +80,13 @@ const ( // HostConfig is the config structure to create a new host type HostConfig struct { - Self *Peer - BLSKey libp2p_crypto.PrivKey - BootNodes []string - DataStoreFile *string - DiscConcurrency int - MaxConnPerIP int + Self *Peer + BLSKey libp2p_crypto.PrivKey + BootNodes []string + DataStoreFile *string + DiscConcurrency int + MaxConnPerIP int + DisablePrivateIPScan bool } // NewHost .. @@ -114,9 +115,10 @@ func NewHost(cfg HostConfig) (Host, error) { } disc, err := discovery.NewDHTDiscovery(p2pHost, discovery.DHTConfig{ - BootNodes: cfg.BootNodes, - DataStoreFile: cfg.DataStoreFile, - DiscConcurrency: cfg.DiscConcurrency, + BootNodes: cfg.BootNodes, + DataStoreFile: cfg.DataStoreFile, + DiscConcurrency: cfg.DiscConcurrency, + DisablePrivateIPScan: cfg.DisablePrivateIPScan, }) if err != nil { cancel() diff --git a/rosetta/infra/harmony-mainnet.conf b/rosetta/infra/harmony-mainnet.conf index 13a593a6e..535e3c65f 100644 --- a/rosetta/infra/harmony-mainnet.conf +++ b/rosetta/infra/harmony-mainnet.conf @@ -1,4 +1,4 @@ -Version = "2.5.1" +Version = "2.5.2" [BLSKeys] KMSConfigFile = "" @@ -62,6 +62,7 @@ Version = "2.5.1" KeyFile = "./.hmykey" MaxConnsPerIP = 10 Port = 9000 + DisablePrivateIPScan = false [Pprof] Enabled = false diff --git a/rosetta/infra/harmony-pstn.conf b/rosetta/infra/harmony-pstn.conf index 70c706ba6..8adf2d071 100644 --- a/rosetta/infra/harmony-pstn.conf +++ b/rosetta/infra/harmony-pstn.conf @@ -1,4 +1,4 @@ -Version = "2.5.1" +Version = "2.5.2" [BLSKeys] KMSConfigFile = "" @@ -62,6 +62,7 @@ Version = "2.5.1" KeyFile = "./.hmykey" MaxConnsPerIP = 10 Port = 9000 + DisablePrivateIPScan = false [Pprof] Enabled = false