Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
b26e109
version crate, structs and tower layer
j-chmielewski Aug 5, 2025
2e0a582
DefguardVersionLayer::make_layer()
j-chmielewski Aug 5, 2025
c3af6f6
working interceptor-based middleware
j-chmielewski Aug 6, 2025
1e7c7df
remove tower dependency
j-chmielewski Aug 6, 2025
891ae49
cleanup
j-chmielewski Aug 6, 2025
5b5bb74
wip try to use shared version set, tonnic typing issues
j-chmielewski Aug 6, 2025
17af171
initial server middleware implementation
j-chmielewski Aug 7, 2025
689f882
wip try to implement DefguardVersion Layer and Middleware, new typing…
j-chmielewski Aug 7, 2025
9ee0f2c
client versioning stack
j-chmielewski Aug 7, 2025
8c72d2a
cargo fmt
j-chmielewski Aug 7, 2025
581cdbc
DefguardVersionMiddleware holds and sets own and remote component infos
j-chmielewski Aug 7, 2025
10a0ffa
cleanup server
j-chmielewski Aug 7, 2025
c95ce47
DefguardVersionClientLayer holds and sets own and remote version
j-chmielewski Aug 7, 2025
fed8c47
also send / parse system info
j-chmielewski Aug 7, 2025
c8a3d0f
remove unused import
j-chmielewski Aug 7, 2025
85f1a24
tracing-version integration
j-chmielewski Aug 7, 2025
961f206
format
j-chmielewski Aug 8, 2025
e16032f
remove unused enum
j-chmielewski Aug 8, 2025
18bbd75
don't RwLock the whole DefguardVersionSet struct
j-chmielewski Aug 8, 2025
9b42618
remove SemanticVersion struct, use semver::Version instead
j-chmielewski Aug 8, 2025
286b817
parse_version_headers util fn
j-chmielewski Aug 8, 2025
307f98a
refactor parse_version_headers function
j-chmielewski Aug 8, 2025
766a73a
rename DefguardVersionMiddleware -> DefguardVersionServerMiddleware
j-chmielewski Aug 8, 2025
c9fce4b
versioned proxy communication
j-chmielewski Aug 8, 2025
771dfe6
don't version defguard binary crate
j-chmielewski Aug 8, 2025
05adc84
remove version-set struct, remove tracing
j-chmielewski Aug 8, 2025
242a6ea
version metadata parsing
j-chmielewski Aug 8, 2025
7d399f9
span-based version logging
j-chmielewski Aug 11, 2025
a4d6f91
move proxy message loop to separate, instrumented function
j-chmielewski Aug 11, 2025
9aeb381
ProxyMessageLoopContext struct
j-chmielewski Aug 11, 2025
a06433d
custom formatter:
j-chmielewski Aug 11, 2025
2c4a102
don't store own version in OnceLock, don't require own version in spa…
j-chmielewski Aug 11, 2025
237701a
extract and log gateway version info, apply to stats endpoint
j-chmielewski Aug 11, 2025
bddcc6a
version span for gateway config and updates endpoints
j-chmielewski Aug 11, 2025
d214a8e
extract and log core version
j-chmielewski Aug 11, 2025
9b16408
cleanup
j-chmielewski Aug 11, 2025
b0b6233
clippy fixes
j-chmielewski Aug 11, 2025
b6b1543
skip logging version fields to avoid duplication
j-chmielewski Aug 12, 2025
771d360
version info at the end of the log line
j-chmielewski Aug 12, 2025
5925f5c
restore colored output
j-chmielewski Aug 12, 2025
a2b4b7c
clippy fixes
j-chmielewski Aug 12, 2025
cd90229
remove unused dependency
j-chmielewski Aug 12, 2025
8c342d6
rename VersionPrefixFormat -> VersionSuffixFormat
j-chmielewski Aug 13, 2025
6432ccd
use interceptor instead of tower service for client-side
j-chmielewski Aug 13, 2025
dc7e5d4
don't fail on version parsing issues
j-chmielewski Aug 13, 2025
53d5592
make structs and methods accessible from external crates
j-chmielewski Aug 13, 2025
0d8e6d5
expose commonly used functions to avoid code duplication
j-chmielewski Aug 13, 2025
6bbeb80
fix biometric_auth_down migration
j-chmielewski Aug 13, 2025
b671562
remove unwrap
j-chmielewski Aug 13, 2025
317154b
version info from metadata function
j-chmielewski Aug 14, 2025
a39390f
fmt
j-chmielewski Aug 14, 2025
39540ba
Merge branch 'release/1.5-alpha' into versions-merger
j-chmielewski Aug 14, 2025
be0d27a
Merge branch 'release/1.5-alpha' into versions-merger
j-chmielewski Aug 18, 2025
cdba82f
bump tonic-middleware to 0.4 (compatible with tonic 0.14)
j-chmielewski Aug 18, 2025
1289791
remove tonic-middleware - does not work with our interceptors
j-chmielewski Aug 18, 2025
4c42d09
rewrite server components - don't use tonic-middleware
j-chmielewski Aug 18, 2025
c1cc9e4
fix tls issue
j-chmielewski Aug 18, 2025
3ad0138
fmt
j-chmielewski Aug 18, 2025
4d1be6e
parse server version headers once
j-chmielewski Aug 18, 2025
d139c82
server comments
j-chmielewski Aug 18, 2025
979b982
avoid redefining of tracing fields
j-chmielewski Aug 18, 2025
d0d1878
client docs
j-chmielewski Aug 18, 2025
eccb395
lib comments
j-chmielewski Aug 18, 2025
cfc3622
cleanup tracing comments
j-chmielewski Aug 18, 2025
6373859
cargo fmt
j-chmielewski Aug 19, 2025
2e98f95
tracing module comments
j-chmielewski Aug 19, 2025
2d9192d
strong typing for VersionSuffixFormat version fields
j-chmielewski Aug 19, 2025
e41b087
review: rename headers, remove bitness
j-chmielewski Aug 19, 2025
e18a3ed
review: use std::fmt
j-chmielewski Aug 19, 2025
d3080be
inline string formatting
j-chmielewski Aug 19, 2025
4101bfe
Merge branch 'release/1.5-alpha' into versions
j-chmielewski Aug 19, 2025
b1d5f11
cargo fmt
j-chmielewski Aug 19, 2025
450d631
fix try_from_header after bitness removal
j-chmielewski Aug 19, 2025
03f04db
use String::push_str instead of format! macro in tracing module
j-chmielewski Aug 19, 2025
04976c2
build_version_info unit tests
j-chmielewski Aug 19, 2025
5a802f5
nix flake update
j-chmielewski Aug 19, 2025
b425c15
fix doctests
j-chmielewski Aug 19, 2025
b209b62
cargo fmt
j-chmielewski Aug 19, 2025
8288cf8
extract all span info from current span, don't traverse parents
j-chmielewski Aug 19, 2025
f8a5b57
GatewayServer::extract_metadata utility function
j-chmielewski Aug 20, 2025
d3343f8
log disconnection error message
j-chmielewski Aug 20, 2025
a2f27b7
Merge branch 'release/1.5-alpha' into versions-merger
j-chmielewski Aug 20, 2025
b911a1a
clippy fixes
j-chmielewski Aug 20, 2025
cb496a9
clone_from() instead of reassignment
j-chmielewski Aug 20, 2025
edf8d42
store single component info in ExtractedVersionInfo struct
j-chmielewski Aug 20, 2025
81d0ddb
rewrite tracing methods to use the new ExtractedVersionInfo struct
j-chmielewski Aug 20, 2025
159b4ed
cargo fmt
j-chmielewski Aug 20, 2025
f15a420
fix FieldFilterVisitor to work with new field names
j-chmielewski Aug 20, 2025
d907352
bring back traversing the span hierarchy to extract field values
j-chmielewski Aug 20, 2025
1daa09c
fix string-typing with DefguardComponent struct
j-chmielewski Aug 21, 2025
41c2daf
use DefguardComponent enum in span definitions
j-chmielewski Aug 21, 2025
dda78a2
improve parse_metadata typing
j-chmielewski Aug 21, 2025
8251eea
take Version in constructors / initializers instead of &str
j-chmielewski Aug 21, 2025
eadf3d8
better span name
j-chmielewski Aug 21, 2025
122541a
re-export semver::Error to be used by downstream crates
j-chmielewski Aug 21, 2025
cfc8786
escape newline characters in log lines
j-chmielewski Aug 21, 2025
2d5f8c4
lib rustdoc
j-chmielewski Aug 21, 2025
06727ec
update rustdoc comments
j-chmielewski Aug 21, 2025
0e2f3ad
Merge branch 'release/1.5-alpha' into versions-merger
j-chmielewski Aug 21, 2025
30c81e9
cargo fmt
j-chmielewski Aug 21, 2025
7a56987
use aws cached rust image
j-chmielewski Aug 21, 2025
b937995
clippy fix
j-chmielewski Aug 21, 2025
18e7e7d
allow AGPL-3.0-only license in defguard_version crate
j-chmielewski Aug 21, 2025
cee90c2
run cargo-deny manually instead of using gh-action
j-chmielewski Aug 21, 2025
aaab364
sort import statements
j-chmielewski Aug 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on:
- codebuild-defguard-core-runner-${{ github.run_id }}-${{ github.run_attempt }}

