[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
pull/4168/head
Max 3 years ago committed by GitHub
parent 8bb885e85b
commit 947c6ef11c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      cmd/harmony/config_migrations.go
  2. 13
      cmd/harmony/default.go
  3. 10
      cmd/harmony/flags.go
  4. 53
      cmd/harmony/flags_test.go
  5. 13
      cmd/harmony/main.go
  6. 13
      internal/configs/harmony/harmony.go
  7. 14
      p2p/discovery/option.go
  8. 20
      p2p/host.go
  9. 3
      rosetta/infra/harmony-mainnet.conf
  10. 3
      rosetta/infra/harmony-pstn.conf

@ -229,4 +229,13 @@ func init() {
confTree.Set("Version", "2.5.1") confTree.Set("Version", "2.5.1")
return confTree 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
}
} }

@ -5,7 +5,7 @@ import (
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" 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 ( const (
defNetworkType = nodeconfig.Mainnet defNetworkType = nodeconfig.Mainnet
@ -25,11 +25,12 @@ var defaultConfig = harmonyconfig.HarmonyConfig{
}, },
Network: getDefaultNetworkConfig(defNetworkType), Network: getDefaultNetworkConfig(defNetworkType),
P2P: harmonyconfig.P2pConfig{ P2P: harmonyconfig.P2pConfig{
Port: nodeconfig.DefaultP2PPort, Port: nodeconfig.DefaultP2PPort,
IP: nodeconfig.DefaultPublicListenIP, IP: nodeconfig.DefaultPublicListenIP,
KeyFile: "./.hmykey", KeyFile: "./.hmykey",
DiscConcurrency: nodeconfig.DefaultP2PConcurrency, DiscConcurrency: nodeconfig.DefaultP2PConcurrency,
MaxConnsPerIP: nodeconfig.DefaultMaxConnPerIP, MaxConnsPerIP: nodeconfig.DefaultMaxConnPerIP,
DisablePrivateIPScan: false,
}, },
HTTP: harmonyconfig.HttpConfig{ HTTP: harmonyconfig.HttpConfig{
Enabled: true, Enabled: true,

@ -60,6 +60,7 @@ var (
p2pDHTDataStoreFlag, p2pDHTDataStoreFlag,
p2pDiscoveryConcurrencyFlag, p2pDiscoveryConcurrencyFlag,
legacyKeyFileFlag, legacyKeyFileFlag,
p2pDisablePrivateIPScanFlag,
maxConnPerIPFlag, maxConnPerIPFlag,
} }
@ -551,6 +552,11 @@ var (
Usage: "the pubsub's DHT discovery concurrency num (default with raw libp2p dht option)", Usage: "the pubsub's DHT discovery concurrency num (default with raw libp2p dht option)",
DefValue: defaultConfig.P2P.DiscConcurrency, 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{ maxConnPerIPFlag = cli.IntFlag{
Name: "p2p.security.max-conn-per-ip", Name: "p2p.security.max-conn-per-ip",
Usage: "maximum number of connections allowed per node", 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) { if cli.IsFlagChanged(cmd, maxConnPerIPFlag) {
config.P2P.MaxConnsPerIP = cli.GetIntFlagValue(cmd, maxConnPerIPFlag) config.P2P.MaxConnsPerIP = cli.GetIntFlagValue(cmd, maxConnPerIPFlag)
} }
if cli.IsFlagChanged(cmd, p2pDisablePrivateIPScanFlag) {
config.P2P.DisablePrivateIPScan = cli.GetBoolFlagValue(cmd, p2pDisablePrivateIPScanFlag)
}
} }
// http flags // http flags

@ -58,11 +58,12 @@ func TestHarmonyFlags(t *testing.T) {
ServerPort: nodeconfig.DefaultDNSPort, ServerPort: nodeconfig.DefaultDNSPort,
}, },
P2P: harmonyconfig.P2pConfig{ P2P: harmonyconfig.P2pConfig{
Port: 9000, Port: 9000,
IP: defaultConfig.P2P.IP, IP: defaultConfig.P2P.IP,
KeyFile: defaultConfig.P2P.KeyFile, KeyFile: defaultConfig.P2P.KeyFile,
DiscConcurrency: 5, DiscConcurrency: 5,
MaxConnsPerIP: 5, MaxConnsPerIP: 5,
DisablePrivateIPScan: false,
}, },
HTTP: harmonyconfig.HttpConfig{ HTTP: harmonyconfig.HttpConfig{
Enabled: true, Enabled: true,
@ -375,30 +376,44 @@ func TestP2PFlags(t *testing.T) {
args: []string{"--p2p.port", "9001", "--p2p.keyfile", "./key.file", "--p2p.dht.datastore", args: []string{"--p2p.port", "9001", "--p2p.keyfile", "./key.file", "--p2p.dht.datastore",
defDataStore}, defDataStore},
expConfig: harmonyconfig.P2pConfig{ expConfig: harmonyconfig.P2pConfig{
Port: 9001, Port: 9001,
IP: nodeconfig.DefaultPublicListenIP, IP: nodeconfig.DefaultPublicListenIP,
KeyFile: "./key.file", KeyFile: "./key.file",
DHTDataStore: &defDataStore, DHTDataStore: &defDataStore,
MaxConnsPerIP: 10, MaxConnsPerIP: 10,
DisablePrivateIPScan: false,
}, },
}, },
{ {
args: []string{"--port", "9001", "--key", "./key.file"}, args: []string{"--port", "9001", "--key", "./key.file"},
expConfig: harmonyconfig.P2pConfig{ expConfig: harmonyconfig.P2pConfig{
Port: 9001, Port: 9001,
IP: nodeconfig.DefaultPublicListenIP, IP: nodeconfig.DefaultPublicListenIP,
KeyFile: "./key.file", KeyFile: "./key.file",
MaxConnsPerIP: 10, MaxConnsPerIP: 10,
DisablePrivateIPScan: false,
}, },
}, },
{ {
args: []string{"--p2p.port", "9001", "--p2p.disc.concurrency", "5", "--p2p.security.max-conn-per-ip", "5"}, args: []string{"--p2p.port", "9001", "--p2p.disc.concurrency", "5", "--p2p.security.max-conn-per-ip", "5"},
expConfig: harmonyconfig.P2pConfig{ expConfig: harmonyconfig.P2pConfig{
Port: 9001, Port: 9001,
IP: nodeconfig.DefaultPublicListenIP, IP: nodeconfig.DefaultPublicListenIP,
KeyFile: "./.hmykey", KeyFile: "./.hmykey",
DiscConcurrency: 5, DiscConcurrency: 5,
MaxConnsPerIP: 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,
}, },
}, },
} }

