Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 2s
CI/CD Pipeline / Clippy Lints (push) Successful in 44s
CI/CD Pipeline / Enrollment Tests (push) Has been skipped
CI/CD Pipeline / All Unit Tests (push) Successful in 1m12s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build Debian Package (Ubuntu 22.04) (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
CI/CD Pipeline / Security Audit (push) Successful in 4s
CI/CD Pipeline / Verify Enrollment CLI Flag (push) Successful in 55s
97 lines
3.4 KiB
Rust
97 lines
3.4 KiB
Rust
//! Self-enrollment module for linux_patch_api daemon.
|
|
//!
|
|
//! Handles secure registration with the patch manager, including
|
|
//! identity extraction (machine-id, FQDN, IPs, OS details) and
|
|
//! mTLS enrollment via the manager API.
|
|
|
|
pub mod client;
|
|
pub mod identity;
|
|
pub mod provision;
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
/// Re-export key types for ergonomic access from parent modules.
|
|
pub use client::{
|
|
EnrollmentClient, EnrollmentRequest, EnrollmentResponse, EnrollmentStatusResponse, PkiBundle,
|
|
};
|
|
/// Re-export identity extraction functions.
|
|
pub use identity::{
|
|
get_fqdn, get_ip_addresses, get_ip_for_interface, get_machine_id, get_os_details,
|
|
get_primary_ip, get_route_source_ip, is_container_bridge, is_link_local,
|
|
};
|
|
|
|
/// Run the full enrollment flow against the manager at the given URL.
|
|
///
|
|
/// # Phases
|
|
/// 1. **Registration** - POST machine identity to manager, receive polling token
|
|
/// 2. **Polling** - Poll manager for approval with configurable interval/max attempts
|
|
/// 3. **Provisioning** - Write PKI bundle to disk (certs/keys) and append manager IP to whitelist
|
|
///
|
|
/// # Errors
|
|
/// Returns Err on registration failure, polling timeout, denial, user interruption,
|
|
/// PKI provisioning failure, or whitelist update failure.
|
|
pub async fn run_enrollment(manager_url: &str, config: &super::AppConfig) -> Result<()> {
|
|
// Extract IP reporting overrides from enrollment config
|
|
let (report_interface, report_ip) = config
|
|
.enrollment
|
|
.as_ref()
|
|
.map(|e| (e.report_interface.clone(), e.report_ip.clone()))
|
|
.unwrap_or((None, None));
|
|
|
|
let client = EnrollmentClient::with_ip_overrides(manager_url, report_interface, report_ip);
|
|
|
|
// Phase 1: Registration
|
|
tracing::info!(
|
|
manager_url = manager_url,
|
|
"Starting enrollment - registration phase"
|
|
);
|
|
let response = client.register().await?;
|
|
tracing::info!("Registration successful - received polling token");
|
|
|
|
// Get polling config (use defaults if not set)
|
|
let interval = config
|
|
.enrollment
|
|
.as_ref()
|
|
.map(|e| e.polling_interval_seconds)
|
|
.unwrap_or(60);
|
|
let max_attempts = config
|
|
.enrollment
|
|
.as_ref()
|
|
.map(|e| e.max_poll_attempts)
|
|
.unwrap_or(1440);
|
|
|
|
// Phase 2: Polling
|
|
tracing::info!(
|
|
interval_seconds = interval,
|
|
max_attempts = max_attempts,
|
|
"Starting enrollment - polling phase"
|
|
);
|
|
let pki_bundle = client
|
|
.poll_for_approval(&response.polling_token, interval, max_attempts)
|
|
.await?;
|
|
|
|
// Phase 3: PKI provisioning & whitelist update
|
|
tracing::info!("Enrollment approved - starting PKI provisioning phase");
|
|
|
|
// Write certificates to configured paths (or defaults)
|
|
provision::provision_pki_bundle(
|
|
&pki_bundle.ca_crt,
|
|
&pki_bundle.server_crt,
|
|
&pki_bundle.server_key,
|
|
config.tls_config(),
|
|
)
|
|
.await?;
|
|
tracing::info!("PKI bundle written to disk");
|
|
|
|
// Resolve manager hostname to IP and append to whitelist
|
|
let manager_ip = client
|
|
.manager_ip()
|
|
.await
|
|
.context("Failed to resolve manager IP - cannot update whitelist")?;
|
|
provision::append_manager_to_whitelist(&manager_ip, config.whitelist_path()).await?;
|
|
tracing::info!(manager_ip = %manager_ip, "Manager IP appended to whitelist");
|
|
|
|
tracing::info!("Enrollment complete - PKI and whitelist configured");
|
|
Ok(())
|
|
}
|