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,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
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user