container: rust:1
container: public.ecr.aws/docker/library/rust:1

services:
postgres:
Expand Down Expand Up @@ -72,7 +72,9 @@ jobs:
cargo clippy --all-targets --all-features -- -D warnings

- name: Run cargo deny
uses: EmbarkStudios/cargo-deny-action@v2
run: |
cargo install cargo-deny
cargo deny check

- name: Install nextest
uses: taiki-e/install-action@nextest
Expand Down
53 changes: 52 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ resolver = "2"
defguard_core = { path = "./crates/defguard_core", version = "1.5.0" }
defguard_event_logger = { path = "./crates/defguard_event_logger", version = "0.0.0" }
defguard_event_router = { path = "./crates/defguard_event_router", version = "0.0.0" }
defguard_version = { path = "./crates/defguard_version", version = "0.0.0" }
defguard_web_ui = { path = "./crates/defguard_web_ui", version = "0.0.0" }
model_derive = { path = "./crates/model_derive", version = "0.0.0" }

Expand Down
3 changes: 2 additions & 1 deletion crates/defguard/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "defguard"
version = "1.5.0"
version = "0.0.0"
Comment thread
j-chmielewski marked this conversation as resolved.
edition.workspace = true
license-file.workspace = true
homepage.workspace = true
Expand All @@ -12,6 +12,7 @@ rust-version.workspace = true
defguard_core = { workspace = true }
defguard_event_router = { workspace = true }
defguard_event_logger = { workspace = true }
defguard_version = { workspace = true }

