Skip to content
Open
51 changes: 28 additions & 23 deletions crates/defguard/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use defguard_core::{
limits::update_counts,
},
events::{ApiEvent, BidiStreamEvent},
gateway_config,
grpc::{GatewayEvent, WorkerState, run_grpc_server},
init_dev_env, init_vpn_location, run_web_server,
setup_logs::CoreSetupLogLayer,
Expand Down Expand Up @@ -83,6 +84,29 @@ async fn main() -> Result<(), anyhow::Error> {
)
.await;

if config.openid_signing_key.is_some() {
info!("Using RSA OpenID signing key");
} else {
info!("Using HMAC OpenID signing key");
}

// initialize global settings struct
initialize_current_settings(&pool).await?;

debug!("Checking enterprise license status");
match License::load_or_renew(&pool).await {
Ok(license) => {
set_cached_license(license);
}
Err(err) => {
warn!(
"There was an error while loading the license, error: {err}. The enterprise \
features will be disabled."
);
set_cached_license(None);
}
}

// handle optional subcommands
if let Some(command) = &config.cmd {
match command {
Expand All @@ -93,21 +117,16 @@ async fn main() -> Result<(), anyhow::Error> {
let token = init_vpn_location(&pool, args).await?;
println!("{token}");
}
Command::GatewayConfig(args) => {
let config = gateway_config(&pool, args).await?;
println!("{config:#?}");
}
}

// return early
return Ok(());
}

if config.openid_signing_key.is_some() {
info!("Using RSA OpenID signing key");
} else {
info!("Using HMAC OpenID signing key");
}

// initialize global settings struct
initialize_current_settings(&pool).await?;

