moving code from command server into cli
This commit is contained in:
parent
8a6021aa83
commit
d53ca8a33a
212
Cargo.lock
generated
212
Cargo.lock
generated
@ -26,6 +26,26 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
@ -67,9 +87,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.97"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||
checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -78,19 +98,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.12"
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags 1.3.2",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.19"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
@ -135,6 +170,24 @@ version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
@ -200,9 +253,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.154"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "linemux"
|
||||
@ -229,6 +282,7 @@ dependencies = [
|
||||
"iptables",
|
||||
"linemux",
|
||||
"regex",
|
||||
"structopt",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@ -240,9 +294,9 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||
checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
@ -293,7 +347,7 @@ version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.3.9",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@ -319,10 +373,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -408,16 +486,66 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.63"
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.37.0"
|
||||
@ -443,7 +571,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -452,6 +580,30 @@ version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
@ -468,6 +620,22 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.8"
|
||||
@ -477,6 +645,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
structopt = "0.3.26"
|
||||
iptables = "0.5.1"
|
||||
linemux = "0.3.0"
|
||||
regex = "1.10.4"
|
||||
|
@ -8,4 +8,4 @@ FROM ubuntu:latest
|
||||
RUN apt update && apt upgrade -y && apt install iptables iptables-persistent -y
|
||||
COPY --from=builder /target/release/martillo-maldito ./
|
||||
|
||||
CMD ["/martillo-maldito"]
|
||||
CMD [ "/martillo-maldito", "ban-server", "-f", "/host_ssh/auth.log", "-s", "/host_iptables/rules.v4" ]
|
||||
|
44
src/cli.rs
Normal file
44
src/cli.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(name = "martillo-maldito", about = "A simple iptables ban server")]
|
||||
pub enum Arguments {
|
||||
#[structopt(about = "Initialize ban server")]
|
||||
BanServer {
|
||||
#[structopt(name = "Ssh auth log file", short = "f", long = "ssh-file")]
|
||||
ssh_auth_log: PathBuf,
|
||||
#[structopt(name = "Iptables save file", short = "s", long = "iptables-save")]
|
||||
iptables_save: Option<PathBuf>,
|
||||
},
|
||||
|
||||
#[structopt(about = "Ban port")]
|
||||
BanPort {
|
||||
#[structopt(name = "Port to ban", short = "p", long = "port")]
|
||||
port: u16,
|
||||
},
|
||||
|
||||
#[structopt(about = "Unban port")]
|
||||
UnbanPort {
|
||||
#[structopt(name = "Port to unban", short = "p", long = "port")]
|
||||
port: u16,
|
||||
},
|
||||
|
||||
#[structopt(about = "Allow ip and port")]
|
||||
AllowIpPort {
|
||||
#[structopt(name = "Ip to allow", short = "i", long = "ip")]
|
||||
ip: String,
|
||||
|
||||
#[structopt(name = "Port to allow", short = "p", long = "port")]
|
||||
port: u16,
|
||||
},
|
||||
|
||||
#[structopt(about = "Remove ip and port")]
|
||||
RemoveIpPort {
|
||||
#[structopt(name = "Ip to remove", short = "i", long = "ip")]
|
||||
ip: String,
|
||||
|
||||
#[structopt(name = "Port to remove", short = "p", long = "port")]
|
||||
port: u16,
|
||||
},
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use std::process::Command;
|
||||
use std::{path::Path, process::Command};
|
||||
|
||||
pub fn save_iptables() {
|
||||
pub fn save_iptables(path: &Path) {
|
||||
let _ = Command::new("iptables-save")
|
||||
.args(&["-f", "/host_iptables/rules.v4"])
|
||||
.args(["-f", path.to_str().unwrap()])
|
||||
.output();
|
||||
}
|
||||
|
41
src/iptables_wrapper.rs
Normal file
41
src/iptables_wrapper.rs
Normal file
@ -0,0 +1,41 @@
|
||||
pub fn ban_port(port: u16) {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let _ = iptables.append_unique(
|
||||
"filter",
|
||||
"INPUT",
|
||||
&format!("-p tcp --dport {} -j DROP", port),
|
||||
);
|
||||
|
||||
println!("banned port {}", port);
|
||||
}
|
||||
|
||||
pub fn unban_port(port: u16) {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let _ = iptables.delete(
|
||||
"filter",
|
||||
"INPUT",
|
||||
&format!("-p tcp --dport {} -j DROP", port),
|
||||
);
|
||||
|
||||
println!("unbanned port {}", port);
|
||||
}
|
||||
|
||||
pub fn allow_ip_port(ip: &str, port: u16) {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let _ = iptables.append_unique(
|
||||
"filter",
|
||||
"INPUT",
|
||||
&format!("-p tcp --dport {} -s {} -j ACCEPT", port, ip),
|
||||
);
|
||||
println!("allowed {} to access {}", ip, port);
|
||||
}
|
||||
|
||||
pub fn remove_ip_port(ip: &str, port: u16) {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let _ = iptables.delete(
|
||||
"filter",
|
||||
"INPUT",
|
||||
&format!("-p tcp --dport {} -s {} -j ACCEPT", port, ip),
|
||||
);
|
||||
println!("removed access {} to {}", ip, port);
|
||||
}
|
60
src/main.rs
60
src/main.rs
@ -1,37 +1,57 @@
|
||||
pub mod cli;
|
||||
pub mod iptables_save;
|
||||
pub mod iptables_wrapper;
|
||||
pub mod login_attempt;
|
||||
pub mod tpc_command_server;
|
||||
|
||||
use crate::tpc_command_server::start_tcp_command_server;
|
||||
use cli::Arguments;
|
||||
use iptables_wrapper::{allow_ip_port, ban_port, remove_ip_port, unban_port};
|
||||
use linemux::MuxedLines;
|
||||
use login_attempt::LoginAttempt;
|
||||
use std::path::PathBuf;
|
||||
use std::thread;
|
||||
use std::{collections::HashMap, thread::sleep, time::Duration};
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
async fn main() {
|
||||
let opts = Arguments::from_args();
|
||||
match opts {
|
||||
Arguments::BanServer {
|
||||
ssh_auth_log,
|
||||
iptables_save,
|
||||
} => {
|
||||
let _ = start_ban_server(ssh_auth_log, iptables_save).await;
|
||||
}
|
||||
Arguments::BanPort { port } => ban_port(port),
|
||||
Arguments::UnbanPort { port } => unban_port(port),
|
||||
Arguments::AllowIpPort { ip, port } => allow_ip_port(&ip, port),
|
||||
Arguments::RemoveIpPort { ip, port } => remove_ip_port(&ip, port),
|
||||
}
|
||||
}
|
||||
|
||||
async fn start_ban_server(
|
||||
ssh_auth_log: PathBuf,
|
||||
iptables_save: Option<PathBuf>,
|
||||
) -> std::io::Result<()> {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let mut lines = MuxedLines::new()?;
|
||||
lines.add_file("/host_ssh/auth.log").await?;
|
||||
lines.add_file(&ssh_auth_log).await?;
|
||||
let mut login_attempts: HashMap<String, usize> = HashMap::new();
|
||||
|
||||
let seconds_iptables = Duration::from_secs(60);
|
||||
println!(
|
||||
"starting iptables-save, run every {} seconds",
|
||||
seconds_iptables.as_secs()
|
||||
);
|
||||
if let Some(iptables_save) = iptables_save {
|
||||
let seconds_iptables = Duration::from_secs(60);
|
||||
println!(
|
||||
"starting iptables-save, run every {} seconds",
|
||||
seconds_iptables.as_secs()
|
||||
);
|
||||
thread::spawn(move || loop {
|
||||
sleep(seconds_iptables);
|
||||
iptables_save::save_iptables(&iptables_save);
|
||||
println!("saved iptables rules");
|
||||
});
|
||||
}
|
||||
|
||||
thread::spawn(move || loop {
|
||||
sleep(seconds_iptables);
|
||||
iptables_save::save_iptables();
|
||||
println!("saved iptables rules");
|
||||
});
|
||||
|
||||
thread::spawn(|| {
|
||||
start_tcp_command_server();
|
||||
});
|
||||
|
||||
println!("listening to changes over /host_ssh/auth.log");
|
||||
println!("listening to changes over {}", ssh_auth_log.display());
|
||||
while let Ok(Some(line)) = lines.next_line().await {
|
||||
if let Some(login_attempt) = LoginAttempt::capture(line.line()) {
|
||||
println!(
|
||||
|
@ -1,103 +0,0 @@
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::thread;
|
||||
|
||||
pub fn start_tcp_command_server() {
|
||||
let listener = TcpListener::bind("127.0.0.1:9999").unwrap();
|
||||
println!("listening on port 9999 for tcp commands");
|
||||
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
thread::spawn(move || handle_client(&stream));
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("err with tcp conn: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_client(mut stream: &TcpStream) {
|
||||
for line in BufReader::new(stream).lines() {
|
||||
let buffer = match line {
|
||||
Ok(data) => data,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
if buffer.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
let mut parts = buffer.trim().split_whitespace();
|
||||
if let Some(command) = parts.next() {
|
||||
let arguments: Vec<&str> = parts.collect();
|
||||
let response = handle_command(command, arguments);
|
||||
stream.write_all(response.as_bytes()).unwrap();
|
||||
} else {
|
||||
stream.write_all("invalid command".as_bytes()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_command(command: &str, arguments: Vec<&str>) -> String {
|
||||
match command {
|
||||
"banport" => {
|
||||
if let Some(port) = arguments.get(0) {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let _ = iptables.append_unique(
|
||||
"filter",
|
||||
"INPUT",
|
||||
&format!("-p tcp --dport {} -j DROP", port),
|
||||
);
|
||||
|
||||
format!("banned port {} for all ips", port)
|
||||
} else {
|
||||
"missing args for banport: port".to_string()
|
||||
}
|
||||
}
|
||||
"unbanport" => {
|
||||
if let Some(port) = arguments.get(0) {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let _ = iptables.delete(
|
||||
"filter",
|
||||
"INPUT",
|
||||
&format!("-p tcp --dport {} -j DROP", port),
|
||||
);
|
||||
|
||||
format!("unbanned port {}", port)
|
||||
} else {
|
||||
"missing args for unbanport: port".to_string()
|
||||
}
|
||||
}
|
||||
"allowipport" => {
|
||||
if let (Some(ip), Some(port)) = (arguments.get(0), arguments.get(1)) {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let _ = iptables.append_unique(
|
||||
"filter",
|
||||
"INPUT",
|
||||
&format!("-s {} -p tcp --dport {} -j ACCEPT", ip, port),
|
||||
);
|
||||
format!("allowed {} to access {}", ip, port)
|
||||
} else {
|
||||
"missing args for allowipport: ip and port".to_string()
|
||||
}
|
||||
}
|
||||
"removeipport" => {
|
||||
if let (Some(ip), Some(port)) = (arguments.get(0), arguments.get(1)) {
|
||||
let iptables = iptables::new(false).unwrap();
|
||||
let _ = iptables.delete(
|
||||
"filter",
|
||||
"INPUT",
|
||||
&format!("-s {} -p tcp --dport {} -j ACCEPT", ip, port),
|
||||
);
|
||||
format!("rm {} access to {}", ip, port)
|
||||
} else {
|
||||
"missing args for rmipport: ip and port".to_string()
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
format!("unknown command: {}", command)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user