cli: avoid data-dir initialization for version; create db parent dirs; redact generated passwords in CLI output
- Prevent 'nx9-wg version' from creating data directories by avoiding database initialization. - Create parent directories when an explicit --database path is provided. - Redact printed generated administrator passwords; announce file path or redact instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
commit
2ac6c81dfe
140 files changed
+31342
No files matched your search
@@ -0,0 +1,150 @@
|
||||
//! Integration tests for Phase 5 Network Engine, Route Management, and nftables ruleset builder.
|
||||
|
||||
use chrono::Utc;
|
||||
use ipnet::IpNet;
|
||||
use nx9_wg_core::types::firewall::{
|
||||
FirewallAction, FirewallDirection, FirewallProtocol, FirewallRule,
|
||||
};
|
||||
use nx9_wg_core::types::network::Route;
|
||||
use nx9_wg_network::{NetworkEngine, NftablesRulesetBuilder, SimulatedNetworkEngine};
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_network_engine_routes_and_firewall_lifecycle() {
|
||||
let engine = SimulatedNetworkEngine::new();
|
||||
let now = Utc::now().naive_utc();
|
||||
|
||||
// 1. Sync routes
|
||||
let r1 = Route {
|
||||
id: Uuid::new_v4(),
|
||||
network_id: None,
|
||||
interface_id: None,
|
||||
destination: IpNet::from_str("192.168.10.0/24").unwrap(),
|
||||
gateway: Some(IpAddr::from_str("10.0.0.1").unwrap()),
|
||||
interface_name: Some("wg0".to_string()),
|
||||
metric: Some(100),
|
||||
enabled: true,
|
||||
description: None,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
};
|
||||
|
||||
let r2 = Route {
|
||||
id: Uuid::new_v4(),
|
||||
network_id: None,
|
||||
interface_id: None,
|
||||
destination: IpNet::from_str("192.168.20.0/24").unwrap(),
|
||||
gateway: None,
|
||||
interface_name: Some("wg0".to_string()),
|
||||
metric: None,
|
||||
enabled: false, // disabled route should not be synchronized
|
||||
description: None,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
};
|
||||
|
||||
engine.sync_routes(&[r1, r2]).await.expect("sync routes");
|
||||
|
||||
// 2. Sync firewall rules & NAT
|
||||
let fw1 = FirewallRule {
|
||||
id: Uuid::new_v4(),
|
||||
name: "Allow WireGuard Port".to_string(),
|
||||
interface_id: None,
|
||||
peer_id: None,
|
||||
direction: FirewallDirection::In,
|
||||
action: FirewallAction::Accept,
|
||||
protocol: FirewallProtocol::Udp,
|
||||
source: None,
|
||||
destination: None,
|
||||
source_port: None,
|
||||
destination_port: Some(51820),
|
||||
port_range: None,
|
||||
priority: 1,
|
||||
enabled: true,
|
||||
description: None,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
};
|
||||
|
||||
let subnets = vec![
|
||||
IpNet::from_str("10.0.0.0/24").unwrap(),
|
||||
IpNet::from_str("fd00::/64").unwrap(),
|
||||
];
|
||||
|
||||
engine
|
||||
.sync_firewall(&[fw1], true, &subnets)
|
||||
.await
|
||||
.expect("sync firewall");
|
||||
|
||||
let ruleset = engine
|
||||
.get_active_nftables_ruleset()
|
||||
.await
|
||||
.expect("get ruleset");
|
||||
|
||||
assert!(ruleset.contains("table inet nx9_wg"));
|
||||
assert!(ruleset.contains("udp dport 51820 accept"));
|
||||
assert!(ruleset.contains("ip saddr 10.0.0.0/24 oifname != \"wg*\" masquerade"));
|
||||
assert!(ruleset.contains("ip6 saddr fd00::/64 oifname != \"wg*\" masquerade"));
|
||||
|
||||
// 3. IP Forwarding inspection
|
||||
let status = engine.get_forwarding_status().await.expect("forwarding");
|
||||
assert!(status.ipv4_enabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nftables_builder_ordering_and_rules() {
|
||||
let now = Utc::now().naive_utc();
|
||||
|
||||
let r_prio10 = FirewallRule {
|
||||
id: Uuid::new_v4(),
|
||||
name: "Low Priority Accept".to_string(),
|
||||
interface_id: None,
|
||||
peer_id: None,
|
||||
direction: FirewallDirection::In,
|
||||
action: FirewallAction::Accept,
|
||||
protocol: FirewallProtocol::Tcp,
|
||||
source: None,
|
||||
destination: None,
|
||||
source_port: None,
|
||||
destination_port: Some(80),
|
||||
port_range: None,
|
||||
priority: 10,
|
||||
enabled: true,
|
||||
description: None,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
};
|
||||
|
||||
let r_prio1 = FirewallRule {
|
||||
id: Uuid::new_v4(),
|
||||
name: "High Priority Drop".to_string(),
|
||||
interface_id: None,
|
||||
peer_id: None,
|
||||
direction: FirewallDirection::In,
|
||||
action: FirewallAction::Drop,
|
||||
protocol: FirewallProtocol::Tcp,
|
||||
source: Some("1.2.3.4".to_string()),
|
||||
destination: None,
|
||||
source_port: None,
|
||||
destination_port: Some(80),
|
||||
port_range: None,
|
||||
priority: 1,
|
||||
enabled: true,
|
||||
description: None,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
};
|
||||
|
||||
let subnets = vec![IpNet::from_str("10.0.0.0/24").unwrap()];
|
||||
let ruleset = NftablesRulesetBuilder::build(&[r_prio10, r_prio1], false, &subnets);
|
||||
|
||||
// High priority drop (priority 1) must appear before low priority accept (priority 10)
|
||||
let drop_idx = ruleset.find("1.2.3.4").expect("drop rule");
|
||||
let accept_idx = ruleset.find("dport 80 accept").expect("accept rule");
|
||||
assert!(
|
||||
drop_idx < accept_idx,
|
||||
"Higher priority rule (1) must appear before lower priority rule (10)"
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user