diff --git a/src/cli.rs b/src/cli.rs index ce2f448..85413ed 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -19,6 +19,9 @@ pub enum Arguments { #[structopt(name = "Docker", short = "d", long = "docker")] docker: bool, + + #[structopt(name = "Position", short = "P", long = "position")] + position: Option, }, #[structopt(about = "Unban port")] @@ -38,6 +41,20 @@ pub enum Arguments { port: u16, #[structopt(name = "Docker", short = "d", long = "docker")] docker: bool, + + #[structopt(name = "Position", short = "P", long = "position")] + position: Option, + }, + + #[structopt(about = "Allow port for only an ip")] + OnlyIpPort { + #[structopt(name = "Ip to allow", short = "i", long = "ip")] + ip: String, + + #[structopt(name = "Port to allow", short = "p", long = "port")] + port: u16, + #[structopt(name = "Docker", short = "d", long = "docker")] + docker: bool, }, #[structopt(about = "Remove ip and port")] diff --git a/src/iptables_wrapper.rs b/src/iptables_wrapper.rs index fe72103..4730fd2 100644 --- a/src/iptables_wrapper.rs +++ b/src/iptables_wrapper.rs @@ -1,11 +1,16 @@ -pub fn ban_port(port: u16, docker: bool) { +use iptables::IPTables; + +pub fn ban_port(port: u16, docker: bool, position: Option) { let iptables = iptables::new(false).unwrap(); - let _ = iptables.append_unique( - "filter", - &get_chain(docker), - &format!("-p tcp --dport {} -j DROP", port), - ); + let table = "filter"; + let chain = get_chain(docker); + let rule = format!("-p tcp --dport {} -j DROP", port); + if let Some(position) = position { + insert_unique(&iptables, table, &chain, &rule, position) + } else { + append_unique(&iptables, table, &chain, &rule) + } println!("banned port {}", port); } @@ -21,13 +26,18 @@ pub fn unban_port(port: u16, docker: bool) { println!("unbanned port {}", port); } -pub fn allow_ip_port(ip: &str, port: u16, docker: bool) { +pub fn allow_ip_port(ip: &str, port: u16, docker: bool, position: Option) { let iptables = iptables::new(false).unwrap(); - let _ = iptables.append_unique( - "filter", - &get_chain(docker), - &format!("-p tcp --dport {} -s {} -j ACCEPT", port, ip), - ); + + let table = "filter"; + let chain = get_chain(docker); + let rule = format!("-p tcp --dport {} -s {} -j ACCEPT", port, ip); + if let Some(position) = position { + insert_unique(&iptables, table, &chain, &rule, position) + } else { + append_unique(&iptables, table, &chain, &rule) + } + println!("allowed {} to access {}", ip, port); } @@ -48,3 +58,11 @@ fn get_chain(docker: bool) -> String { "INPUT".to_string() } } + +fn append_unique(iptables: &IPTables, table: &str, chain: &str, rule: &str) { + let _ = iptables.append_unique(table, chain, rule); +} + +fn insert_unique(iptables: &IPTables, table: &str, chain: &str, rule: &str, position: i32) { + let _ = iptables.insert_unique(table, chain, rule, position); +} diff --git a/src/main.rs b/src/main.rs index f3e9f83..f647271 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,9 +22,22 @@ async fn main() { } => { let _ = start_ban_server(ssh_auth_log, iptables_save).await; } - Arguments::BanPort { port, docker } => ban_port(port, docker), + Arguments::BanPort { + port, + docker, + position, + } => ban_port(port, docker, position), Arguments::UnbanPort { port, docker } => unban_port(port, docker), - Arguments::AllowIpPort { ip, port, docker } => allow_ip_port(&ip, port, docker), + Arguments::AllowIpPort { + ip, + port, + docker, + position, + } => allow_ip_port(&ip, port, docker, position), + Arguments::OnlyIpPort { ip, port, docker } => { + allow_ip_port(&ip, port, docker, Some(1)); + ban_port(port, docker, Some(2)); + } Arguments::RemoveIpPort { ip, port, docker } => remove_ip_port(&ip, port, docker), } }