From 63ea401c1482cb9d9ed4fc212d8632040bf5c848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Thu, 26 Feb 2026 12:11:19 +0100 Subject: [PATCH 1/5] Use proper file permissions for certificates --- Cargo.lock | 7 ++++--- Cargo.toml | 4 ++-- src/setup.rs | 55 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5aebee51..b71cbe24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,6 +427,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link", ] @@ -710,12 +711,12 @@ dependencies = [ [[package]] name = "defguard_certs" version = "0.0.0" -source = "git+https://github.com/DefGuard/defguard.git?rev=290bdee718f51179c71e07f3bce3f8a0cbfb9379#290bdee718f51179c71e07f3bce3f8a0cbfb9379" +source = "git+https://github.com/DefGuard/defguard.git?rev=12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d#12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d" dependencies = [ "base64", + "chrono", "rcgen", "rustls-pki-types", - "serde", "sqlx", "thiserror 2.0.18", "time", @@ -725,7 +726,7 @@ dependencies = [ [[package]] name = "defguard_version" version = "0.0.0" -source = "git+https://github.com/DefGuard/defguard.git?rev=5be16525f5208739fd79384b30d8ac5056ffdb2f#5be16525f5208739fd79384b30d8ac5056ffdb2f" +source = "git+https://github.com/DefGuard/defguard.git?rev=12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d#12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d" dependencies = [ "axum", "http", diff --git a/Cargo.toml b/Cargo.toml index b0f1d550..441b035b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,9 @@ edition = "2024" axum = "0.8" base64 = "0.22" clap = { version = "4.5", features = ["derive", "env"] } -defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "5be16525f5208739fd79384b30d8ac5056ffdb2f" } +defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d" } defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs", rev = "d0b01eabca015ea6c7ddf4e255a0228074684e96" } -defguard_certs = { git = "https://github.com/DefGuard/defguard.git", rev = "290bdee718f51179c71e07f3bce3f8a0cbfb9379" } +defguard_certs = { git = "https://github.com/DefGuard/defguard.git", rev = "12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d" } env_logger = "0.11" gethostname = "1.0" ipnetwork = "0.21" diff --git a/src/setup.rs b/src/setup.rs index 7e8d0bf7..75568fa6 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,10 +1,15 @@ use std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, + path::Path, sync::{Arc, Mutex}, }; use defguard_version::{Version, server::DefguardVersionLayer}; -use tokio::sync::{mpsc, oneshot}; +use tokio::{ + fs::OpenOptions, + io::AsyncWriteExt, + sync::{mpsc, oneshot}, +}; use tokio_stream::wrappers::UnboundedReceiverStream; use tonic::{Request, Response, Status, transport::Server}; use tower::ServiceBuilder; @@ -23,16 +28,32 @@ type LogsReceiver = Arc>>; pub async fn run_setup( config: &Config, - cert_dir: &std::path::Path, + cert_dir: &Path, logs_rx: Arc>>, ) -> Result { let setup_server = GatewaySetupServer::new(logs_rx); - let tls_config = setup_server.await_setup(config.clone()).await?; + let tls_config = setup_server.await_setup(config).await?; let cert_path = cert_dir.join(GRPC_CERT_NAME); let key_path = cert_dir.join(GRPC_KEY_NAME); - tokio::fs::write(cert_path, &tls_config.grpc_cert_pem).await?; - tokio::fs::write(key_path, &tls_config.grpc_key_pem).await?; + // Certificate and its key will be accessed only to this process's user. + let mut options = OpenOptions::new(); + options.write(true).create(true).truncate(true); + #[cfg(unix)] + options.mode(0o600); // rw------- + // Write certificate to a file. + options + .clone() + .open(cert_path) + .await? + .write_all(tls_config.grpc_cert_pem.as_bytes()) + .await?; + // Write key to a file. + options + .open(key_path) + .await? + .write_all(tls_config.grpc_key_pem.as_bytes()) + .await?; log::info!( "Generated gRPC TLS certificates have been saved to {}", cert_dir.display() @@ -74,7 +95,7 @@ impl GatewaySetupServer { } } - pub async fn await_setup(&self, config: Config) -> Result { + pub async fn await_setup(&self, config: &Config) -> Result { let mut server_builder = Server::builder(); let mut server_config = None; let setup_rx = Arc::clone(&self.setup_rx); @@ -86,10 +107,6 @@ impl GatewaySetupServer { server_builder .add_service( ServiceBuilder::new() - // .layer(InterceptorLayer::new(CoreVersionInterceptor::new( - // MIN_CORE_VERSION, - // incompatible_components, - // ))) .layer(DefguardVersionLayer::new(Version::parse(VERSION)?)) .service(gateway_setup_server::GatewaySetupServer::new(self.clone())), ) @@ -251,7 +268,7 @@ impl gateway_setup_server::GatewaySetup for GatewaySetupServer { }; debug!("Key pair created"); - let subject_alt_names = vec![setup_info.cert_hostname]; + let subject_alt_names = [setup_info.cert_hostname]; debug!("Preparing Certificate Signing Request for hostname: {subject_alt_names:?}",); let csr = match defguard_certs::Csr::new( @@ -274,7 +291,10 @@ impl gateway_setup_server::GatewaySetup for GatewaySetupServer { self.key_pair .lock() - .expect("Failed to acquire lock on key pair during gateway setup when trying to store generated key pair") + .expect( + "Failed to acquire lock on key pair during gateway setup when trying to store \ + generated key pair", + ) .replace(key_pair); debug!("Encoding Certificate Signing Request for transmission"); @@ -331,17 +351,22 @@ impl gateway_setup_server::GatewaySetup for GatewaySetupServer { let key_pair = self .key_pair .lock() - .expect("Failed to acquire lock on key pair during gateway setup when trying to receive certificate") + .expect( + "Failed to acquire lock on key pair during gateway setup when trying to \ + receive certificate", + ) .take(); if let Some(kp) = key_pair { kp } else { error!( - "Key pair not found during Gateway setup. Key pair generation step might have failed." + "Key pair not found during Gateway setup. Key pair generation step might have \ + failed." ); self.clear_setup_session(); return Err(Status::internal( - "Key pair not found during Gateway setup. Key pair generation step might have failed.", + "Key pair not found during Gateway setup. Key pair generation step might have \ + failed.", )); } }; From 8147cb44bdb9420a5846e31c5bdb213f8217339d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Thu, 26 Feb 2026 12:13:19 +0100 Subject: [PATCH 2/5] Update trivy-action --- .github/workflows/build-docker.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/sbom.yml | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index f0f95075..16c39c35 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -74,7 +74,7 @@ jobs: cache-to: type=registry,mode=max,ref=${{ env.GHCR_REPO }}:cache-${{ matrix.tag }}-${{ env.SAFE_REF }} - name: Scan image with Trivy - uses: aquasecurity/trivy-action@0.33.1 + uses: aquasecurity/trivy-action@0.34.1 with: image-ref: "${{ env.GHCR_REPO }}:${{ github.sha }}-${{ matrix.tag }}" format: "table" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d79ae06..4c414950 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: submodules: recursive - name: Scan code with Trivy - uses: aquasecurity/trivy-action@0.33.1 + uses: aquasecurity/trivy-action@0.34.1 with: scan-type: 'fs' scan-ref: '.' diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml index 9f2fc8bb..d0fbc4a1 100644 --- a/.github/workflows/sbom.yml +++ b/.github/workflows/sbom.yml @@ -33,7 +33,7 @@ jobs: submodules: recursive - name: Create SBOM with Trivy - uses: aquasecurity/trivy-action@0.33.1 + uses: aquasecurity/trivy-action@0.34.1 with: scan-type: 'fs' format: 'spdx-json' @@ -43,7 +43,7 @@ jobs: scanners: "vuln" - name: Create docker image SBOM with Trivy - uses: aquasecurity/trivy-action@0.33.1 + uses: aquasecurity/trivy-action@0.34.1 with: image-ref: "ghcr.io/defguard/gateway:${{ steps.vars.outputs.VERSION }}" scan-type: 'image' @@ -53,7 +53,7 @@ jobs: scanners: "vuln" - name: Create security advisory file with Trivy - uses: aquasecurity/trivy-action@0.33.1 + uses: aquasecurity/trivy-action@0.34.1 with: scan-type: 'fs' format: 'json' @@ -63,7 +63,7 @@ jobs: scanners: "vuln" - name: Create docker image security advisory file with Trivy - uses: aquasecurity/trivy-action@0.33.1 + uses: aquasecurity/trivy-action@0.34.1 with: image-ref: "ghcr.io/defguard/gateway:${{ steps.vars.outputs.VERSION }}" scan-type: 'image' From 3eab7c187d71eaeb572ce9d1b2a373301f8eaa51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Thu, 26 Feb 2026 13:45:52 +0100 Subject: [PATCH 3/5] set permissions for cert dir --- src/main.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 69889118..732a1c43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use std::{ - fs::{File, read_to_string}, + fs::{File, Permissions, read_to_string}, io::Write, + os::unix::fs::PermissionsExt, process, sync::{Arc, Mutex}, }; @@ -39,6 +40,8 @@ async fn main() -> Result<(), GatewayError> { let cert_dir = &config.cert_dir; if !cert_dir.exists() { tokio::fs::create_dir_all(cert_dir).await?; + #[cfg(unix)] + tokio::fs::set_permissions(cert_dir, Permissions::from_mode(0o700)).await?; } let (grpc_cert, grpc_key) = ( From 80be80ad03826a9f3177a42ec504fd261b340280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Thu, 26 Feb 2026 13:51:03 +0100 Subject: [PATCH 4/5] Proper use of use --- src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 732a1c43..3aba3423 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ +#[cfg(unix)] +use std::{fs::Permissions, os::unix::fs::PermissionsExt}; use std::{ - fs::{File, Permissions, read_to_string}, + fs::{File, read_to_string}, io::Write, - os::unix::fs::PermissionsExt, process, sync::{Arc, Mutex}, }; From aa15ba3e74b32db6c5585702ad7f16b54e1847e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Ciarcin=CC=81ski?= Date: Thu, 26 Feb 2026 16:33:56 +0100 Subject: [PATCH 5/5] Update repo rev --- Cargo.lock | 4 ++-- Cargo.toml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b71cbe24..445485e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -711,7 +711,7 @@ dependencies = [ [[package]] name = "defguard_certs" version = "0.0.0" -source = "git+https://github.com/DefGuard/defguard.git?rev=12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d#12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d" +source = "git+https://github.com/DefGuard/defguard.git?rev=9c6cbd5108470f9c8dc9b4ee740a9a08f071468c#9c6cbd5108470f9c8dc9b4ee740a9a08f071468c" dependencies = [ "base64", "chrono", @@ -726,7 +726,7 @@ dependencies = [ [[package]] name = "defguard_version" version = "0.0.0" -source = "git+https://github.com/DefGuard/defguard.git?rev=12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d#12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d" +source = "git+https://github.com/DefGuard/defguard.git?rev=9c6cbd5108470f9c8dc9b4ee740a9a08f071468c#9c6cbd5108470f9c8dc9b4ee740a9a08f071468c" dependencies = [ "axum", "http", diff --git a/Cargo.toml b/Cargo.toml index 441b035b..2f4bb851 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,11 @@ edition = "2024" [dependencies] axum = "0.8" base64 = "0.22" +chrono = "0.4" clap = { version = "4.5", features = ["derive", "env"] } -defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d" } +defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "9c6cbd5108470f9c8dc9b4ee740a9a08f071468c" } defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs", rev = "d0b01eabca015ea6c7ddf4e255a0228074684e96" } -defguard_certs = { git = "https://github.com/DefGuard/defguard.git", rev = "12f3c134f6d814779e8c3ad6d21eeb3c5f999f7d" } +defguard_certs = { git = "https://github.com/DefGuard/defguard.git", rev = "9c6cbd5108470f9c8dc9b4ee740a9a08f071468c" } env_logger = "0.11" gethostname = "1.0" ipnetwork = "0.21" @@ -32,11 +33,10 @@ tonic = { version = "0.14", default-features = false, features = [ "tls-native-roots", "tls-ring", ] } -tracing = "0.1" tonic-prost = "0.14" tower = "0.5" -chrono = "0.4.43" -tracing-subscriber = "0.3.22" +tracing = "0.1" +tracing-subscriber = "0.3" [target.'cfg(target_os = "linux")'.dependencies] nftnl = { git = "https://github.com/DefGuard/nftnl-rs.git", rev = "f30cbf9c0e081aed7d8d8740eabdf07109a70373" }