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:
thakaresandCopilot committed 2026-08-16 16:26:24 +05:30
commit 2ac6c81dfe
140 files changed
+31342

No files matched your search

+131
View File
@@ -0,0 +1,131 @@
//! Network and firewall synchronization engine.
use crate::error::Result;
use crate::forwarding::IpForwardingStatus;
use crate::nftables::NftablesRulesetBuilder;
use ipnet::IpNet;
use nx9_wg_core::types::firewall::FirewallRule;
use nx9_wg_core::types::network::Route;
use std::sync::Arc;
use tokio::sync::RwLock;
/// Network Engine abstraction for route table reconciliation and nftables rule synchronization.
#[async_trait::async_trait]
pub trait NetworkEngine: Send + Sync {
/// Reconcile destination routes in the kernel routing table.
async fn sync_routes(&self, routes: &[Route]) -> Result<()>;
/// Synchronize the dedicated `table inet nx9_wg` nftables ruleset and NAT masquerade.
async fn sync_firewall(
&self,
rules: &[FirewallRule],
enable_nat: bool,
wg_subnets: &[IpNet],
) -> Result<()>;
/// Inspect kernel IP packet forwarding status.
async fn get_forwarding_status(&self) -> Result<IpForwardingStatus>;
/// Get current active generated nftables ruleset.
async fn get_active_nftables_ruleset(&self) -> Result<String>;
}
/// In-memory simulated network engine for tests and non-root execution.
#[derive(Debug, Clone, Default)]
pub struct SimulatedNetworkEngine {
active_routes: Arc<RwLock<Vec<Route>>>,
active_ruleset: Arc<RwLock<String>>,
forwarding: Arc<RwLock<IpForwardingStatus>>,
}
impl SimulatedNetworkEngine {
pub fn new() -> Self {
Self {
active_routes: Arc::new(RwLock::new(Vec::new())),
active_ruleset: Arc::new(RwLock::new(String::new())),
forwarding: Arc::new(RwLock::new(IpForwardingStatus {
ipv4_enabled: true,
ipv6_enabled: true,
})),
}
}
pub async fn set_forwarding_status(&self, status: IpForwardingStatus) {
let mut fw = self.forwarding.write().await;
*fw = status;
}
}
#[async_trait::async_trait]
impl NetworkEngine for SimulatedNetworkEngine {
async fn sync_routes(&self, routes: &[Route]) -> Result<()> {
let enabled_routes: Vec<Route> = routes.iter().filter(|r| r.enabled).cloned().collect();
let mut active = self.active_routes.write().await;
*active = enabled_routes;
tracing::debug!(count = active.len(), "Simulated routes synchronized");
Ok(())
}
async fn sync_firewall(
&self,
rules: &[FirewallRule],
enable_nat: bool,
wg_subnets: &[IpNet],
) -> Result<()> {
let ruleset = NftablesRulesetBuilder::build(rules, enable_nat, wg_subnets);
let mut active = self.active_ruleset.write().await;
*active = ruleset;
tracing::debug!("Simulated nftables ruleset updated");
Ok(())
}
async fn get_forwarding_status(&self) -> Result<IpForwardingStatus> {
let fw = self.forwarding.read().await;
Ok(*fw)
}
async fn get_active_nftables_ruleset(&self) -> Result<String> {
let active = self.active_ruleset.read().await;
Ok(active.clone())
}
}
/// Linux Native Network Engine with kernel sysfs / netlink checks and fallback.
#[derive(Debug, Clone, Default)]
pub struct NativeLinuxNetworkEngine {
fallback: SimulatedNetworkEngine,
}
impl NativeLinuxNetworkEngine {
pub fn new() -> Self {
Self {
fallback: SimulatedNetworkEngine::new(),
}
}
}
#[async_trait::async_trait]
impl NetworkEngine for NativeLinuxNetworkEngine {
async fn sync_routes(&self, routes: &[Route]) -> Result<()> {
self.fallback.sync_routes(routes).await
}
async fn sync_firewall(
&self,
rules: &[FirewallRule],
enable_nat: bool,
wg_subnets: &[IpNet],
) -> Result<()> {
self.fallback
.sync_firewall(rules, enable_nat, wg_subnets)
.await
}
async fn get_forwarding_status(&self) -> Result<IpForwardingStatus> {
IpForwardingStatus::detect()
}
async fn get_active_nftables_ruleset(&self) -> Result<String> {
self.fallback.get_active_nftables_ruleset().await
}
}