Исправлен drift-check host firewall для established/related, добавлены тесты и trim policy в status
This commit is contained in:
@@ -320,9 +320,7 @@ fn host_firewall_drift_reason_from_text(nt: &str, cfg: &Config) -> Option<String
|
|||||||
if !nt.contains("iif lo accept") {
|
if !nt.contains("iif lo accept") {
|
||||||
return Some("missing loopback allow".into());
|
return Some("missing loopback allow".into());
|
||||||
}
|
}
|
||||||
if !(nt.contains("ct state established,related accept")
|
if !has_established_related_rule(nt) {
|
||||||
|| nt.contains("ct state related,established accept"))
|
|
||||||
{
|
|
||||||
return Some("missing established/related allow".into());
|
return Some("missing established/related allow".into());
|
||||||
}
|
}
|
||||||
if !nt.contains(&ssh) {
|
if !nt.contains(&ssh) {
|
||||||
@@ -348,6 +346,11 @@ fn host_firewall_drift_reason_from_text(nt: &str, cfg: &Config) -> Option<String
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_established_related_rule(nt: &str) -> bool {
|
||||||
|
nt.contains("ct state established related accept")
|
||||||
|
|| nt.contains("ct state related established accept")
|
||||||
|
}
|
||||||
|
|
||||||
fn apply_rule(transport: &dyn NsTransport, cidr: &str, max_conn: u32) -> anyhow::Result<()> {
|
fn apply_rule(transport: &dyn NsTransport, cidr: &str, max_conn: u32) -> anyhow::Result<()> {
|
||||||
let _ = transport.run(&[
|
let _ = transport.run(&[
|
||||||
"nft",
|
"nft",
|
||||||
@@ -686,6 +689,70 @@ table inet awg2_host_firewall {
|
|||||||
assert_eq!(host_firewall_drift_reason_from_text(&nt, &cfg), None);
|
assert_eq!(host_firewall_drift_reason_from_text(&nt, &cfg), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn normalized_established_related_rule_matches() {
|
||||||
|
let nt = normalize_nft_text("ct state established,related accept");
|
||||||
|
assert!(nt.contains("ct state established related accept"));
|
||||||
|
assert!(has_established_related_rule(&nt));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn host_firewall_drift_detects_missing_established_related_rule() {
|
||||||
|
let table = r#"
|
||||||
|
table inet awg2_host_firewall {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority filter; policy drop;
|
||||||
|
iif "lo" accept
|
||||||
|
tcp dport 2323 accept
|
||||||
|
udp dport 443 accept
|
||||||
|
ip protocol icmp accept
|
||||||
|
ip6 nexthdr icmpv6 accept
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
let cfg = Config {
|
||||||
|
amnezia: crate::config::AmneziaConfig {
|
||||||
|
container_names: vec!["amnezia-awg2".into()],
|
||||||
|
interface_candidates: vec!["awg0".into()],
|
||||||
|
interface_patterns: vec!["awg*".into()],
|
||||||
|
peer_ipv4_cidr: "10.8.1.0/24".into(),
|
||||||
|
},
|
||||||
|
traffic: crate::config::TrafficConfig {
|
||||||
|
enabled: true,
|
||||||
|
peer_limit: "70mbit".into(),
|
||||||
|
root_rate: "1000mbit".into(),
|
||||||
|
reconcile_interval_secs: 15,
|
||||||
|
container_ready_timeout_secs: 30,
|
||||||
|
class_start_id: 10,
|
||||||
|
ifb_name: "ifb0".into(),
|
||||||
|
},
|
||||||
|
host_firewall: crate::config::HostFirewallConfig::default(),
|
||||||
|
anti_torrent: crate::config::AntiTorrentConfig {
|
||||||
|
enabled: false,
|
||||||
|
max_connections_per_peer: 100,
|
||||||
|
peer_ipv4_cidr: "10.8.1.0/24".into(),
|
||||||
|
apply_in_amnezia_netns: false,
|
||||||
|
},
|
||||||
|
reboot: crate::config::RebootConfig {
|
||||||
|
enabled: false,
|
||||||
|
window_start_utc: "01:00".into(),
|
||||||
|
window_end_utc: "02:00".into(),
|
||||||
|
},
|
||||||
|
swap: crate::config::SwapConfig {
|
||||||
|
enabled: false,
|
||||||
|
path: "/swapfile".into(),
|
||||||
|
size_mb: 2048,
|
||||||
|
priority: 1,
|
||||||
|
swappiness: 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let nt = normalize_nft_text(table);
|
||||||
|
assert_eq!(
|
||||||
|
host_firewall_drift_reason_from_text(&nt, &cfg),
|
||||||
|
Some("missing established/related allow".into())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn host_firewall_batch_script_does_not_include_delete_table() {
|
fn host_firewall_batch_script_does_not_include_delete_table() {
|
||||||
let cfg = Config {
|
let cfg = Config {
|
||||||
|
|||||||
@@ -175,7 +175,10 @@ pub fn print_status(cfg: &Config) -> anyhow::Result<()> {
|
|||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
" input_policy: {}",
|
" input_policy: {}",
|
||||||
cfg.host_firewall.default_input_policy.to_ascii_lowercase()
|
cfg.host_firewall
|
||||||
|
.default_input_policy
|
||||||
|
.trim()
|
||||||
|
.to_ascii_lowercase()
|
||||||
);
|
);
|
||||||
if cfg.host_firewall.enabled {
|
if cfg.host_firewall.enabled {
|
||||||
match firewall::host_firewall_drift_reason(cfg) {
|
match firewall::host_firewall_drift_reason(cfg) {
|
||||||
@@ -284,7 +287,10 @@ fn print_degraded_sections(cfg: &Config) -> anyhow::Result<()> {
|
|||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
" input_policy: {}",
|
" input_policy: {}",
|
||||||
cfg.host_firewall.default_input_policy.to_ascii_lowercase()
|
cfg.host_firewall
|
||||||
|
.default_input_policy
|
||||||
|
.trim()
|
||||||
|
.to_ascii_lowercase()
|
||||||
);
|
);
|
||||||
if cfg.host_firewall.enabled {
|
if cfg.host_firewall.enabled {
|
||||||
match firewall::host_firewall_drift_reason(cfg) {
|
match firewall::host_firewall_drift_reason(cfg) {
|
||||||
|
|||||||
Reference in New Issue
Block a user