From 94cf3d9bdef9d6c74ed46ef207d3c9dbfad8987f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 12 Apr 2020 14:54:25 +0200 Subject: [PATCH] src/exporter/client: Don't attempt connecting to local ip addresses --- Cargo.lock | 1 + Cargo.toml | 1 + Dockerfile | 4 +-- src/exporter/client.rs | 8 ++++- src/exporter/client/global_only.rs | 56 ++++++++++++++++++++++++++++++ src/main.rs | 2 ++ 6 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/exporter/client/global_only.rs diff --git a/Cargo.lock b/Cargo.lock index 671ec83..60f13a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1190,6 +1190,7 @@ dependencies = [ "futures-timer 3.0.2", "libp2p", "libp2p-kad", + "log", "prometheus", "structopt", "tide", diff --git a/Cargo.toml b/Cargo.toml index 747cd20..83c187f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ env_logger = "0.7.1" futures = "0.3.1" libp2p = "0.18.0" libp2p-kad = "0.18.0" +log = "0.4.1" prometheus = "0.7" void = "1.0.2" tide = "0.6" diff --git a/Dockerfile b/Dockerfile index 77fb568..af214c9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ # Build container -FROM rust as build +FROM rustlang/rust:nightly as build COPY ./ ./ -RUN cargo build --release +RUN cargo +nightly build --release RUN mkdir -p /build-out diff --git a/src/exporter/client.rs b/src/exporter/client.rs index 029ea07..378266a 100644 --- a/src/exporter/client.rs +++ b/src/exporter/client.rs @@ -24,6 +24,8 @@ use std::{ usize, }; +mod global_only; + const RANDOM_WALK_INTERVAL: Duration = Duration::from_secs(10); pub struct Client { @@ -173,7 +175,11 @@ impl NetworkBehaviourEventProcess for MyBehaviour { fn build_transport(keypair: Keypair) -> Boxed<(PeerId, StreamMuxerBox), impl Error> { let tcp = tcp::TcpConfig::new().nodelay(true); - let transport = dns::DnsConfig::new(tcp).unwrap(); + // Ignore any non global IP addresses. Given the amount of private IP + // addresses in most Dhts dialing private IP addresses can easily be (and + // has been) interpreted as a port-scan by ones hosting provider. + let global_only_tcp = global_only::GlobalIpOnly::new(tcp); + let transport = dns::DnsConfig::new(global_only_tcp).unwrap(); let noise_keypair = noise::Keypair::new().into_authentic(&keypair).unwrap(); let noise_config = noise::NoiseConfig::ix(noise_keypair); diff --git a/src/exporter/client/global_only.rs b/src/exporter/client/global_only.rs new file mode 100644 index 0000000..65bb7d4 --- /dev/null +++ b/src/exporter/client/global_only.rs @@ -0,0 +1,56 @@ +use libp2p::core::{ + multiaddr::{Multiaddr, Protocol}, + transport::TransportError, + Transport, +}; +use log::warn; + +// Wrapper around a libp2p `Transport` dropping all dial requests to non-global +// IP addresses. +#[derive(Debug, Clone, Default)] +pub struct GlobalIpOnly { + inner: T, +} + +impl GlobalIpOnly { + pub fn new(transport: T) -> Self { + GlobalIpOnly { inner: transport } + } +} + +impl Transport for GlobalIpOnly { + type Output = ::Output; + type Error = ::Error; + type Listener = ::Listener; + type ListenerUpgrade = ::ListenerUpgrade; + type Dial = ::Dial; + + fn listen_on(self, addr: Multiaddr) -> Result> { + self.inner.listen_on(addr) + } + + fn dial(self, addr: Multiaddr) -> Result> { + match addr.iter().next() { + Some(Protocol::Ip4(a)) => { + if a.is_global() { + return self.inner.dial(addr); + } else { + warn!("Not dialing non global IP address {:?}.", a); + return Err(TransportError::MultiaddrNotSupported(addr)); + } + } + Some(Protocol::Ip6(a)) => { + if a.is_global() { + return self.inner.dial(addr); + } else { + warn!("Not dialing non global IP address {:?}.", a); + return Err(TransportError::MultiaddrNotSupported(addr)); + } + } + _ => { + warn!("Not dialing unsupported Multiaddress {:?}.", addr); + return Err(TransportError::MultiaddrNotSupported(addr)); + } + } + } +} diff --git a/src/main.rs b/src/main.rs index ed21944..d1c8f2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +#![feature(ip)] + use async_std::task; use libp2p::core::Multiaddr; use prometheus::{Encoder, Registry, TextEncoder};