Рефакторинг под прод: nsenter-first транспорт, drift-aware reconcile, hardening daemon/lock/reboot/swap, расширенный status и build-скрипт
This commit is contained in:
@@ -1,29 +1,62 @@
|
||||
use crate::{config::Config, docker};
|
||||
use crate::{
|
||||
config::Config,
|
||||
docker,
|
||||
netns::{build_transport, NsTransport},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct FirewallActual {
|
||||
table_exists: bool,
|
||||
chain_exists: bool,
|
||||
rule_matches: bool,
|
||||
}
|
||||
|
||||
pub fn apply_firewall(cfg: &Config) -> anyhow::Result<()> {
|
||||
let target = docker::discover_target(cfg)?;
|
||||
let transport = build_transport(target.container_pid, &target.container_name);
|
||||
|
||||
if !cfg.anti_torrent.enabled {
|
||||
let _ = docker::run_capture(&[
|
||||
"docker",
|
||||
"exec",
|
||||
&target.container_name,
|
||||
"sh",
|
||||
"-c",
|
||||
"nft delete table inet awg2_harness 2>/dev/null || true",
|
||||
])?;
|
||||
let _ = transport.run(&["sh", "-c", "nft delete table inet awg2_harness 2>/dev/null || true"])?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let actual = inspect_firewall(transport.as_ref(), cfg)?;
|
||||
if actual.table_exists && actual.chain_exists && actual.rule_matches {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let rule = format!(
|
||||
"nft 'add table inet awg2_harness' 2>/dev/null || true; \
|
||||
nft 'add chain inet awg2_harness forward_antitorrent {{ type filter hook forward priority filter; policy accept; }}' 2>/dev/null || true; \
|
||||
nft 'flush chain inet awg2_harness forward_antitorrent'; \
|
||||
nft 'add rule inet awg2_harness forward_antitorrent ip saddr {cidr} ct state new meter awg2_peer_connlimit_v4 {{ ip saddr ct count over {max} }} counter name antitorrent_dropped_v4 drop'",
|
||||
nft 'add rule inet awg2_harness forward_antitorrent ip saddr {cidr} ct state new meter awg2_peer_connlimit_v4 {{ ip saddr ct count over {max} }} counter name antitorrent_dropped_v4 drop' 2>/dev/null || true",
|
||||
cidr = cfg.anti_torrent.peer_ipv4_cidr,
|
||||
max = cfg.anti_torrent.max_connections_per_peer
|
||||
);
|
||||
let _ = docker::run_capture(&["docker", "exec", &target.container_name, "sh", "-c", &rule])?;
|
||||
apply_rule(transport.as_ref(), &rule)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn inspect_firewall(transport: &dyn NsTransport, cfg: &Config) -> anyhow::Result<FirewallActual> {
|
||||
let table = transport
|
||||
.run(&["sh", "-c", "nft list table inet awg2_harness 2>/dev/null"])
|
||||
.unwrap_or_default();
|
||||
|
||||
let table_exists = !table.trim().is_empty();
|
||||
let chain_exists = table.contains("chain forward_antitorrent");
|
||||
|
||||
let needle_cidr = format!("ip saddr {}", cfg.anti_torrent.peer_ipv4_cidr);
|
||||
let needle_max = format!("ct count over {}", cfg.anti_torrent.max_connections_per_peer);
|
||||
let rule_matches = table.contains(&needle_cidr) && table.contains(&needle_max);
|
||||
|
||||
Ok(FirewallActual {
|
||||
table_exists,
|
||||
chain_exists,
|
||||
rule_matches,
|
||||
})
|
||||
}
|
||||
|
||||
fn apply_rule(transport: &dyn NsTransport, rule: &str) -> anyhow::Result<()> {
|
||||
let _ = transport.run(&["sh", "-c", rule])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user