Полный продакшн-фикс: hardened build/install, drift/firewall/wg проверки и актуализация документации
This commit is contained in:
@@ -3,6 +3,7 @@ use crate::{
|
||||
docker,
|
||||
netns::{NsTransport, build_host_transport, build_transport},
|
||||
};
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct FirewallActual {
|
||||
@@ -77,7 +78,14 @@ fn inspect_firewall(transport: &dyn NsTransport, cfg: &Config) -> anyhow::Result
|
||||
"ct count over {}",
|
||||
cfg.anti_torrent.max_connections_per_peer
|
||||
);
|
||||
let rule_matches = table.contains(&needle_cidr) && table.contains(&needle_max);
|
||||
let rule_matches = table.contains(&needle_cidr)
|
||||
&& table.contains(&needle_max)
|
||||
&& table.contains("ct state new")
|
||||
&& table.contains("meter awg2_peer_connlimit_v4")
|
||||
&& table.contains("counter name antitorrent_dropped_v4")
|
||||
&& table.contains("drop")
|
||||
&& table.contains("hook forward")
|
||||
&& table.contains("policy accept");
|
||||
|
||||
Ok(FirewallActual {
|
||||
table_exists,
|
||||
@@ -90,7 +98,10 @@ fn inspect_firewall(transport: &dyn NsTransport, cfg: &Config) -> anyhow::Result
|
||||
fn firewall_transport(cfg: &Config) -> anyhow::Result<Box<dyn NsTransport>> {
|
||||
if cfg.anti_torrent.apply_in_amnezia_netns {
|
||||
let target = docker::discover_target(cfg)?;
|
||||
Ok(build_transport(target.container_pid, &target.container_name))
|
||||
Ok(build_transport(
|
||||
target.container_pid,
|
||||
&target.container_name,
|
||||
))
|
||||
} else {
|
||||
Ok(build_host_transport())
|
||||
}
|
||||
@@ -180,25 +191,75 @@ pub fn antitorrent_drop_counter(cfg: &Config) -> anyhow::Result<Option<(u64, u64
|
||||
}
|
||||
|
||||
let transport = firewall_transport(cfg)?;
|
||||
let json = transport.run(&[
|
||||
"nft",
|
||||
"-j",
|
||||
"list",
|
||||
"counter",
|
||||
"inet",
|
||||
"awg2_harness",
|
||||
"antitorrent_dropped_v4",
|
||||
]);
|
||||
|
||||
if let Ok(raw) = json {
|
||||
if let Some(v) = parse_counter_json(&raw)? {
|
||||
return Ok(Some(v));
|
||||
}
|
||||
}
|
||||
|
||||
let table = transport
|
||||
.run(&["nft", "list", "table", "inet", "awg2_harness"])
|
||||
.unwrap_or_default();
|
||||
|
||||
for line in table.lines() {
|
||||
if line.contains("counter antitorrent_dropped_v4") && line.contains("packets") {
|
||||
let toks: Vec<&str> = line.split_whitespace().collect();
|
||||
if let Some(idx) = toks.iter().position(|t| *t == "packets") {
|
||||
if let Some(v) = toks.get(idx + 1).and_then(|s| s.parse::<u64>().ok()) {
|
||||
let bytes = toks
|
||||
.iter()
|
||||
.position(|t| *t == "bytes")
|
||||
.and_then(|i| toks.get(i + 1))
|
||||
.and_then(|s| s.parse::<u64>().ok())
|
||||
.unwrap_or(0);
|
||||
return Ok(Some((v, bytes)));
|
||||
}
|
||||
let t = line.trim();
|
||||
if !t.contains("packets") {
|
||||
continue;
|
||||
}
|
||||
let toks: Vec<&str> = t.split_whitespace().collect();
|
||||
let packets = toks
|
||||
.iter()
|
||||
.position(|x| *x == "packets")
|
||||
.and_then(|i| toks.get(i + 1))
|
||||
.and_then(|s| s.parse::<u64>().ok());
|
||||
let bytes = toks
|
||||
.iter()
|
||||
.position(|x| *x == "bytes")
|
||||
.and_then(|i| toks.get(i + 1))
|
||||
.and_then(|s| s.parse::<u64>().ok())
|
||||
.unwrap_or(0);
|
||||
if let Some(p) = packets {
|
||||
return Ok(Some((p, bytes)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn parse_counter_json(raw: &str) -> anyhow::Result<Option<(u64, u64)>> {
|
||||
let v: Value = serde_json::from_str(raw)?;
|
||||
let Some(arr) = v.get("nftables").and_then(|x| x.as_array()) else {
|
||||
return Ok(None);
|
||||
};
|
||||
for item in arr {
|
||||
if let Some(counter) = item.get("counter") {
|
||||
let packets = counter.get("packets").and_then(|x| x.as_u64());
|
||||
let bytes = counter.get("bytes").and_then(|x| x.as_u64());
|
||||
if let (Some(p), Some(b)) = (packets, bytes) {
|
||||
return Ok(Some((p, b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parse_nft_counter_json() {
|
||||
let raw = r#"{"nftables":[{"metainfo":{"json_schema_version":1}},{"counter":{"family":"inet","table":"awg2_harness","name":"antitorrent_dropped_v4","handle":2,"packets":7,"bytes":448}}]}"#;
|
||||
let got = parse_counter_json(raw).expect("json parse");
|
||||
assert_eq!(got, Some((7, 448)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user