// Both flags must be provided together
if let Err(msg) = config.validate_adopt_flags() {
anyhow::bail!("{msg}");
Expand Down Expand Up @@ -212,20 +231,6 @@ async fn main() -> Result<(), anyhow::Error> {

update_counts(&pool).await?;

debug!("Checking enterprise license status");
match License::load_or_renew(&pool).await {
Ok(license) => {
set_cached_license(license);
}
Err(err) => {
warn!(
"There was an error while loading the license, error: {err}. The enterprise \
features will be disabled."
);
set_cached_license(None);
}
}

let (proxy_control_tx, proxy_control_rx) = channel::<ProxyControlMessage>(100);
let proxy_secret_key = settings.secret_key_required()?;
let proxy_manager = ProxyManager::new(
Expand Down
8 changes: 8 additions & 0 deletions crates/defguard_common/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ pub enum Command {
about = "Add a new VPN location and return a gateway token. Used for automated setup."
)]
InitVpnLocation(InitVpnLocationArgs),
#[command(about = "Output the gateway gRPC configuration payload for a VPN location by ID.")]
GatewayConfig(GatewayConfigArgs),
}

#[derive(Args, Debug, Clone)]
Expand All @@ -215,6 +217,12 @@ pub struct InitVpnLocationArgs {
pub id: Option<i64>,
}

#[derive(Args, Debug, Clone)]
pub struct GatewayConfigArgs {
#[arg(long)]
pub location_id: i64,
}

impl DefGuardConfig {
#[must_use]
pub fn new() -> Self {
Expand Down
48 changes: 46 additions & 2 deletions crates/defguard_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use defguard_certs::CertificateAuthority;
use defguard_common::{
VERSION,
auth::claims::{Claims, ClaimsType},
config::{DefGuardConfig, InitVpnLocationArgs, server_config},
config::{DefGuardConfig, GatewayConfigArgs, InitVpnLocationArgs, server_config},
db::{
init_db,
models::{
Expand All @@ -28,6 +28,7 @@ use defguard_common::{
},
types::proxy::ProxyControlMessage,
};
use defguard_proto::gateway::Configuration;
use defguard_version::server::DefguardVersionLayer;
use defguard_web_ui::{index, svg, web_asset};
use events::ApiEvent;
Expand Down Expand Up @@ -76,6 +77,7 @@ use crate::{
auth::failed_login::FailedLoginMap,
db::AppEvent,
enterprise::{
firewall::try_get_location_firewall_config,
handlers::{
acl::{
alias::{
Expand Down Expand Up @@ -167,7 +169,9 @@ use crate::{
},
worker::{create_job, create_worker_token, job_status, list_workers, remove_worker},
},
location_management::sync_location_allowed_devices,
location_management::{
allowed_peers::get_location_allowed_peers, sync_location_allowed_devices,
},
version::IncompatibleComponents,
};

Expand Down Expand Up @@ -929,6 +933,46 @@ pub async fn init_vpn_location(
Ok(token)
}

pub async fn gateway_config(
pool: &PgPool,
args: &GatewayConfigArgs,
) -> Result<Configuration, anyhow::Error> {
let location_id = args.location_id;

let mut conn = pool.acquire().await?;

// fetch specified location
let location = match WireguardNetwork::find_by_id(&mut *conn, location_id).await {
Ok(Some(network)) => network,
Ok(None) => return Err(anyhow!("Location {location_id} not found")),
Err(err) => {
return Err(anyhow!(
"Failed to rerieve location {location_id} with error: {err}"
));
}
};

// get peers
let peers = get_location_allowed_peers(&location, &mut *conn)
.await
.map_err(|err| anyhow!("Failed to get peers for location {location} with error: {err}"))?;

// prepare firewall config
let maybe_firewall_config = try_get_location_firewall_config(&location, &mut conn)
.await
.map_err(|err| {
anyhow!("Failed to prepare firewall config for location {location} with error: {err}")
})?;

// generate config
let mut config = Configuration::new(&location, peers, maybe_firewall_config);

// overwrite private key just in case
config.prvkey = "REDACTED".into();

Ok(config)
}

pub fn is_valid_phone_number(number: &str) -> bool {
PHONE_NUMBER_REGEX.is_match(number)
}
Expand Down
20 changes: 1 addition & 19 deletions crates/defguard_gateway_manager/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl GatewayHandler {
let peers = get_location_allowed_peers(&network, &self.pool).await?;

let maybe_firewall_config = try_get_location_firewall_config(&network, &mut conn).await?;
let payload = Some(core_response::Payload::Config(gen_config(
let payload = Some(core_response::Payload::Config(Configuration::new(
&network,
peers,
maybe_firewall_config,
Expand Down Expand Up @@ -846,24 +846,6 @@ fn try_protos_into_stats_message(
latest_handshake,
))
}

fn gen_config(
network: &WireguardNetwork<Id>,
peers: Vec<Peer>,
maybe_firewall_config: Option<FirewallConfig>,
) -> Configuration {
Configuration {
name: network.name.clone(),
port: network.port.cast_unsigned(),
prvkey: network.prvkey.clone(),
addresses: network.address().iter().map(ToString::to_string).collect(),
peers,
firewall_config: maybe_firewall_config,
mtu: network.mtu.cast_unsigned(),
fwmark: network.fwmark as u32,
}
}

#[cfg(test)]
mod tests {
use std::{collections::HashMap, net::IpAddr, str::FromStr, sync::Arc};
Expand Down
28 changes: 26 additions & 2 deletions crates/defguard_proto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,23 @@ pub mod enterprise {
use defguard_common::{
csv::AsCsv,
db::{
Id,
models::{
Device, DeviceConfig, User,
vpn_client_session::VpnClientMfaMethod,
wireguard::{LocationMfaMode, ServiceLocationMode},
Device, DeviceConfig, User, WireguardNetwork,
},
Id,
},
};
use proxy::{CoreError, MfaMethod};
use serde::Serialize;
use tonic::Status;

use crate::{
enterprise::firewall::FirewallConfig,
gateway::{Configuration, Peer},
};

// Client MFA methods
impl fmt::Display for MfaMethod {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -159,3 +164,22 @@ impl From<ServiceLocationMode> for proxy::ServiceLocationMode {
}
}
}

impl Configuration {
pub fn new(
location: &WireguardNetwork<Id>,
peers: Vec<Peer>,
maybe_firewall_config: Option<FirewallConfig>,
) -> Self {
Self {
name: location.name.clone(),
port: location.port.cast_unsigned(),
prvkey: location.prvkey.clone(),
addresses: location.address().iter().map(ToString::to_string).collect(),
peers,
firewall_config: maybe_firewall_config,
mtu: location.mtu.cast_unsigned(),
fwmark: location.fwmark as u32,
}
}
}
3 changes: 0 additions & 3 deletions migrations/20251125072923_network_gateways.down.sql

This file was deleted.

20 changes: 0 additions & 20 deletions migrations/20251125072923_network_gateways.up.sql

This file was deleted.

3 changes: 0 additions & 3 deletions migrations/20251218140442_[2.0.0]_core_ca.down.sql

This file was deleted.

3 changes: 0 additions & 3 deletions migrations/20251218140442_[2.0.0]_core_ca.up.sql

This file was deleted.

Loading
Loading