From 1c7fe141d347186c1ffd865743901498ed406110 Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Fri, 22 Aug 2025 12:47:51 +0200 Subject: [PATCH 01/10] fix semver version --- src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 73847794..2c157057 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ mod grpc; mod handlers; pub mod http; pub mod logging; +mod version; pub(crate) mod proto { tonic::include_proto!("defguard.proxy"); @@ -14,4 +15,4 @@ pub(crate) mod proto { #[macro_use] extern crate tracing; -pub static VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), "-", env!("VERGEN_GIT_SHA")); +pub static VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), "+", env!("VERGEN_GIT_SHA")); From 987c4f786563296a3c7b374a5b0757e5c37b4ca4 Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Fri, 22 Aug 2025 13:11:21 +0200 Subject: [PATCH 02/10] implement core version check --- src/grpc.rs | 25 +++++++++++++++++++++++-- src/version.rs | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/version.rs diff --git a/src/grpc.rs b/src/grpc.rs index 40450e16..6c8e4737 100644 --- a/src/grpc.rs +++ b/src/grpc.rs @@ -11,11 +11,14 @@ use tokio_stream::wrappers::UnboundedReceiverStream; use tonic::{Request, Response, Status, Streaming}; use tracing::Instrument; -use defguard_version::{version_info_from_metadata, DefguardComponent}; +use defguard_version::{ + parse_metadata, version_info_from_metadata, ComponentInfo, DefguardComponent, +}; use crate::{ error::ApiError, proto::{core_request, core_response, proxy_server, CoreRequest, CoreResponse, DeviceInfo}, + version::is_core_version_supported, }; // connected clients @@ -86,6 +89,17 @@ impl Clone for ProxyServer { } } +fn get_tracing_variables(info: &Option) -> (String, String) { + let version = info + .as_ref() + .map_or(String::from("?"), |info| info.version.to_string()); + let info = info + .as_ref() + .map_or(String::from("?"), |info| info.system.to_string()); + + (version, info) +} + #[tonic::async_trait] impl proxy_server::Proxy for ProxyServer { type BidiStream = UnboundedReceiverStream>; @@ -100,9 +114,16 @@ impl proxy_server::Proxy for ProxyServer { error!("Failed to determine client address for request: {request:?}"); return Err(Status::internal("Failed to determine client address")); }; - let (version, info) = version_info_from_metadata(request.metadata()); + let maybe_info = parse_metadata(request.metadata()); + let (version, info) = get_tracing_variables(&maybe_info); let span = tracing::info_span!("core_bidi_stream", component = %DefguardComponent::Core, version, info); let _guard = span.enter(); + + // check core version and return if it's not supported + let version = maybe_info.as_ref().map(|info| &info.version); + if !is_core_version_supported(version) { + return Err(Status::internal("Unsupported core version")); + } info!("Defguard Core gRPC client connected from: {address}"); let (tx, rx) = mpsc::unbounded_channel(); diff --git a/src/version.rs b/src/version.rs new file mode 100644 index 00000000..a87fad6d --- /dev/null +++ b/src/version.rs @@ -0,0 +1,18 @@ +use defguard_version::Version; + +const MIN_CORE_VERSION: Version = Version::new(1, 5, 0); + +/// Checks if the core version meets minimum version requirements. +pub(crate) fn is_core_version_supported(core_version: Option<&Version>) -> bool { + let Some(core_version) = core_version else { + error!("Missing core component version information. This most likely means that core component uses unsupported version."); + return false; + }; + if core_version < &MIN_CORE_VERSION { + error!("Core version {core_version} is not supported. Minimal supported core version is {MIN_CORE_VERSION}. Exiting."); + return false; + } + + info!("Core version {core_version} is supported"); + true +} From ccd039ebcf1f3f91744e25df349a8355d27da80a Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Mon, 25 Aug 2025 09:57:33 +0200 Subject: [PATCH 03/10] use get_tracing_variables function from defguard_version crate --- Cargo.lock | 1 - Cargo.toml | 2 +- src/grpc.rs | 13 +------------ src/version.rs | 2 +- 4 files changed, 3 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e03a895c..e0c4d985 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -597,7 +597,6 @@ dependencies = [ [[package]] name = "defguard_version" version = "0.0.0" -source = "git+https://github.com/DefGuard/defguard.git?rev=f61ce40927a4d21095ea53a691219d5ae46e3e4e#f61ce40927a4d21095ea53a691219d5ae46e3e4e" dependencies = [ "http", "os_info", diff --git a/Cargo.toml b/Cargo.toml index 0c1ffebd..844e11c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ homepage = "https://github.com/DefGuard/proxy" repository = "https://github.com/DefGuard/proxy" [dependencies] -defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "f61ce40927a4d21095ea53a691219d5ae46e3e4e" } +defguard_version = { path = "../defguard/crates/defguard_version" } # base `axum` deps axum = { version = "0.7", features = ["macros", "tracing", "ws"] } axum-client-ip = "0.6" diff --git a/src/grpc.rs b/src/grpc.rs index 6c8e4737..cc5de3b7 100644 --- a/src/grpc.rs +++ b/src/grpc.rs @@ -12,7 +12,7 @@ use tonic::{Request, Response, Status, Streaming}; use tracing::Instrument; use defguard_version::{ - parse_metadata, version_info_from_metadata, ComponentInfo, DefguardComponent, + get_tracing_variables, parse_metadata, version_info_from_metadata, ComponentInfo, DefguardComponent }; use crate::{ @@ -89,17 +89,6 @@ impl Clone for ProxyServer { } } -fn get_tracing_variables(info: &Option) -> (String, String) { - let version = info - .as_ref() - .map_or(String::from("?"), |info| info.version.to_string()); - let info = info - .as_ref() - .map_or(String::from("?"), |info| info.system.to_string()); - - (version, info) -} - #[tonic::async_trait] impl proxy_server::Proxy for ProxyServer { type BidiStream = UnboundedReceiverStream>; diff --git a/src/version.rs b/src/version.rs index a87fad6d..2ca6093e 100644 --- a/src/version.rs +++ b/src/version.rs @@ -9,7 +9,7 @@ pub(crate) fn is_core_version_supported(core_version: Option<&Version>) -> bool return false; }; if core_version < &MIN_CORE_VERSION { - error!("Core version {core_version} is not supported. Minimal supported core version is {MIN_CORE_VERSION}. Exiting."); + error!("Core version {core_version} is not supported. Minimal supported core version is {MIN_CORE_VERSION}."); return false; } From 1af051830fb7bdeb3c9f436b879703565e07163e Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Tue, 26 Aug 2025 13:54:24 +0200 Subject: [PATCH 04/10] use version interceptor --- src/grpc.rs | 5 ----- src/http.rs | 9 ++++++++- src/version.rs | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/grpc.rs b/src/grpc.rs index cc5de3b7..a89ce1bf 100644 --- a/src/grpc.rs +++ b/src/grpc.rs @@ -108,11 +108,6 @@ impl proxy_server::Proxy for ProxyServer { let span = tracing::info_span!("core_bidi_stream", component = %DefguardComponent::Core, version, info); let _guard = span.enter(); - // check core version and return if it's not supported - let version = maybe_info.as_ref().map(|info| &info.version); - if !is_core_version_supported(version) { - return Err(Status::internal("Unsupported core version")); - } info!("Defguard Core gRPC client connected from: {address}"); let (tx, rx) = mpsc::unbounded_channel(); diff --git a/src/http.rs b/src/http.rs index 87d30fe1..5c87daf9 100644 --- a/src/http.rs +++ b/src/http.rs @@ -16,7 +16,10 @@ use axum::{ }; use axum_extra::extract::cookie::Key; use clap::crate_version; -use defguard_version::{server::DefguardVersionLayer, Version}; +use defguard_version::{ + server::{DefguardVersionInterceptor, DefguardVersionLayer}, + DefguardComponent, Version, +}; use serde::Serialize; use tokio::{net::TcpListener, sync::oneshot, task::JoinSet}; use tonic::transport::{Identity, Server, ServerTlsConfig}; @@ -36,6 +39,7 @@ use crate::{ grpc::ProxyServer, handlers::{desktop_client_mfa, enrollment, password_reset, polling}, proto::proxy_server, + version::MIN_CORE_VERSION, VERSION, }; @@ -170,6 +174,9 @@ pub async fn run_server(config: Config) -> anyhow::Result<()> { Server::builder() }; let versioned_service = ServiceBuilder::new() + .layer(tonic::service::InterceptorLayer::new( + DefguardVersionInterceptor::new(DefguardComponent::Core, MIN_CORE_VERSION), + )) .layer(DefguardVersionLayer::new(Version::parse(VERSION)?)) .service(proxy_server::ProxyServer::new(grpc_server)); builder diff --git a/src/version.rs b/src/version.rs index 2ca6093e..1332902b 100644 --- a/src/version.rs +++ b/src/version.rs @@ -1,6 +1,6 @@ use defguard_version::Version; -const MIN_CORE_VERSION: Version = Version::new(1, 5, 0); +pub const MIN_CORE_VERSION: Version = Version::new(1, 6, 0); /// Checks if the core version meets minimum version requirements. pub(crate) fn is_core_version_supported(core_version: Option<&Version>) -> bool { From 0704dd3bf2e4ad83f6bf10d63e6c76f2b5a8dbc7 Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Wed, 27 Aug 2025 10:52:45 +0200 Subject: [PATCH 05/10] use updated DefguardVersionInterceptor with relative version check --- src/http.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/http.rs b/src/http.rs index 5c87daf9..a3d5a5c3 100644 --- a/src/http.rs +++ b/src/http.rs @@ -173,11 +173,17 @@ pub async fn run_server(config: Config) -> anyhow::Result<()> { } else { Server::builder() }; + let own_version = Version::parse(VERSION)?; let versioned_service = ServiceBuilder::new() .layer(tonic::service::InterceptorLayer::new( - DefguardVersionInterceptor::new(DefguardComponent::Core, MIN_CORE_VERSION), + DefguardVersionInterceptor::new( + own_version.clone(), + DefguardComponent::Core, + MIN_CORE_VERSION, + false, + ), )) - .layer(DefguardVersionLayer::new(Version::parse(VERSION)?)) + .layer(DefguardVersionLayer::new(own_version)) .service(proxy_server::ProxyServer::new(grpc_server)); builder .add_service(versioned_service) From 6011a64901320e73b58043274081aa7a177436eb Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Wed, 27 Aug 2025 15:05:40 +0200 Subject: [PATCH 06/10] remove unused is_core_version_supported function --- src/grpc.rs | 5 +---- src/http.rs | 10 +--------- src/lib.rs | 4 +++- src/version.rs | 18 ------------------ 4 files changed, 5 insertions(+), 32 deletions(-) delete mode 100644 src/version.rs diff --git a/src/grpc.rs b/src/grpc.rs index a89ce1bf..f69a724a 100644 --- a/src/grpc.rs +++ b/src/grpc.rs @@ -11,14 +11,11 @@ use tokio_stream::wrappers::UnboundedReceiverStream; use tonic::{Request, Response, Status, Streaming}; use tracing::Instrument; -use defguard_version::{ - get_tracing_variables, parse_metadata, version_info_from_metadata, ComponentInfo, DefguardComponent -}; +use defguard_version::{get_tracing_variables, parse_metadata, DefguardComponent}; use crate::{ error::ApiError, proto::{core_request, core_response, proxy_server, CoreRequest, CoreResponse, DeviceInfo}, - version::is_core_version_supported, }; // connected clients diff --git a/src/http.rs b/src/http.rs index a3d5a5c3..f8592021 100644 --- a/src/http.rs +++ b/src/http.rs @@ -32,15 +32,7 @@ use tracing::{info_span, Level}; use url::Url; use crate::{ - assets::{index, svg, web_asset}, - config::Config, - enterprise::handlers::openid_login::{self, FlowType}, - error::ApiError, - grpc::ProxyServer, - handlers::{desktop_client_mfa, enrollment, password_reset, polling}, - proto::proxy_server, - version::MIN_CORE_VERSION, - VERSION, + assets::{index, svg, web_asset}, config::Config, enterprise::handlers::openid_login::{self, FlowType}, error::ApiError, grpc::ProxyServer, handlers::{desktop_client_mfa, enrollment, password_reset, polling}, proto::proxy_server, MIN_CORE_VERSION, VERSION }; pub(crate) static ENROLLMENT_COOKIE_NAME: &str = "defguard_proxy"; diff --git a/src/lib.rs b/src/lib.rs index 2c157057..e4ccce8d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +use defguard_version::Version; + pub mod assets; pub mod config; mod enterprise; @@ -6,7 +8,6 @@ mod grpc; mod handlers; pub mod http; pub mod logging; -mod version; pub(crate) mod proto { tonic::include_proto!("defguard.proxy"); @@ -16,3 +17,4 @@ pub(crate) mod proto { extern crate tracing; pub static VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), "+", env!("VERGEN_GIT_SHA")); +pub const MIN_CORE_VERSION: Version = Version::new(1, 5, 0); diff --git a/src/version.rs b/src/version.rs deleted file mode 100644 index 1332902b..00000000 --- a/src/version.rs +++ /dev/null @@ -1,18 +0,0 @@ -use defguard_version::Version; - -pub const MIN_CORE_VERSION: Version = Version::new(1, 6, 0); - -/// Checks if the core version meets minimum version requirements. -pub(crate) fn is_core_version_supported(core_version: Option<&Version>) -> bool { - let Some(core_version) = core_version else { - error!("Missing core component version information. This most likely means that core component uses unsupported version."); - return false; - }; - if core_version < &MIN_CORE_VERSION { - error!("Core version {core_version} is not supported. Minimal supported core version is {MIN_CORE_VERSION}."); - return false; - } - - info!("Core version {core_version} is supported"); - true -} From 88f6bb9e4de3f09fd113f8b6c66b7cdb71f0c8f8 Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Wed, 27 Aug 2025 15:08:13 +0200 Subject: [PATCH 07/10] cargo fmt --- src/http.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/http.rs b/src/http.rs index f8592021..05870c79 100644 --- a/src/http.rs +++ b/src/http.rs @@ -32,7 +32,14 @@ use tracing::{info_span, Level}; use url::Url; use crate::{ - assets::{index, svg, web_asset}, config::Config, enterprise::handlers::openid_login::{self, FlowType}, error::ApiError, grpc::ProxyServer, handlers::{desktop_client_mfa, enrollment, password_reset, polling}, proto::proxy_server, MIN_CORE_VERSION, VERSION + assets::{index, svg, web_asset}, + config::Config, + enterprise::handlers::openid_login::{self, FlowType}, + error::ApiError, + grpc::ProxyServer, + handlers::{desktop_client_mfa, enrollment, password_reset, polling}, + proto::proxy_server, + MIN_CORE_VERSION, VERSION, }; pub(crate) static ENROLLMENT_COOKIE_NAME: &str = "defguard_proxy"; From 29b082174096ef66c5b16e8cd08fdbd5d4f05c50 Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Thu, 28 Aug 2025 15:37:47 +0200 Subject: [PATCH 08/10] update defguard_version dependency --- Cargo.lock | 1 + Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index e0c4d985..9407d6ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -597,6 +597,7 @@ dependencies = [ [[package]] name = "defguard_version" version = "0.0.0" +source = "git+https://github.com/DefGuard/defguard.git?rev=a5709e7117103458ad8417d4437a8a369ca5bbce#a5709e7117103458ad8417d4437a8a369ca5bbce" dependencies = [ "http", "os_info", diff --git a/Cargo.toml b/Cargo.toml index 844e11c9..4620329d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ homepage = "https://github.com/DefGuard/proxy" repository = "https://github.com/DefGuard/proxy" [dependencies] -defguard_version = { path = "../defguard/crates/defguard_version" } +defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "a5709e7117103458ad8417d4437a8a369ca5bbce" } # base `axum` deps axum = { version = "0.7", features = ["macros", "tracing", "ws"] } axum-client-ip = "0.6" From 5f1c777209a23684ab9da0003fa03a415fc7ebf6 Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Thu, 28 Aug 2025 15:40:48 +0200 Subject: [PATCH 09/10] use aws cached docker image --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 36c38f12..553f01c8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: test: runs-on: - codebuild-defguard-proxy-runner-${{ github.run_id }}-${{ github.run_attempt }} - container: rust:1 + container: public.ecr.aws/docker/library/rust:1 steps: - name: Debug From 15c611f13213085c73fc5f79bcbe2859a0b82fed Mon Sep 17 00:00:00 2001 From: Jacek Chmielewski Date: Thu, 28 Aug 2025 15:44:35 +0200 Subject: [PATCH 10/10] don't use cargo-deny gh action --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 553f01c8..fc24763b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,6 +47,8 @@ jobs: rustup component add clippy 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: Run tests run: cargo test --locked --no-fail-fast