# external dependencies
anyhow = { workspace = true }
Expand Down
21 changes: 9 additions & 12 deletions crates/defguard/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use bytes::Bytes;
use secrecy::ExposeSecret;
use std::{
fs::read_to_string,
sync::{Arc, Mutex},
};
use tokio::sync::{broadcast, mpsc::unbounded_channel};

use bytes::Bytes;
use defguard_core::{
SERVER_CONFIG, VERSION,
auth::failed_login::FailedLoginMap,
Expand All @@ -28,9 +30,6 @@ use defguard_core::{
};
use defguard_event_logger::{message::EventLoggerMessage, run_event_logger};
use defguard_event_router::{RouterReceiverSet, run_event_router};
use secrecy::ExposeSecret;
use tokio::sync::{broadcast, mpsc::unbounded_channel};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

#[macro_use]
extern crate tracing;
Expand All @@ -42,14 +41,12 @@ async fn main() -> Result<(), anyhow::Error> {
}
let config = DefGuardConfig::new();
SERVER_CONFIG.set(config.clone())?;
// initialize tracing
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| format!("{},h2=info", config.log_level).into()),
)
.with(tracing_subscriber::fmt::layer())
.init();

// initialize tracing with version formatter
defguard_version::tracing::init(
defguard_version::Version::parse(VERSION)?,
&config.log_level,
)?;

