Skip to content

Commit

Permalink
Merge pull request #529 from NordSecurity/LLT-4749_modify_incoming_fi…
Browse files Browse the repository at this point in the history
…rewall_logic

LLT 4749 Modify incoming firewall logic
  • Loading branch information
Hasan6979 authored Dec 13, 2024
2 parents a47c971 + 5b2e675 commit a2e7ab8
Show file tree
Hide file tree
Showing 27 changed files with 1,363 additions and 418 deletions.
1 change: 1 addition & 0 deletions .unreleased/LLT-4749
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Modify incoming firewall handler
5 changes: 5 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ telio-proxy = { workspace = true, features = ["mockall"] }
telio-pq = { workspace = true, features = ["mockall"] }
telio-test.workspace = true
telio-traversal = { workspace = true, features = ["mockall"] }
telio-utils.workspace = true
telio-wg = { workspace = true, features = ["mockall", "test-adapter"] }

[build-dependencies]
Expand Down
7 changes: 5 additions & 2 deletions crates/telio-firewall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,19 @@ publish = false
test_utils = [] # For use in benchmarks to avoid duplication of the 'setup' code needed to create buffers with valid packets

[dependencies]
enum-map = "2.7.3"
hashlink.workspace = true
if-addrs.workspace = true
ipnet.workspace = true
tracing.workspace = true
mockall = { workspace = true, optional = true }
pnet_packet.workspace = true
rustc-hash.workspace = true

telio-crypto.workspace = true
telio-utils.workspace = true
telio-model.workspace = true
telio-network-monitors.workspace = true

[dev-dependencies]
criterion = "0.5.1"
Expand All @@ -28,8 +33,6 @@ proptest-derive.workspace = true
rand.workspace = true
sn_fake_clock.workspace = true

telio-utils = { workspace = true, features = ["sn_fake_clock"] }

[[bench]]
name = "firewall_bench"
harness = false
163 changes: 142 additions & 21 deletions crates/telio-firewall/benches/firewall_bench.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use std::fmt::{Debug, Display, Formatter};
use std::net::SocketAddr;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use std::ops::Deref;
use std::rc::Rc;

use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use pnet_packet::tcp::TcpFlags;
use telio_crypto::SecretKey;
use telio_firewall::firewall::tests::{make_tcp, make_tcp6, make_udp, make_udp6};
use telio_firewall::firewall::{Firewall, StatefullFirewall};
use telio_firewall::firewall::{Firewall, Permissions, StatefullFirewall};
use telio_model::features::FeatureFirewall;

const PEER_COUNTS: [usize; 8] = [0, 1, 2, 4, 8, 16, 32, 64]; // max 60 peers: https://meshnet.nordvpn.com/getting-started/meshnet-explained#meshnet-scalability
const PACKET_COUNT: u64 = 100_000;
Expand Down Expand Up @@ -90,10 +91,17 @@ pub fn firewall_tcp_inbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
firewall.set_ip_addresses(vec![
(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
]);
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
firewall.add_to_peer_whitelist(public_key);
firewall.add_to_peer_whitelist(
public_key,
Permissions::IncomingConnections,
);
firewall.add_to_port_whitelist(public_key, 42);
}
let other_peer_pk1 = SecretKey::gen().public();
Expand Down Expand Up @@ -127,11 +135,18 @@ pub fn firewall_tcp_inbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
firewall.set_ip_addresses(vec![
(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
]);
let mut peers = vec![];
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
firewall.add_to_peer_whitelist(public_key);
firewall.add_to_peer_whitelist(
public_key,
Permissions::IncomingConnections,
);
peers.push(public_key.0);
}
let mut which_peer = 0usize;
Expand Down Expand Up @@ -162,7 +177,11 @@ pub fn firewall_tcp_inbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
firewall.set_ip_addresses(vec![
(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
]);
let mut peers_and_packets = vec![];
let port_base = 1111;
for i in 0..param.peers {
Expand Down Expand Up @@ -191,6 +210,42 @@ pub fn firewall_tcp_inbound_benchmarks(c: &mut Criterion) {
}
}
}

{
let mut group = c.benchmark_group("process inbound tcp from vpn peer packet - accepted");
for packet in &packets {
for peers in PEER_COUNTS[1..].iter().copied() {
group.throughput(criterion::Throughput::Elements(PACKET_COUNT));
let parameter = Parameter {
peers,
packet: packet.clone(),
};
group.bench_with_input(
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
firewall.set_ip_addresses(vec![
(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
]);

let public_key = SecretKey::gen().public();
firewall.add_vpn_peer(public_key);

b.iter(|| {
for _ in 0..PACKET_COUNT {
assert!(
firewall.process_inbound_packet(&public_key.0, &param.packet)
);
}
assert_eq!((0, 0), firewall.get_state());
});
},
);
}
}
}
}

