Рефакторинг под прод: nsenter-first транспорт, drift-aware reconcile, hardening daemon/lock/reboot/swap, расширенный status и build-скрипт

This commit is contained in:
2026-05-09 22:03:30 +05:00
parent d937f816bf
commit e7818054e8
16 changed files with 900 additions and 96 deletions
+45 -12
View File
@@ -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(())
}