info!("Starting ... version v{}", VERSION);
debug!("Using config: {config:?}");
Expand Down
2 changes: 2 additions & 0 deletions crates/defguard_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ rust-version.workspace = true
[dependencies]
# internal crates
defguard_web_ui = { workspace = true }
defguard_version = { workspace = true }
model_derive = { workspace = true }

# external dependencies
Expand Down Expand Up @@ -85,6 +86,7 @@ strum = { workspace = true }
strum_macros = { workspace = true }
bytes = { workspace = true }
ed25519-dalek = { version = "2.2.0", features = ["rand_core"] }
tower = "0.5.2"

# https://github.com/juhaku/utoipa/issues/1345
[dependencies.zip]
Expand Down
79 changes: 56 additions & 23 deletions crates/defguard_core/src/grpc/gateway/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::{

use chrono::{DateTime, TimeDelta, Utc};
use client_state::ClientMap;
use defguard_version::{DefguardComponent, version_info_from_metadata};
use sqlx::{Error as SqlxError, PgExecutor, PgPool, query};
use thiserror::Error;
use tokio::{
Expand Down Expand Up @@ -127,6 +128,14 @@ impl WireguardNetwork<Id> {
}
}

/// Utility struct encapsulating commonly extracted metadata fields during gRPC communication.
struct GatewayMetadata {
network_id: Id,
hostname: String,
version: String,
info: String,
}

impl GatewayServer {
/// Create new gateway server instance
#[must_use]
Expand Down Expand Up @@ -158,10 +167,10 @@ impl GatewayServer {
}

// parse network id from gateway request metadata from intercepted information from JWT token
fn get_network_id_from_metadata(metadata: &MetadataMap) -> Option<i64> {
fn get_network_id_from_metadata(metadata: &MetadataMap) -> Option<Id> {
if let Some(ascii_value) = metadata.get("gateway_network_id") {
if let Ok(slice) = ascii_value.clone().to_str() {
if let Ok(id) = slice.parse::<i64>() {
if let Ok(id) = slice.parse::<Id>() {
return Some(id);
}
}
Expand Down Expand Up @@ -276,6 +285,17 @@ impl GatewayServer {

Ok(user)
}

/// Utility function extracting metadata fields during gRPC communication.
fn extract_metadata(metadata: &MetadataMap) -> Result<GatewayMetadata, Status> {
let (version, info) = version_info_from_metadata(metadata);
Ok(GatewayMetadata {
network_id: Self::get_network_id(metadata)?,
hostname: Self::get_gateway_hostname(metadata)?,
version,
info,
})
}
}

fn gen_config(
Expand Down Expand Up @@ -721,11 +741,17 @@ impl gateway_service_server::GatewayService for GatewayServer {
&self,
request: Request<tonic::Streaming<StatsUpdate>>,
) -> Result<Response<()>, Status> {
let network_id = Self::get_network_id(request.metadata())?;
let gateway_hostname = Self::get_gateway_hostname(request.metadata())?;
let GatewayMetadata {
network_id,
hostname,
version,
info,
} = Self::extract_metadata(request.metadata())?;
let mut stream = request.into_inner();
let mut disconnect_timer = interval(Duration::from_secs(PEER_DISCONNECT_INTERVAL));

let span = tracing::info_span!("gateway_stats", component = %DefguardComponent::Gateway, version, info);
let _guard = span.enter();
loop {
// wait for a message or update client map at least once a mninute if no messages are received
let stats_update = tokio::select! {
Expand Down Expand Up @@ -821,7 +847,7 @@ impl gateway_service_server::GatewayService for GatewayServer {
// mark new VPN client as connected
client_map.connect_vpn_client(
network_id,
&gateway_hostname,
&hostname,
&public_key,
&device,
&user,
Expand Down Expand Up @@ -884,8 +910,14 @@ impl gateway_service_server::GatewayService for GatewayServer {
request: Request<ConfigurationRequest>,
) -> Result<Response<Configuration>, Status> {
debug!("Sending configuration to gateway client.");
let network_id = Self::get_network_id(request.metadata())?;
let hostname = Self::get_gateway_hostname(request.metadata())?;
let GatewayMetadata {
network_id,
hostname,
version,
info,
} = Self::extract_metadata(request.metadata())?;
let span = tracing::info_span!("gateway_config", component = %DefguardComponent::Gateway, version, info);
let _guard = span.enter();

let mut conn = self.pool.acquire().await.map_err(|e| {
error!("Failed to acquire DB connection: {e}");
Expand Down Expand Up @@ -956,22 +988,28 @@ impl gateway_service_server::GatewayService for GatewayServer {
}

async fn updates(&self, request: Request<()>) -> Result<Response<Self::UpdatesStream>, Status> {
let gateway_network_id = Self::get_network_id(request.metadata())?;
let hostname = Self::get_gateway_hostname(request.metadata())?;
let GatewayMetadata {
network_id,
hostname,
version,
info,
} = Self::extract_metadata(request.metadata())?;
let span = tracing::info_span!("gateway_updates", component = %DefguardComponent::Gateway, version, info);
let _guard = span.enter();

let Some(network) = WireguardNetwork::find_by_id(&self.pool, gateway_network_id)
let Some(network) = WireguardNetwork::find_by_id(&self.pool, network_id)
.await
.map_err(|_| {
error!("Failed to fetch network {gateway_network_id} from the database");
error!("Failed to fetch network {network_id} from the database");
Status::new(
Code::Internal,
format!("Failed to retrieve network {gateway_network_id} from the database"),
format!("Failed to retrieve network {network_id} from the database"),
)
})?
else {
return Err(Status::new(
Code::Internal,
format!("Network with id {gateway_network_id} not found"),
format!("Network with id {network_id} not found"),
));
};

Expand All @@ -981,9 +1019,9 @@ impl gateway_service_server::GatewayService for GatewayServer {
let events_rx = self.wireguard_tx.subscribe();
let mut state = self.gateway_state.lock().unwrap();
state
.connect_gateway(gateway_network_id, &hostname, &self.pool)
.connect_gateway(network_id, &hostname, &self.pool)
.map_err(|err| {
error!("Failed to connect gateway on network {gateway_network_id}: {err}");
error!("Failed to connect gateway on network {network_id}: {err}");
Status::new(
Code::Internal,
"Failed to connect gateway on network {gateway_network_id}",
Expand All @@ -993,20 +1031,15 @@ impl gateway_service_server::GatewayService for GatewayServer {
// clone here before moving into a closure
let gateway_hostname = hostname.clone();
let handle = tokio::spawn(async move {
let mut update_handler = GatewayUpdatesHandler::new(
gateway_network_id,
network,
gateway_hostname,
events_rx,
tx,
);
let mut update_handler =
GatewayUpdatesHandler::new(network_id, network, gateway_hostname, events_rx, tx);
update_handler.run().await;
});

Ok(Response::new(GatewayUpdatesStream::new(
handle,
rx,
gateway_network_id,
network_id,
hostname,
Arc::clone(&self.gateway_state),
self.pool.clone(),
Expand Down
Loading