@ -594,12 +594,13 @@ func createGlobalConfig(hc harmonyconfig.HarmonyConfig) (*nodeconfig.ConfigType,
ConsensusPubKey: nodeConfig.ConsensusPriKey[0].Pub.Object, ConsensusPubKey: nodeConfig.ConsensusPriKey[0].Pub.Object,
} }
myHost, err = p2p.NewHost(p2p.HostConfig{ myHost, err = p2p.NewHost(p2p.HostConfig{
Self: &selfPeer, Self: &selfPeer,
BLSKey: nodeConfig.P2PPriKey, BLSKey: nodeConfig.P2PPriKey,
BootNodes: hc.Network.BootNodes, BootNodes: hc.Network.BootNodes,
DataStoreFile: hc.P2P.DHTDataStore, DataStoreFile: hc.P2P.DHTDataStore,
DiscConcurrency: hc.P2P.DiscConcurrency, DiscConcurrency: hc.P2P.DiscConcurrency,
MaxConnPerIP: hc.P2P.MaxConnsPerIP, MaxConnPerIP: hc.P2P.MaxConnsPerIP,
DisablePrivateIPScan: hc.P2P.DisablePrivateIPScan,
}) })
if err != nil { if err != nil {
return nil, errors.Wrap(err, "cannot create P2P network host") return nil, errors.Wrap(err, "cannot create P2P network host")

@ -46,12 +46,13 @@ type NetworkConfig struct {
} }
type P2pConfig struct { type P2pConfig struct {
Port int Port int
IP string IP string
KeyFile string KeyFile string
DHTDataStore *string `toml:",omitempty"` DHTDataStore *string `toml:",omitempty"`
DiscConcurrency int // Discovery Concurrency value DiscConcurrency int // Discovery Concurrency value
MaxConnsPerIP int MaxConnsPerIP int
DisablePrivateIPScan bool
} }
type GeneralConfig struct { type GeneralConfig struct {

@ -11,9 +11,10 @@ import (
// DHTConfig is the configurable DHT options. // DHTConfig is the configurable DHT options.
// For normal nodes, only BootNodes field need to be specified. // For normal nodes, only BootNodes field need to be specified.
type DHTConfig struct { type DHTConfig struct {
BootNodes []string BootNodes []string
DataStoreFile *string // File path to store DHT data. Shall be only used for bootstrap nodes. DataStoreFile *string // File path to store DHT data. Shall be only used for bootstrap nodes.
DiscConcurrency int DiscConcurrency int
DisablePrivateIPScan bool
} }
// getLibp2pRawOptions get the raw libp2p options as a slice. // 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)) 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 return opts, nil
} }

@ -80,12 +80,13 @@ const (
// HostConfig is the config structure to create a new host // HostConfig is the config structure to create a new host
type HostConfig struct { type HostConfig struct {
Self *Peer Self *Peer
BLSKey libp2p_crypto.PrivKey BLSKey libp2p_crypto.PrivKey
BootNodes []string BootNodes []string
DataStoreFile *string DataStoreFile *string
DiscConcurrency int DiscConcurrency int
MaxConnPerIP int MaxConnPerIP int
DisablePrivateIPScan bool
} }
// NewHost .. // NewHost ..
@ -114,9 +115,10 @@ func NewHost(cfg HostConfig) (Host, error) {
} }
disc, err := discovery.NewDHTDiscovery(p2pHost, discovery.DHTConfig{ disc, err := discovery.NewDHTDiscovery(p2pHost, discovery.DHTConfig{
BootNodes: cfg.BootNodes, BootNodes: cfg.BootNodes,
DataStoreFile: cfg.DataStoreFile, DataStoreFile: cfg.DataStoreFile,
DiscConcurrency: cfg.DiscConcurrency, DiscConcurrency: cfg.DiscConcurrency,
DisablePrivateIPScan: cfg.DisablePrivateIPScan,
}) })
if err != nil { if err != nil {
cancel() cancel()

@ -1,4 +1,4 @@
Version = "2.5.1" Version = "2.5.2"
[BLSKeys] [BLSKeys]
KMSConfigFile = "" KMSConfigFile = ""
@ -62,6 +62,7 @@ Version = "2.5.1"
KeyFile = "./.hmykey" KeyFile = "./.hmykey"
MaxConnsPerIP = 10 MaxConnsPerIP = 10
Port = 9000 Port = 9000
DisablePrivateIPScan = false
[Pprof] [Pprof]
Enabled = false Enabled = false

@ -1,4 +1,4 @@
Version = "2.5.1" Version = "2.5.2"
[BLSKeys] [BLSKeys]
KMSConfigFile = "" KMSConfigFile = ""
@ -62,6 +62,7 @@ Version = "2.5.1"
KeyFile = "./.hmykey" KeyFile = "./.hmykey"
MaxConnsPerIP = 10 MaxConnsPerIP = 10
Port = 9000 Port = 9000
DisablePrivateIPScan = false
[Pprof] [Pprof]
Enabled = false Enabled = false

Loading…
Cancel
Save