Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Refactor --allow-ips to handle custom ip-ranges (#6144)
Browse files Browse the repository at this point in the history
* Add checks for additional reserved ip addresses

100.64.0.0/10 and 240.0.0.0/4 are both reserved but not currently
filtered.

* Add check for special purpose addresses

192.0.0.0/24 - Used for the IANA IPv4 Special Purpose Address Registry

* Refactor ip_utils (#5872)

* Add checks for all ipv4 special use addresses
* Add comprehensive ipv4 test cases

* Refactor Ipv6 address checks (#5872)

* Refactor AllowIP (#5872)

* Add IpFilter struct to wrap predefined filter (AllowIP) with custom
allow/block filters.
* Refactor parsing of --allow-ips to handle custom filters.
* Move AllowIP/IpFilter from ethsync to ethcore-network where they
are used.

* Revert Cargo.lock

* Tests for custom ip filters (#5872)

* Add "none" as a valid argument for --allow-ips to allow narrow
custom ranges, eg.: --allow-ips="none 10.0.0.0/8"
* Add tests for parsing filter arguments and node endpoints.
* Add ipnetwork crate to dev dependencies for testing.

* Add ipv6 filter tests (#5872)

* Revert parity-ui-precompiled to master

* Fix minor detail in usage.txt (#5872)

* Spaces to tabs

* Rename IpFilter::new() to ::default()

* Small readability improvements

* Test (#5872)

* Revert "Test (#5872)"

This reverts commit 7a89064.
  • Loading branch information
Joseph Mark authored and gavofyork committed Jul 28, 2017
1 parent ad30a68 commit b5f1524
Show file tree
Hide file tree
Showing 15 changed files with 507 additions and 110 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
ethcore-light = { path = "ethcore/light" }
ethcore-logger = { path = "logger" }
ethcore-stratum = { path = "stratum" }
ethcore-network = { path = "util/network" }
ethkey = { path = "ethkey" }
rlp = { path = "util/rlp" }
rpc-cli = { path = "rpc_cli" }
Expand All @@ -65,6 +66,7 @@ rustc_version = "0.2"
[dev-dependencies]
ethcore-ipc-tests = { path = "ipc/tests" }
pretty_assertions = "0.1"
ipnetwork = "0.12.6"

[target.'cfg(windows)'.dependencies]
winapi = "0.2"
Expand Down
10 changes: 7 additions & 3 deletions parity/cli/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,15 @@ Networking Options:
These nodes will always have a reserved slot on top
of the normal maximum peers. (default: {flag_reserved_peers:?})
--reserved-only Connect only to reserved nodes. (default: {flag_reserved_only})
--allow-ips FILTER Filter outbound connections. Must be one of:
--allow-ips FILTER Filter outbound connections. FILTER can be one of:
private - connect to private network IP addresses only;
public - connect to public network IP addresses only;
all - connect to any IP address.
(default: {flag_allow_ips})
all - connect to any IP address;
none - block all (for use with a custom filter as below);
a custom filter list in the format: "private ip_range1 -ip_range2 ...".
Where ip_range1 would be allowed and ip_range2 blocked;
Custom blocks ("-ip_range") override custom allows ("ip_range");
(default: {flag_allow_ips}).
--max-pending-peers NUM Allow up to NUM pending connections. (default: {flag_max_pending_peers})
--no-ancient-blocks Disable downloading old blocks after snapshot restoration
or warp sync. (default: {flag_no_ancient_blocks})
Expand Down
68 changes: 59 additions & 9 deletions parity/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use cli::{Args, ArgsError};
use util::{Hashable, H256, U256, Bytes, version_data, Address};
use util::journaldb::Algorithm;
use util::Colour;
use ethsync::{NetworkConfiguration, is_valid_node_url, AllowIP};
use ethsync::{NetworkConfiguration, is_valid_node_url};
use ethcore::ethstore::ethkey::{Secret, Public};
use ethcore::client::{VMType};
use ethcore::miner::{MinerOptions, Banning, StratumOptions};
Expand All @@ -48,6 +48,7 @@ use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockcha
use presale::ImportWallet;
use account::{AccountCmd, NewAccount, ListAccounts, ImportAccounts, ImportFromGethAccounts};
use snapshot::{self, SnapshotCommand};
use network::{IpFilter};

#[derive(Debug, PartialEq)]
pub enum Cmd {
Expand Down Expand Up @@ -461,12 +462,10 @@ impl Configuration {
max(self.min_peers(), peers)
}

fn allow_ips(&self) -> Result<AllowIP, String> {
match self.args.flag_allow_ips.as_str() {
"all" => Ok(AllowIP::All),
"public" => Ok(AllowIP::Public),
"private" => Ok(AllowIP::Private),
_ => Err("Invalid IP filter value".to_owned()),
fn ip_filter(&self) -> Result<IpFilter, String> {
match IpFilter::parse(self.args.flag_allow_ips.as_str()) {
Ok(allow_ip) => Ok(allow_ip),
Err(_) => Err("Invalid IP filter value".to_owned()),
}
}

Expand Down Expand Up @@ -712,7 +711,7 @@ impl Configuration {
ret.max_peers = self.max_peers();
ret.min_peers = self.min_peers();
ret.snapshot_peers = self.snapshot_peers();
ret.allow_ips = self.allow_ips()?;
ret.ip_filter = self.ip_filter()?;
ret.max_pending_peers = self.max_pending_peers();
let mut net_path = PathBuf::from(self.directories().base);
net_path.push("network");
Expand Down Expand Up @@ -968,7 +967,6 @@ impl Configuration {
}.into()
}


fn ui_interface(&self) -> String {
self.interface(&self.args.flag_ui_interface)
}
Expand Down Expand Up @@ -1080,6 +1078,7 @@ impl Configuration {
mod tests {
use std::io::Write;
use std::fs::{File, create_dir};
use std::str::FromStr;

use devtools::{RandomTempPath};
use ethcore::client::{VMType, BlockId};
Expand All @@ -1097,6 +1096,11 @@ mod tests {
use rpc::{WsConfiguration, UiConfiguration};
use run::RunCmd;

use network::{AllowIP, IpFilter};

extern crate ipnetwork;
use self::ipnetwork::IpNetwork;

use super::*;

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -1752,4 +1756,50 @@ mod tests {
assert_eq!(&conf0.ipfs_config().interface, "0.0.0.0");
assert_eq!(conf0.ipfs_config().hosts, None);
}

#[test]
fn allow_ips() {
let all = parse(&["parity", "--allow-ips", "all"]);
let private = parse(&["parity", "--allow-ips", "private"]);
let block_custom = parse(&["parity", "--allow-ips", "-10.0.0.0/8"]);
let combo = parse(&["parity", "--allow-ips", "public 10.0.0.0/8 -1.0.0.0/8"]);
let ipv6_custom_public = parse(&["parity", "--allow-ips", "public fc00::/7"]);
let ipv6_custom_private = parse(&["parity", "--allow-ips", "private -fc00::/7"]);

assert_eq!(all.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::All,
custom_allow: vec![],
custom_block: vec![],
});

assert_eq!(private.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::Private,
custom_allow: vec![],
custom_block: vec![],
});

assert_eq!(block_custom.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::All,
custom_allow: vec![],
custom_block: vec![IpNetwork::from_str("10.0.0.0/8").unwrap()],
});

assert_eq!(combo.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::Public,
custom_allow: vec![IpNetwork::from_str("10.0.0.0/8").unwrap()],
custom_block: vec![IpNetwork::from_str("1.0.0.0/8").unwrap()],
});

assert_eq!(ipv6_custom_public.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::Public,
custom_allow: vec![IpNetwork::from_str("fc00::/7").unwrap()],
custom_block: vec![],
});

assert_eq!(ipv6_custom_private.ip_filter().unwrap(), IpFilter {
predefined: AllowIP::Private,
custom_allow: vec![],
custom_block: vec![IpNetwork::from_str("fc00::/7").unwrap()],
});
}
}
5 changes: 3 additions & 2 deletions parity/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {

#[cfg(test)]
pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
use ethsync::{NetworkConfiguration, AllowIP};
use ethsync::{NetworkConfiguration};
use super::network::IpFilter;
NetworkConfiguration {
config_path: Some(replace_home(&::dir::default_data_path(), "$BASE/network")),
net_config_path: None,
Expand All @@ -206,7 +207,7 @@ pub fn default_network_config() -> ::ethsync::NetworkConfiguration {
min_peers: 25,
snapshot_peers: 0,
max_pending_peers: 64,
allow_ips: AllowIP::All,
ip_filter: IpFilter::default(),
reserved_nodes: Vec::new(),
allow_non_reserved: true,
}
Expand Down
1 change: 1 addition & 0 deletions parity/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extern crate ethcore_ipc_nano as nanoipc;
extern crate ethcore_light as light;
extern crate ethcore_logger;
extern crate ethcore_util as util;
extern crate ethcore_network as network;
extern crate ethkey;
extern crate ethsync;
extern crate panic_hook;
Expand Down
1 change: 1 addition & 0 deletions sync/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ethcore-ipc-nano = { path = "../ipc/nano" }
ethcore-devtools = { path = "../devtools" }
ethkey = { path = "../ethkey" }
parking_lot = "0.4"
ipnetwork = "0.12.6"

[features]
default = []
Expand Down
42 changes: 5 additions & 37 deletions sync/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ use std::collections::{HashMap, BTreeMap};
use std::io;
use util::Bytes;
use network::{NetworkProtocolHandler, NetworkService, NetworkContext, HostInfo, PeerId, ProtocolId,
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError,
AllowIP as NetworkAllowIP};
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError};
use util::{U256, H256, H512};
use io::{TimerToken};
use ethcore::ethstore::ethkey::Secret;
Expand All @@ -37,6 +36,7 @@ use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT};
use light::client::AsLightClient;
use light::Provider;
use light::net::{self as light_net, LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext};
use network::IpFilter;

/// Parity sync protocol
pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par";
Expand Down Expand Up @@ -539,30 +539,6 @@ impl ManageNetwork for EthSync {
}
}

/// IP fiter
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "ipc", binary)]
pub enum AllowIP {
/// Connect to any address
All,
/// Connect to private network only
Private,
/// Connect to public network only
Public,
}

impl AllowIP {
/// Attempt to parse the peer mode from a string.
pub fn parse(s: &str) -> Option<Self> {
match s {
"all" => Some(AllowIP::All),
"private" => Some(AllowIP::Private),
"public" => Some(AllowIP::Public),
_ => None,
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "ipc", binary)]
/// Network service configuration
Expand Down Expand Up @@ -598,7 +574,7 @@ pub struct NetworkConfiguration {
/// The non-reserved peer mode.
pub allow_non_reserved: bool,
/// IP Filtering
pub allow_ips: AllowIP,
pub ip_filter: IpFilter,
}

impl NetworkConfiguration {
Expand Down Expand Up @@ -629,11 +605,7 @@ impl NetworkConfiguration {
max_handshakes: self.max_pending_peers,
reserved_protocols: hash_map![WARP_SYNC_PROTOCOL_ID => self.snapshot_peers],
reserved_nodes: self.reserved_nodes,
allow_ips: match self.allow_ips {
AllowIP::All => NetworkAllowIP::All,
AllowIP::Private => NetworkAllowIP::Private,
AllowIP::Public => NetworkAllowIP::Public,
},
ip_filter: self.ip_filter,
non_reserved_mode: if self.allow_non_reserved { NonReservedPeerMode::Accept } else { NonReservedPeerMode::Deny },
})
}
Expand All @@ -656,11 +628,7 @@ impl From<BasicNetworkConfiguration> for NetworkConfiguration {
max_pending_peers: other.max_handshakes,
snapshot_peers: *other.reserved_protocols.get(&WARP_SYNC_PROTOCOL_ID).unwrap_or(&0),
reserved_nodes: other.reserved_nodes,
allow_ips: match other.allow_ips {
NetworkAllowIP::All => AllowIP::All,
NetworkAllowIP::Private => AllowIP::Private,
NetworkAllowIP::Public => AllowIP::Public,
},
ip_filter: other.ip_filter,
allow_non_reserved: match other.non_reserved_mode { NonReservedPeerMode::Accept => true, _ => false } ,
}
}
Expand Down
1 change: 1 addition & 0 deletions sync/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extern crate semver;
extern crate parking_lot;
extern crate smallvec;
extern crate rlp;
extern crate ipnetwork;

extern crate ethcore_light as light;

Expand Down
1 change: 1 addition & 0 deletions util/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ ethcrypto = { path = "../../ethcrypto" }
rlp = { path = "../rlp" }
path = { path = "../path" }
ethcore-logger = { path ="../../logger" }
ipnetwork = "0.12.6"

[features]
default = []
Expand Down
Loading

0 comments on commit b5f1524

Please sign in to comment.