diff options
Diffstat (limited to 'talpid-core/src')
| -rw-r--r-- | talpid-core/src/firewall/linux.rs | 49 | ||||
| -rw-r--r-- | talpid-core/src/firewall/mod.rs | 10 |
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 { |
