Filter non global ips from discovery (#3023)

## Issue Addressed

#3006 

## Proposed Changes

This PR changes the default behaviour of lighthouse to ignore discovered IPs that are not globally routable. It adds a CLI flag, --enable-local-discovery to permit the non-global IPs in discovery.

NOTE: We should take care in merging this as I will break current set-ups that rely on local IP discovery. I made this the non-default behaviour because we dont really want to be wasting resources attempting to connect to non-routable addresses and we dont want to propagate these to others (on the chance we can connect to one of these local nodes), improving discoveries efficiency.
This commit is contained in:
Age Manning 2022-03-02 03:14:27 +00:00
parent 668115a4b8
commit f3c1dde898
6 changed files with 40 additions and 0 deletions

View File

@ -176,6 +176,7 @@ impl Default for Config {
.filter_rate_limiter(filter_rate_limiter)
.filter_max_bans_per_ip(Some(5))
.filter_max_nodes_per_ip(Some(10))
.table_filter(|enr| enr.ip().map_or(false, |ip| is_global(&ip))) // Filter non-global IPs
.ban_duration(Some(Duration::from_secs(3600)))
.ping_interval(Duration::from_secs(300))
.build();
@ -347,3 +348,28 @@ pub fn gossipsub_config(network_load: u8, fork_context: Arc<ForkContext>) -> Gos
.build()
.expect("valid gossipsub configuration")
}
/// Helper function to determine if the IpAddr is a global address or not. The `is_global()`
/// function is not yet stable on IpAddr.
#[allow(clippy::nonminimal_bool)]
fn is_global(addr: &std::net::Ipv4Addr) -> bool {
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
// globally routable addresses in the 192.0.0.0/24 range.
if u32::from_be_bytes(addr.octets()) == 0xc0000009
|| u32::from_be_bytes(addr.octets()) == 0xc000000a
{
return true;
}
!addr.is_private()
&& !addr.is_loopback()
&& !addr.is_link_local()
&& !addr.is_broadcast()
&& !addr.is_documentation()
// shared
&& !(addr.octets()[0] == 100 && (addr.octets()[1] & 0b1100_0000 == 0b0100_0000)) &&!(addr.octets()[0] & 240 == 240 && !addr.is_broadcast())
// addresses reserved for future protocols (`192.0.0.0/24`)
// reserved
&& !(addr.octets()[0] == 192 && addr.octets()[1] == 0 && addr.octets()[2] == 0)
// Make sure the address is not in 0.0.0.0/8
&& addr.octets()[0] != 0
}

View File

@ -59,6 +59,7 @@ mod tests {
);
let mut config = NetworkConfig::default();
config.discv5_config.table_filter = |_| true; // Do not ignore local IPs
config.libp2p_port = 21212;
config.upnp_enabled = false;
config.discovery_port = 21212;

View File

@ -187,6 +187,12 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
.help("One or more comma-delimited trusted peer ids which always have the highest score according to the peer scoring system.")
.takes_value(true),
)
.arg(
Arg::with_name("enable-private-discovery")
.long("enable-private-discovery")
.help("Lighthouse by default does not discover private IP addresses. Set this flag to enable connection attempts to local addresses.")
.takes_value(false),
)
/* REST API related arguments */
.arg(
Arg::with_name("http")

View File

@ -765,6 +765,10 @@ pub fn set_network_config(
config.metrics_enabled = true;
}
if cli_args.is_present("enable-private-discovery") {
config.discv5_config.table_filter = |_| true;
}
Ok(())
}

View File

@ -46,6 +46,7 @@ exec lighthouse \
$SUBSCRIBE_ALL_SUBNETS \
--datadir $data_dir \
--testnet-dir $TESTNET_DIR \
--enable-private-discovery \
--staking \
--enr-address 127.0.0.1 \
--enr-udp-port $network_port \

View File

@ -55,6 +55,7 @@ impl<E: EthSpec> LocalNetwork<E> {
beacon_config.network.libp2p_port = BOOTNODE_PORT;
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT);
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT);
beacon_config.network.discv5_config.table_filter = |_| true;
let beacon_node =
LocalBeaconNode::production(context.service_context("boot_node".into()), beacon_config)
.await?;
@ -103,6 +104,7 @@ impl<E: EthSpec> LocalNetwork<E> {
beacon_config.network.libp2p_port = BOOTNODE_PORT + count;
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT + count);
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT + count);
beacon_config.network.discv5_config.table_filter = |_| true;
}
let mut write_lock = self_1.beacon_nodes.write();