Files
telemt/src/conntrack_control/firewall/tests/model_tests.rs
T
2026-09-25 19:49:36 +03:00

119 lines
4.4 KiB
Rust

use crate::config::{ConntrackBackend, ConntrackMode, ProxyConfig};
use super::super::command::is_not_found_error;
use super::super::iptables::{self, is_chain_exists_error};
use super::super::model::{DesiredPolicy, ShadowSlot};
use super::super::nftables;
use super::target;
#[test]
fn desired_policy_derives_exact_listener_targets() {
let mut config = ProxyConfig::default();
config.server.port = 8443;
config.server.listen_addr_ipv4 = Some("0.0.0.0".to_string());
config.server.listen_addr_ipv6 = Some("2001:db8::10".to_string());
config.server.conntrack_control.inline_conntrack_control = true;
config.server.conntrack_control.mode = ConntrackMode::Notrack;
config.server.conntrack_control.backend = ConntrackBackend::Iptables;
assert_eq!(
DesiredPolicy::from_config(&config),
DesiredPolicy::Rules {
configured_backend: ConntrackBackend::Iptables,
v4: vec![target(None, 8443)],
v6: vec![target(Some("2001:db8::10"), 8443)],
}
);
config.server.conntrack_control.mode = ConntrackMode::Tracked;
assert_eq!(DesiredPolicy::from_config(&config), DesiredPolicy::Empty);
config.server.conntrack_control.mode = ConntrackMode::Notrack;
config.server.conntrack_control.inline_conntrack_control = false;
assert_eq!(DesiredPolicy::from_config(&config), DesiredPolicy::Empty);
}
#[test]
fn hybrid_policy_is_a_sorted_deduplicated_address_port_product() {
let mut config = ProxyConfig::default();
config.server.conntrack_control.inline_conntrack_control = true;
config.server.conntrack_control.mode = ConntrackMode::Hybrid;
config.server.conntrack_control.hybrid_listener_ips = vec![
"2001:db8::10".parse().unwrap(),
"192.0.2.10".parse().unwrap(),
"192.0.2.10".parse().unwrap(),
];
config.server.listeners = vec![
serde_json::from_value(serde_json::json!({
"ip": "0.0.0.0",
"port": 8443
}))
.unwrap(),
serde_json::from_value(serde_json::json!({
"ip": "::",
"port": 443
}))
.unwrap(),
];
assert_eq!(
DesiredPolicy::from_config(&config),
DesiredPolicy::Rules {
configured_backend: ConntrackBackend::Auto,
v4: vec![
target(Some("192.0.2.10"), 443),
target(Some("192.0.2.10"), 8443),
],
v6: vec![
target(Some("2001:db8::10"), 443),
target(Some("2001:db8::10"), 8443),
],
}
);
}
#[test]
fn restore_renderers_keep_staging_detached_from_activation() {
let stage = iptables::render_stage_script(ShadowSlot::B, &[target(Some("192.0.2.20"), 443)]);
assert!(stage.contains("-F TELEMT_NT_B\n"));
assert!(stage.contains("-A TELEMT_NT_B -p tcp --dport 443 -d 192.0.2.20 -j CT --notrack\n"));
assert!(!stage.contains("-A TELEMT_NOTRACK -j TELEMT_NT_B"));
assert!(!stage.contains(":TELEMT_"));
let activation = iptables::render_dispatch_script(Some(ShadowSlot::B));
assert!(activation.contains("-F TELEMT_NOTRACK\n"));
assert!(activation.contains("-A TELEMT_NOTRACK -j TELEMT_NT_B\n"));
assert!(!activation.contains(":TELEMT_"));
let nft_stage = nftables::render_stage_script(
ShadowSlot::A,
&[target(None, 443)],
&[target(Some("2001:db8::20"), 8443)],
);
assert!(!nft_stage.contains("hook prerouting"));
assert!(nft_stage.contains("tcp dport 443 notrack\n"));
assert!(nft_stage.contains("tcp dport 8443 ip6 daddr 2001:db8::20 notrack\n"));
assert!(nftables::render_activate_script(ShadowSlot::A).contains("hook prerouting"));
}
#[test]
fn command_error_classification_only_accepts_absent_owned_objects() {
assert!(is_not_found_error(
"iptables: No chain/target/match by that name."
));
assert!(is_not_found_error(
"Bad rule (does a matching rule exist in that chain?)."
));
assert!(is_not_found_error(
"Error: Could not process rule: No such file or directory"
));
assert!(!is_not_found_error("Permission denied"));
assert!(!is_not_found_error(
"can't initialize iptables table `raw': Table does not exist"
));
assert!(!is_not_found_error(
"Another app is currently holding the xtables lock"
));
assert!(is_chain_exists_error("iptables: Chain already exists."));
assert!(!is_chain_exists_error("Permission denied"));
}