summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2019-05-07 15:24:32 +0200
committerLinus Färnstrand <linus@mullvad.net>2019-05-08 14:12:32 +0200
commit9efcd31574d18c34d9baff593c6364c314237ef5 (patch)
tree19c75819c5875e206593a8e4bdc51111b5ceee35
parent6bb9c4335919530b90a5be86d5321b355f591bbd (diff)
downloadmullvadvpn-9efcd31574d18c34d9baff593c6364c314237ef5.tar.xz
mullvadvpn-9efcd31574d18c34d9baff593c6364c314237ef5.zip
Add router solicitation/advertisement rules to Linux
-rw-r--r--Cargo.lock17
-rw-r--r--talpid-core/Cargo.toml2
-rw-r--r--talpid-core/src/firewall/linux.rs49
-rw-r--r--talpid-core/src/firewall/mod.rs10
4 files changed, 68 insertions, 10 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 94e2e8b782..99dcef5a24 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1254,21 +1254,22 @@ dependencies = [
[[package]]
name = "nftnl"
-version = "0.1.0"
-source = "git+https://github.com/mullvad/nftnl-rs?rev=29651f4370fdf22cc2e3abf5097a51f8ff17e3a3#29651f4370fdf22cc2e3abf5097a51f8ff17e3a3"
+version = "0.2.0"
+source = "git+https://github.com/mullvad/nftnl-rs?rev=86b30cdc38a6d4b30a900c21f7c644857d6f7401#86b30cdc38a6d4b30a900c21f7c644857d6f7401"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "nftnl-sys 0.1.0 (git+https://github.com/mullvad/nftnl-rs?rev=29651f4370fdf22cc2e3abf5097a51f8ff17e3a3)",
+ "nftnl-sys 0.2.0 (git+https://github.com/mullvad/nftnl-rs?rev=86b30cdc38a6d4b30a900c21f7c644857d6f7401)",
]
[[package]]
name = "nftnl-sys"
-version = "0.1.0"
-source = "git+https://github.com/mullvad/nftnl-rs?rev=29651f4370fdf22cc2e3abf5097a51f8ff17e3a3#29651f4370fdf22cc2e3abf5097a51f8ff17e3a3"
+version = "0.2.0"
+source = "git+https://github.com/mullvad/nftnl-rs?rev=86b30cdc38a6d4b30a900c21f7c644857d6f7401#86b30cdc38a6d4b30a900c21f7c644857d6f7401"
dependencies = [
+ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1996,7 +1997,7 @@ dependencies = [
"netlink-proto 0.1.1 (git+https://github.com/mullvad/netlink?branch=hack-older-kernel-compat)",
"netlink-socket 0.0.2 (git+https://github.com/mullvad/netlink?branch=ignore-hw-address)",
"netlink-sys 0.1.0 (git+https://github.com/mullvad/netlink?branch=hack-older-kernel-compat)",
- "nftnl 0.1.0 (git+https://github.com/mullvad/nftnl-rs?rev=29651f4370fdf22cc2e3abf5097a51f8ff17e3a3)",
+ "nftnl 0.2.0 (git+https://github.com/mullvad/nftnl-rs?rev=86b30cdc38a6d4b30a900c21f7c644857d6f7401)",
"nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"openvpn-plugin 0.3.0 (git+https://github.com/mullvad/openvpn-plugin-rs?branch=auth-failed-event)",
@@ -2726,8 +2727,8 @@ dependencies = [
"checksum netlink-proto 0.1.1 (git+https://github.com/mullvad/netlink?branch=hack-older-kernel-compat)" = "<none>"
"checksum netlink-socket 0.0.2 (git+https://github.com/mullvad/netlink?branch=ignore-hw-address)" = "<none>"
"checksum netlink-sys 0.1.0 (git+https://github.com/mullvad/netlink?branch=hack-older-kernel-compat)" = "<none>"
-"checksum nftnl 0.1.0 (git+https://github.com/mullvad/nftnl-rs?rev=29651f4370fdf22cc2e3abf5097a51f8ff17e3a3)" = "<none>"
-"checksum nftnl-sys 0.1.0 (git+https://github.com/mullvad/nftnl-rs?rev=29651f4370fdf22cc2e3abf5097a51f8ff17e3a3)" = "<none>"
+"checksum nftnl 0.2.0 (git+https://github.com/mullvad/nftnl-rs?rev=86b30cdc38a6d4b30a900c21f7c644857d6f7401)" = "<none>"
+"checksum nftnl-sys 0.2.0 (git+https://github.com/mullvad/nftnl-rs?rev=86b30cdc38a6d4b30a900c21f7c644857d6f7401)" = "<none>"
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml
index c2fd7b90bc..982b1d500d 100644
--- a/talpid-core/Cargo.toml
+++ b/talpid-core/Cargo.toml
@@ -44,7 +44,7 @@ rtnetlink = { git = "https://github.com/mullvad/netlink", branch = "hack-older-k
netlink-proto = { git = "https://github.com/mullvad/netlink", branch = "hack-older-kernel-compat" }
netlink-packet = { git = "https://github.com/mullvad/netlink", branch = "hack-older-kernel-compat" }
netlink-sys = { git = "https://github.com/mullvad/netlink", branch = "hack-older-kernel-compat" }
-nftnl = { git = "https://github.com/mullvad/nftnl-rs", rev = "29651f4370fdf22cc2e3abf5097a51f8ff17e3a3", features = ["nftnl-1-1-0"] }
+nftnl = { git = "https://github.com/mullvad/nftnl-rs", rev = "86b30cdc38a6d4b30a900c21f7c644857d6f7401", features = ["nftnl-1-1-0"] }
mnl = { git = "https://github.com/mullvad/mnl-rs", rev = "f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6", features = ["mnl-1-0-4"] }
which = "2.0"
err-derive = "0.1.5"
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 {