diff options
Diffstat (limited to 'src/fw.rs')
-rw-r--r-- | src/fw.rs | 148 |
1 files changed, 76 insertions, 72 deletions
@@ -8,92 +8,96 @@ use regex::Regex; use crate::messages; pub fn setup(ipt: &iptables::IPTables) -> Result<()> { - // ensure we start from a clean state without any rule already set - cleanup(ipt)?; + // ensure we start from a clean state without any rule already set + cleanup(ipt)?; - ipt - .new_chain("filter", "DIPLONAT") - .context("Failed to create new chain")?; - ipt - .insert_unique("filter", "INPUT", "-j DIPLONAT", 1) - .context("Failed to insert jump rule")?; + info!("{}: creating DIPLONAT chain", ipt.cmd); + ipt.new_chain("filter", "DIPLONAT") + .context("Failed to create new chain")?; + ipt.insert_unique("filter", "INPUT", "-j DIPLONAT", 1) + .context("Failed to insert jump rule")?; - Ok(()) + Ok(()) } pub fn open_ports(ipt: &iptables::IPTables, ports: messages::PublicExposedPorts) -> Result<()> { - for p in ports.tcp_ports { - ipt - .append( - "filter", - "DIPLONAT", - &format!("-p tcp --dport {} -j ACCEPT", p), - ) - .context("Failed to insert port rule")?; - } - - for p in ports.udp_ports { - ipt - .append( - "filter", - "DIPLONAT", - &format!("-p udp --dport {} -j ACCEPT", p), - ) - .context("Failed to insert port rule")?; - } - - Ok(()) + for p in ports.tcp_ports { + info!("{}: opening TCP port {}", ipt.cmd, p); + ipt.append( + "filter", + "DIPLONAT", + &format!("-p tcp --dport {} -j ACCEPT", p), + ) + .context("Failed to insert port rule")?; + } + + for p in ports.udp_ports { + info!("{}: opening UDP port {}", ipt.cmd, p); + ipt.append( + "filter", + "DIPLONAT", + &format!("-p udp --dport {} -j ACCEPT", p), + ) + .context("Failed to insert port rule")?; + } + + Ok(()) } pub fn get_opened_ports(ipt: &iptables::IPTables) -> Result<messages::PublicExposedPorts> { - let mut ports = messages::PublicExposedPorts { - tcp_ports: HashSet::new(), - udp_ports: HashSet::new(), - }; - - let list = ipt.list("filter", "DIPLONAT")?; - let re = Regex::new(r"\-A.*? \-p (\w+).*\-\-dport (\d+).*?\-j ACCEPT") - .context("Regex matching open ports encountered an unexpected rule")?; - for i in list { - let caps = re.captures(&i); - match caps { - Some(c) => { - if let (Some(raw_proto), Some(raw_port)) = (c.get(1), c.get(2)) { - let proto = String::from(raw_proto.as_str()); - let number = String::from(raw_port.as_str()).parse::<u16>()?; - - if proto == "tcp" { - ports.tcp_ports.insert(number); - } else { - ports.udp_ports.insert(number); - } - } else { - error!("Unexpected rule found in DIPLONAT chain") + let mut ports = messages::PublicExposedPorts { + tcp_ports: HashSet::new(), + udp_ports: HashSet::new(), + }; + + let list = ipt.list("filter", "DIPLONAT")?; + let re = Regex::new(r"\-A.*? \-p (\w+).*\-\-dport (\d+).*?\-j ACCEPT") + .context("Regex matching open ports encountered an unexpected rule")?; + for i in list { + debug!("{} list DIPLONAT: got {}", ipt.cmd, i); + let caps = re.captures(&i); + match caps { + Some(c) => { + if let (Some(raw_proto), Some(raw_port)) = (c.get(1), c.get(2)) { + let proto = String::from(raw_proto.as_str()); + let number = String::from(raw_port.as_str()).parse::<u16>()?; + + if proto == "tcp" || proto == "6" { + ports.tcp_ports.insert(number); + } else if proto == "udp" || proto == "17" { + ports.udp_ports.insert(number); + } else { + error!("Unexpected protocol in iptables rule: {}", proto); + } + } else { + error!("Unexpected rule found in DIPLONAT chain") + } + } + _ => { + debug!("{} rule not parsed: {}", ipt.cmd, i); + } } - } - _ => {} } - } - Ok(ports) + debug!("{} ports already openned: {:?}", ipt.cmd, ports); + + Ok(ports) } pub fn cleanup(ipt: &iptables::IPTables) -> Result<()> { - if ipt.chain_exists("filter", "DIPLONAT")? { - ipt - .flush_chain("filter", "DIPLONAT") - .context("Failed to flush the DIPLONAT chain")?; - - if ipt.exists("filter", "INPUT", "-j DIPLONAT")? { - ipt - .delete("filter", "INPUT", "-j DIPLONAT") - .context("Failed to delete jump rule")?; - } + if ipt.chain_exists("filter", "DIPLONAT")? { + info!("{}: removing old DIPLONAT chain", ipt.cmd); + ipt.flush_chain("filter", "DIPLONAT") + .context("Failed to flush the DIPLONAT chain")?; + + if ipt.exists("filter", "INPUT", "-j DIPLONAT")? { + ipt.delete("filter", "INPUT", "-j DIPLONAT") + .context("Failed to delete jump rule")?; + } - ipt - .delete_chain("filter", "DIPLONAT") - .context("Failed to delete chain")?; - } + ipt.delete_chain("filter", "DIPLONAT") + .context("Failed to delete chain")?; + } - Ok(()) + Ok(()) } |