summaryrefslogtreecommitdiffhomepage
path: root/talpid-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'talpid-core/src')
-rw-r--r--talpid-core/src/firewall/linux.rs49
-rw-r--r--talpid-core/src/firewall/mod.rs10
2 files changed, 58 insertions, 1 deletions
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs
index 232252fd69..a1bb4cc635 100644
--- a/talpid-core/src/firewall/linux.rs
+++ b/talpid-core/src/firewall/linux.rs
@@ -4,7 +4,8 @@ use ipnetwork::IpNetwork;
use lazy_static::lazy_static;
use libc;
use nftnl::{
- expr::{self, Verdict},
+ self,
+ expr::{self, Payload, Verdict},
nft_expr, table, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table,
};
use std::{
@@ -274,6 +275,52 @@ impl<'a> PolicyBatch<'a> {
add_verdict(&mut in_v6, &Verdict::Accept);
self.batch.add(&in_v6, nftnl::MsgType::Add);
}
+ // Outgoing Router solicitation (part of NDP)
+ {
+ let mut rule = Rule::new(&self.out_chain);
+
+ check_ip(
+ &mut rule,
+ End::Dst,
+ *super::ROUTER_SOLICITATION_OUT_DST_ADDR,
+ );
+
+ rule.add_expr(&nft_expr!(meta l4proto));
+ rule.add_expr(&nft_expr!(cmp == libc::IPPROTO_ICMPV6 as u8));
+
+ rule.add_expr(&Payload::Transport(
+ nftnl::expr::TransportHeaderField::Icmpv6(nftnl::expr::Icmpv6HeaderField::Type),
+ ));
+ rule.add_expr(&nft_expr!(cmp == 133u8));
+ rule.add_expr(&nftnl::expr::Payload::Transport(
+ nftnl::expr::TransportHeaderField::Icmpv6(nftnl::expr::Icmpv6HeaderField::Code),
+ ));
+ rule.add_expr(&nft_expr!(cmp == 0u8));
+
+ add_verdict(&mut rule, &Verdict::Accept);
+ self.batch.add(&rule, nftnl::MsgType::Add);
+ }
+ // Incoming Router advertisement (part of NDP)
+ {
+ let mut rule = Rule::new(&self.in_chain);
+
+ check_net(&mut rule, End::Src, *super::ROUTER_ADVERTISEMENT_IN_SRC_NET);
+
+ rule.add_expr(&nft_expr!(meta l4proto));
+ rule.add_expr(&nft_expr!(cmp == libc::IPPROTO_ICMPV6 as u8));
+
+ rule.add_expr(&Payload::Transport(
+ nftnl::expr::TransportHeaderField::Icmpv6(nftnl::expr::Icmpv6HeaderField::Type),
+ ));
+ rule.add_expr(&nft_expr!(cmp == 134u8));
+ rule.add_expr(&nftnl::expr::Payload::Transport(
+ nftnl::expr::TransportHeaderField::Icmpv6(nftnl::expr::Icmpv6HeaderField::Code),
+ ));
+ rule.add_expr(&nft_expr!(cmp == 0u8));
+
+ add_verdict(&mut rule, &Verdict::Accept);
+ self.batch.add(&rule, nftnl::MsgType::Add);
+ }
}
fn add_policy_specific_rules(&mut self, policy: &FirewallPolicy) -> Result<()> {
diff --git a/talpid-core/src/firewall/mod.rs b/talpid-core/src/firewall/mod.rs
index d52e3ce9b5..2315c6ccc3 100644
--- a/talpid-core/src/firewall/mod.rs
+++ b/talpid-core/src/firewall/mod.rs
@@ -50,13 +50,23 @@ lazy_static! {
// Site-local IPv6 multicast.
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 0), 16).unwrap()),
];
+ // The firewall should always allow DHCPv6 to enable automatic configuring of network adapters
+ /// The allowed source address of outbound DHCPv6 requests
static ref DHCPV6_SRC_ADDR: Ipv6Network = Ipv6Network::new(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0), 10).unwrap();
+ /// The allowed target addresses of outbound DHCPv6 requests
static ref DHCPV6_SERVER_ADDRS: [Ipv6Addr; 2] = [
Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 1, 2),
Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 1, 3),
];
+ // The firewall needs to always allow Router Solicitation/Advertisement (part of NDP)
+ // It should only allow ICMPv6 packets on these addresses. If the platform supports it
+ // it should check that the solicitation packet has ICMP type 133, code 0 for solicitation
+ // and type 134, code 0 for advertisement.
+ static ref ROUTER_SOLICITATION_OUT_DST_ADDR: Ipv6Addr = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 2);
+ static ref ROUTER_ADVERTISEMENT_IN_SRC_NET: Ipv6Network = Ipv6Network::new(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0), 10).unwrap();
}
+
/// A enum that describes network security strategy
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum FirewallPolicy {