diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2019-01-22 15:34:51 +0000 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2019-01-22 15:34:51 +0000 |
| commit | 676119edac59d4cb1768fa06c1948902dd520006 (patch) | |
| tree | bf1eada43754fd4326ffd98c01903f3bb95ee933 | |
| parent | caccdfa7450a7027bdc78a436d564f4399dc17b6 (diff) | |
| parent | 4983c1b49ccd92984196677a23eab4bd94ef3fbe (diff) | |
| download | mullvadvpn-676119edac59d4cb1768fa06c1948902dd520006.tar.xz mullvadvpn-676119edac59d4cb1768fa06c1948902dd520006.zip | |
Merge branch 'linux-fix-nft-on-1404'
| -rw-r--r-- | Cargo.lock | 24 | ||||
| -rw-r--r-- | talpid-core/Cargo.toml | 4 | ||||
| -rw-r--r-- | talpid-core/src/security/linux/mod.rs | 53 |
3 files changed, 61 insertions, 20 deletions
diff --git a/Cargo.lock b/Cargo.lock index e0402856c3..262b0bdd82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -975,17 +975,17 @@ dependencies = [ [[package]] name = "mnl" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/mullvad/mnl-rs?rev=f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6#f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6" dependencies = [ "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mnl-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mnl-sys 0.1.0 (git+https://github.com/mullvad/mnl-rs?rev=f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6)", ] [[package]] name = "mnl-sys" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/mullvad/mnl-rs?rev=f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6#f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6" dependencies = [ "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1175,19 +1175,19 @@ dependencies = [ [[package]] name = "nftnl" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/mullvad/nftnl-rs?rev=f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6#f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.44 (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 (registry+https://github.com/rust-lang/crates.io-index)", + "nftnl-sys 0.1.0 (git+https://github.com/mullvad/nftnl-rs?rev=f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6)", ] [[package]] name = "nftnl-sys" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/mullvad/nftnl-rs?rev=f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6#f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6" dependencies = [ "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1824,9 +1824,9 @@ dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mnl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mnl 0.1.0 (git+https://github.com/mullvad/mnl-rs?rev=f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6)", "netlink-socket 0.0.2 (git+https://github.com/mullvad/netlink?branch=best-effort-nla-parsing)", - "nftnl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nftnl 0.1.0 (git+https://github.com/mullvad/nftnl-rs?rev=f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6)", "nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "notify 4.0.6 (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)", @@ -2517,12 +2517,12 @@ dependencies = [ "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" -"checksum mnl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9ddf564b33717090dd6127325e590b13176b2346589c392a0cb274f2e5f8b8f7" -"checksum mnl-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7cb01017fef6e68b6c437aed2b7601264dc94759f4c2b41f820f13854d41b3" +"checksum mnl 0.1.0 (git+https://github.com/mullvad/mnl-rs?rev=f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6)" = "<none>" +"checksum mnl-sys 0.1.0 (git+https://github.com/mullvad/mnl-rs?rev=f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6)" = "<none>" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum netlink-socket 0.0.2 (git+https://github.com/mullvad/netlink?branch=best-effort-nla-parsing)" = "<none>" -"checksum nftnl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e05c68d4e54cf42fc4ef946a3bbe7779adfa1c1ce4868f06d0ee48479e8cba87" -"checksum nftnl-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2b00ddf077770bde037202e75296aecc5a0f94351196a5c46219c1c8c3a48c8" +"checksum nftnl 0.1.0 (git+https://github.com/mullvad/nftnl-rs?rev=f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6)" = "<none>" +"checksum nftnl-sys 0.1.0 (git+https://github.com/mullvad/nftnl-rs?rev=f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6)" = "<none>" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" "checksum nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "921f61dc817b379d0834e45d5ec45beaacfae97082090a49c2cf30dcbc30206f" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml index 4211b8dbf4..7c96a8e831 100644 --- a/talpid-core/Cargo.toml +++ b/talpid-core/Cargo.toml @@ -40,8 +40,8 @@ netlink-socket = { git = "https://github.com/mullvad/netlink", branch = "best-ef notify = "4.0" resolv-conf = "0.6.1" rtnetlink = { git = "https://github.com/mullvad/netlink", branch = "best-effort-nla-parsing" } -nftnl = { version = "0.1", features = ["nftnl-1-1-0"] } -mnl = { version = "0.1", features = ["mnl-1-0-4"] } +nftnl = { git = "https://github.com/mullvad/nftnl-rs", rev = "f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6", features = ["nftnl-1-1-0"] } +mnl = { git = "https://github.com/mullvad/mnl-rs", rev = "f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6", features = ["mnl-1-0-4"] } which = "2.0" [target.'cfg(target_os = "macos")'.dependencies] diff --git a/talpid-core/src/security/linux/mod.rs b/talpid-core/src/security/linux/mod.rs index f12bf4a803..76bfef07ac 100644 --- a/talpid-core/src/security/linux/mod.rs +++ b/talpid-core/src/security/linux/mod.rs @@ -5,12 +5,12 @@ use lazy_static::lazy_static; use libc; use nftnl::{ expr::{self, Verdict}, - nft_expr, nft_expr_bitwise, nft_expr_cmp, nft_expr_ct, nft_expr_meta, nft_expr_payload, Batch, - Chain, FinalizedBatch, ProtoFamily, Rule, Table, + nft_expr, nft_expr_bitwise, nft_expr_cmp, nft_expr_ct, nft_expr_meta, nft_expr_payload, table, + Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table, }; use std::{ env, - ffi::CString, + ffi::{CStr, CString}, io, net::{IpAddr, Ipv4Addr}, }; @@ -30,6 +30,9 @@ error_chain! { NetlinkRecvError { description("Error while reading from netlink socket") } /// Error while processing an incoming netlink message ProcessNetlinkError { description("Error while processing an incoming netlink message") } + /// Failed to verify that our tables are set. Probably means that + /// it's the host does not support nftables properly. + NetfilterTableNotSetError{ description("Failed to set firewall rules") } /// The name is not a valid Linux network interface name InvalidInterfaceName(name: String) { description("Invalid network interface name") @@ -84,7 +87,8 @@ impl NetworkSecurityT for NetworkSecurity { fn apply_policy(&mut self, policy: SecurityPolicy) -> Result<()> { let table = Table::new(&self.table_name, ProtoFamily::Inet)?; let batch = PolicyBatch::new(&table)?.finalize(&policy)?; - self.send_and_process(&batch) + self.send_and_process(&batch)?; + self.verify_tables(&[&TABLE_NAME]) } fn reset_policy(&mut self) -> Result<()> { @@ -114,9 +118,37 @@ impl NetworkSecurity { let portid = socket.portid(); let mut buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize]; - + let seq = 0; while let Some(message) = Self::socket_recv(&socket, &mut buffer[..])? { - match mnl::cb_run(message, 2, portid).chain_err(|| ErrorKind::ProcessNetlinkError)? { + match mnl::cb_run(message, seq, portid).chain_err(|| ErrorKind::ProcessNetlinkError)? { + mnl::CbResult::Stop => { + log::trace!("cb_run STOP"); + break; + } + mnl::CbResult::Ok => log::trace!("cb_run OK"), + }; + } + Ok(()) + } + + fn verify_tables(&self, expected_tables: &[&CStr]) -> Result<()> { + let socket = + mnl::Socket::new(mnl::Bus::Netfilter).chain_err(|| ErrorKind::NetlinkOpenError)?; + let portid = socket.portid(); + let seq = 0; + + let get_tables_msg = table::get_tables_nlmsg(seq);; + socket + .send(&get_tables_msg) + .chain_err(|| ErrorKind::NetlinkSendError)?; + + let mut table_set = ::std::collections::HashSet::new(); + let mut msg_buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize]; + + while let Some(message) = Self::socket_recv(&socket, &mut msg_buffer)? { + match mnl::cb_run2(message, seq, portid, table::get_tables_cb, &mut table_set) + .chain_err(|| ErrorKind::ProcessNetlinkError)? + { mnl::CbResult::Stop => { log::trace!("cb_run STOP"); break; @@ -125,6 +157,15 @@ impl NetworkSecurity { } } + for expected_table in expected_tables { + if !table_set.contains(*expected_table) { + log::error!( + "Expected '{}' netfilter table to be set, but it is not", + expected_table.to_string_lossy() + ); + bail!(ErrorKind::NetfilterTableNotSetError) + } + } Ok(()) } |