pub fn firewall_tcp_outbound_benchmarks(c: &mut Criterion) {
Expand All @@ -215,10 +270,13 @@ pub fn firewall_tcp_outbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
firewall.add_to_peer_whitelist(public_key);
firewall.add_to_peer_whitelist(
public_key,
Permissions::IncomingConnections,
);
firewall.add_to_port_whitelist(public_key, 42);
}
let peer_pk1 = SecretKey::gen().public();
Expand Down Expand Up @@ -257,10 +315,13 @@ pub fn firewall_tcp_outbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
firewall.add_to_peer_whitelist(public_key);
firewall.add_to_peer_whitelist(
public_key,
Permissions::IncomingConnections,
);
}
let other_peer_pk1 = SecretKey::gen().public();
let other_peer_pk2 = SecretKey::gen().public();
Expand Down Expand Up @@ -292,11 +353,14 @@ pub fn firewall_tcp_outbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
let mut peers = vec![];
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
firewall.add_to_peer_whitelist(public_key);
firewall.add_to_peer_whitelist(
public_key,
Permissions::IncomingConnections,
);
peers.push(public_key.0);
}
let mut which_peer = 0usize;
Expand Down Expand Up @@ -332,10 +396,17 @@ pub fn firewall_udp_inbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
firewall.set_ip_addresses(vec![
(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
]);
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
firewall.add_to_peer_whitelist(public_key);
firewall.add_to_peer_whitelist(
public_key,
Permissions::IncomingConnections,
);
firewall.add_to_port_whitelist(public_key, 42);
}
let other_peer_pk1 = SecretKey::gen().public();
Expand Down Expand Up @@ -369,11 +440,18 @@ pub fn firewall_udp_inbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
firewall.set_ip_addresses(vec![
(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
]);
let mut peers = vec![];
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
firewall.add_to_peer_whitelist(public_key);
firewall.add_to_peer_whitelist(
public_key,
Permissions::IncomingConnections,
);
peers.push(public_key.0);
}
let mut which_peer = 0usize;
Expand Down Expand Up @@ -404,7 +482,11 @@ pub fn firewall_udp_inbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
firewall.set_ip_addresses(vec![
(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
]);
let mut peers_and_packets = vec![];
let port_base = 42;
for i in 0..param.peers {
Expand Down Expand Up @@ -433,6 +515,42 @@ pub fn firewall_udp_inbound_benchmarks(c: &mut Criterion) {
}
}
}

{
let mut group = c.benchmark_group("process inbound udp from vpn peer packet - accepted");
for packet in &packets {
for peers in PEER_COUNTS[1..].iter().copied() {
group.throughput(criterion::Throughput::Elements(PACKET_COUNT));
let parameter = Parameter {
peers,
packet: packet.clone(),
};
group.bench_with_input(
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
firewall.set_ip_addresses(vec![
(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
]);

let public_key = SecretKey::gen().public();
firewall.add_vpn_peer(public_key);

b.iter(|| {
for _ in 0..PACKET_COUNT {
assert!(
firewall.process_inbound_packet(&public_key.0, &param.packet)
);
}
assert_eq!((0, 0), firewall.get_state());
});
},
);
}
}
}
}

pub fn firewall_udp_outbound_benchmarks(c: &mut Criterion) {
Expand All @@ -453,11 +571,14 @@ pub fn firewall_udp_outbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
let mut peers = vec![];
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
firewall.add_to_peer_whitelist(public_key);
firewall.add_to_peer_whitelist(
public_key,
Permissions::IncomingConnections,
);
peers.push(public_key.0);
}
let mut which_peer = 0usize;
Expand Down Expand Up @@ -487,7 +608,7 @@ pub fn firewall_udp_outbound_benchmarks(c: &mut Criterion) {
BenchmarkId::from_parameter(parameter.clone()),
&parameter,
|b, param| {
let firewall = StatefullFirewall::new(true, false);
let firewall = StatefullFirewall::new(true, FeatureFirewall::default());
let mut peers = vec![];
for _ in 0..param.peers {
let public_key = SecretKey::gen().public();
Expand Down
Loading

0 comments on commit a2e7ab8

Please sign in to comment.