diff --git a/Cargo.lock b/Cargo.lock index e86e28a..83c7c19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,14 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" +dependencies = [ + "memchr", +] + [[package]] name = "aho-corasick" version = "0.7.10" @@ -49,6 +58,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" +[[package]] +name = "bitflags" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" + [[package]] name = "bitflags" version = "1.2.1" @@ -127,11 +142,10 @@ dependencies = [ "anyhow", "futures", "igd", - "libc", + "iptables", "log", - "mnl", - "nftnl", "pretty_env_logger", + "regex 1.3.7", "reqwest", "serde", "serde-lexpr", @@ -163,24 +177,10 @@ dependencies = [ "atty", "humantime", "log", - "regex", + "regex 1.3.7", "termcolor", ] -[[package]] -name = "err-derive" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "rustversion", - "syn", - "synstructure", -] - [[package]] name = "fnv" version = "1.0.6" @@ -214,7 +214,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags", + "bitflags 1.2.1", "fuchsia-zircon-sys", ] @@ -509,6 +509,17 @@ dependencies = [ "libc", ] +[[package]] +name = "iptables" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7910549cb022e3112eea631a4c3e62523281b6c61024b2c3a8d61da620010de" +dependencies = [ + "lazy_static 0.2.11", + "nix", + "regex 0.2.11", +] + [[package]] name = "itoa" version = "0.4.5" @@ -534,6 +545,12 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" + [[package]] name = "lazy_static" version = "1.4.0" @@ -637,34 +654,13 @@ dependencies = [ "ws2_32-sys", ] -[[package]] -name = "mnl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6efb50a48dbacd112e7e847b9847fa530ec4a473ba6322a2f82c42ef333e226" -dependencies = [ - "libc", - "log", - "mnl-sys", -] - -[[package]] -name = "mnl-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5302035599c722b3a5b92a6502ff73c501dc6d100c53b89f0fae0cb932a37122" -dependencies = [ - "libc", - "pkg-config", -] - [[package]] name = "native-tls" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" dependencies = [ - "lazy_static", + "lazy_static 1.4.0", "libc", "log", "openssl", @@ -688,27 +684,17 @@ dependencies = [ ] [[package]] -name = "nftnl" -version = "0.3.0" +name = "nix" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3727d1e8c1c9af88857f46539c3030693158a2a7586056b8cab6ded523bf7aa" -dependencies = [ - "bitflags", - "err-derive", - "libc", - "log", - "nftnl-sys", -] - -[[package]] -name = "nftnl-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba134c9b125b7d7c13d813388aaeb2aeeba60fb1eb702799163fb845086ca33" +checksum = "a0d95c5fa8b641c10ad0b8887454ebaafa3c92b5cd5350f8fc693adafd178e7b" dependencies = [ + "bitflags 0.4.0", "cfg-if", "libc", - "pkg-config", + "rustc_version", + "semver", + "void", ] [[package]] @@ -733,10 +719,10 @@ version = "0.10.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "973293749822d7dd6370d6da1e523b0d1db19f06c459134c658b2a4261378b52" dependencies = [ - "bitflags", + "bitflags 1.2.1", "cfg-if", "foreign-types", - "lazy_static", + "lazy_static 1.4.0", "libc", "openssl-sys", ] @@ -826,32 +812,6 @@ dependencies = [ "log", ] -[[package]] -name = "proc-macro-error" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check 0.9.1", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "syn-mid", - "version_check 0.9.1", -] - [[package]] name = "proc-macro-hack" version = "0.5.11" @@ -977,16 +937,38 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +[[package]] +name = "regex" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +dependencies = [ + "aho-corasick 0.6.10", + "memchr", + "regex-syntax 0.5.6", + "thread_local 0.3.6", + "utf8-ranges", +] + [[package]] name = "regex" version = "1.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" dependencies = [ - "aho-corasick", + "aho-corasick 0.7.10", "memchr", - "regex-syntax", - "thread_local", + "regex-syntax 0.6.17", + "thread_local 1.0.1", +] + +[[package]] +name = "regex-syntax" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" +dependencies = [ + "ucd-util", ] [[package]] @@ -1020,7 +1002,7 @@ dependencies = [ "hyper", "hyper-tls", "js-sys", - "lazy_static", + "lazy_static 1.4.0", "log", "mime", "mime_guess", @@ -1041,14 +1023,12 @@ dependencies = [ ] [[package]] -name = "rustversion" -version = "1.0.2" +name = "rustc_version" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" +checksum = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" dependencies = [ - "proc-macro2", - "quote", - "syn", + "semver", ] [[package]] @@ -1063,7 +1043,7 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507a9e6e8ffe0a4e0ebb9a10293e62fdf7657c06f1b8bb07a8fcf697d2abf295" dependencies = [ - "lazy_static", + "lazy_static 1.4.0", "winapi 0.3.8", ] @@ -1088,6 +1068,12 @@ dependencies = [ "core-foundation-sys", ] +[[package]] +name = "semver" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" + [[package]] name = "serde" version = "1.0.107" @@ -1170,29 +1156,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "syn-mid" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "synstructure" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - [[package]] name = "tempfile" version = "3.1.0" @@ -1216,13 +1179,22 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +dependencies = [ + "lazy_static 1.4.0", +] + [[package]] name = "thread_local" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" dependencies = [ - "lazy_static", + "lazy_static 1.4.0", ] [[package]] @@ -1245,7 +1217,7 @@ dependencies = [ "bytes 0.5.4", "fnv", "iovec", - "lazy_static", + "lazy_static 1.4.0", "memchr", "mio", "pin-project-lite", @@ -1300,6 +1272,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" +[[package]] +name = "ucd-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85f514e095d348c279b1e5cd76795082cf15bd59b93207832abe0b1d8fed236" + [[package]] name = "unicase" version = "2.6.0" @@ -1361,6 +1339,12 @@ dependencies = [ "percent-encoding 2.1.0", ] +[[package]] +name = "utf8-ranges" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba" + [[package]] name = "vcpkg" version = "0.2.8" @@ -1379,6 +1363,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "want" version = "0.3.0" @@ -1414,7 +1404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" dependencies = [ "bumpalo", - "lazy_static", + "lazy_static 1.4.0", "log", "proc-macro2", "quote", @@ -1569,7 +1559,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" dependencies = [ - "bitflags", + "bitflags 1.2.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 2376c52..6aff0de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,5 @@ serde = { version = "1.0.107", features = ["derive"] } serde_json = "1.0.53" serde-lexpr = "0.1.1" anyhow = "1.0.28" -nftnl = "0.3.0" -mnl = "0.2.0" -libc = "0.2.70" +iptables = "0.2.2" +regex = "1" diff --git a/src/fw.rs b/src/fw.rs index aabc420..07282af 100644 --- a/src/fw.rs +++ b/src/fw.rs @@ -1,101 +1,64 @@ -use nftnl::{nft_expr, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table}; -use std::{ - ffi::{self, CString}, - io, -}; -use mnl; -use libc; +use iptables; +use regex::Regex; +use std::collections::HashSet; -const TABLE_NAME: &str = "diplonat"; -const OUT_CHAIN_NAME: &str = "out"; -const IN_CHAIN_NAME: &str = "in"; +#[derive(PartialEq,Eq,Debug,Hash)] +pub struct Port { + proto: String, + number: u16, +} -#[derive(Debug)] -struct Error(String); +pub fn setup(ipt: &iptables::IPTables) { + ipt.new_chain("filter", "DIPLONAT").unwrap(); + ipt.insert("filter", "INPUT", "-j DIPLONAT", 1).unwrap(); +} -impl From for Error { - fn from(error: io::Error) -> Self { - Error(error.to_string()) +pub fn open_ports(ipt: &iptables::IPTables, ports: Vec) { + + for p in ports { + ipt.append("filter", "DIPLONAT", &format!("-p {} --dport {} -j ACCEPT", p.proto, p.number)).unwrap(); } } -impl From for Error { - fn from(error: ffi::NulError) -> Self { - Error(error.to_string()) - } -} +pub fn get_opened_ports(ipt: &iptables::IPTables) -> HashSet { + let mut opened_ports: HashSet = HashSet::new(); -fn send_and_process(batch: &FinalizedBatch) -> Result<(), Error> { - let socket = mnl::Socket::new(mnl::Bus::Netfilter)?; - socket.send_all(batch)?; + let list = ipt.list("filter", "DIPLONAT").unwrap(); + let re = Regex::new(r"\-A.*? \-p (\w+).*\-\-dport (\d+).*?\-j ACCEPT").unwrap(); + for i in list { + let caps = re.captures(&i); + match caps { + Some(c) => { + let raw_proto = c.get(1).unwrap(); + let raw_port = c.get(2).unwrap(); - let portid = socket.portid(); - let mut buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize]; + let proto = String::from(raw_proto.as_str()); + let number = String::from(raw_port.as_str()).parse::().unwrap(); - while let Some(message) = socket_recv(&socket, &mut buffer[..])? { - match mnl::cb_run(message, 2, portid)? { - mnl::CbResult::Stop => { - break; - } - mnl::CbResult::Ok => (), + opened_ports.insert( Port { proto, number } ); + }, + _ => {} } } - Ok(()) + + opened_ports } -fn socket_recv<'a>(socket: &mnl::Socket, buf: &'a mut [u8]) -> Result, Error> { - let ret = socket.recv(buf)?; - if ret > 0 { - Ok(Some(&buf[..ret])) - } else { - Ok(None) - } +pub fn cleanup(ipt: &iptables::IPTables) { + ipt.flush_chain("filter", "DIPLONAT").unwrap(); + ipt.delete("filter", "INPUT", "-j DIPLONAT").unwrap(); + ipt.delete_chain("filter", "DIPLONAT").unwrap(); } -fn add_port_allowed(port: u16) -> Result<(), Error> { - let mut batch = Batch::new(); +/* +fn main() { + let ipt = iptables::new(false).unwrap(); + setup(&ipt); - // TODO: at the moment, I haven't found a way to properly separate setup part (create table and - // chains) and the add rule part because the add rule part needs a reference on the chains. - // apparently creating a table and chains that already exist seems to do nothing so it works - // doing the following. To be done properly though - - let table = Table::new(&CString::new(TABLE_NAME).unwrap(), ProtoFamily::Inet); - - batch.add(&table, nftnl::MsgType::Add); - - let mut out_chain = Chain::new(&CString::new(OUT_CHAIN_NAME).unwrap(), &table); - let mut in_chain = Chain::new(&CString::new(IN_CHAIN_NAME).unwrap(), &table); - - out_chain.set_hook(nftnl::Hook::Out, 0); - in_chain.set_hook(nftnl::Hook::In, 0); - - out_chain.set_policy(nftnl::Policy::Accept); - in_chain.set_policy(nftnl::Policy::Drop); - - batch.add(&out_chain, nftnl::MsgType::Add); - batch.add(&in_chain, nftnl::MsgType::Add); - - let mut _rule = Rule::new(&in_chain); - - _rule.add_expr(&nft_expr!(meta nfproto)); - _rule.add_expr(&nft_expr!(cmp == libc::NFPROTO_IPV4 as u8)); - - _rule.add_expr(&nft_expr!(meta l4proto)); - _rule.add_expr(&nft_expr!(cmp == libc::IPPROTO_TCP as u8)); - - _rule.add_expr(&nftnl::expr::Payload::Transport( - nftnl::expr::TransportHeaderField::Tcp(nftnl::expr::TcpHeaderField::Dport), - )); - _rule.add_expr(&nft_expr!(cmp == port.to_be())); - - _rule.add_expr(&nft_expr!(verdict accept)); - - batch.add(&_rule, nftnl::MsgType::Add); - - let finalized_batch = batch.finalize(); - send_and_process(&finalized_batch)?; - - Ok(()) - + let mut test: HashSet = HashSet::new(); + test.insert(Port { proto: String::from("tcp"), number: 443 }); + let a = get_opened_ports(&ipt); + let l = test.difference(&a).collect::>(); + println!("{:?}", l); } +*/ diff --git a/src/main.rs b/src/main.rs index a35916a..bf8248d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,9 @@ mod consul; mod consul_actor; mod igd_actor; mod diplonat; +mod fw; +use iptables; use log::*; use diplonat::Diplonat; @@ -12,7 +14,10 @@ use diplonat::Diplonat; async fn main() { pretty_env_logger::init(); info!("Starting Diplonat"); - + + let ipt = iptables::new(false).unwrap(); + fw::setup(&ipt).expect("iptables setup failed"); + let mut diplo = Diplonat::new().await.expect("Setup failed"); diplo.listen().await.expect("A runtime error occured"); }