Skip to content

Commit 2d29772

Browse files
authored
Use proper file permission for certificates (#257)
1 parent 9ab3f40 commit 2d29772

6 files changed

Lines changed: 47 additions & 29 deletions

File tree

.github/workflows/build-docker.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969
cache-to: type=gha,mode=max
7070

7171
- name: Scan image with Trivy
72-
uses: aquasecurity/trivy-action@0.33.1
72+
uses: aquasecurity/trivy-action@0.34.1
7373
with:
7474
image-ref: "${{ env.GHCR_REPO }}:${{ github.sha }}-${{ matrix.tag }}"
7575
format: "table"

.github/workflows/sbom.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
submodules: recursive
3434

3535
- name: Create SBOM with Trivy
36-
uses: aquasecurity/trivy-action@0.33.1
36+
uses: aquasecurity/trivy-action@0.34.1
3737
with:
3838
scan-type: 'fs'
3939
format: 'spdx-json'
@@ -43,7 +43,7 @@ jobs:
4343
scanners: "vuln"
4444

4545
- name: Create docker image SBOM with Trivy
46-
uses: aquasecurity/trivy-action@0.33.1
46+
uses: aquasecurity/trivy-action@0.34.1
4747
with:
4848
image-ref: "ghcr.io/defguard/defguard-proxy:${{ steps.vars.outputs.VERSION }}"
4949
scan-type: 'image'
@@ -53,7 +53,7 @@ jobs:
5353
scanners: "vuln"
5454

5555
- name: Create security advisory file with Trivy
56-
uses: aquasecurity/trivy-action@0.33.1
56+
uses: aquasecurity/trivy-action@0.34.1
5757
with:
5858
scan-type: 'fs'
5959
format: 'json'
@@ -63,7 +63,7 @@ jobs:
6363
scanners: "vuln"
6464

6565
- name: Create docker image security advisory file with Trivy
66-
uses: aquasecurity/trivy-action@0.33.1
66+
uses: aquasecurity/trivy-action@0.34.1
6767
with:
6868
image-ref: "ghcr.io/defguard/defguard-proxy:${{ steps.vars.outputs.VERSION }}"
6969
scan-type: 'image'

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
with:
3636
submodules: recursive
3737
- name: Scan code with Trivy
38-
uses: aquasecurity/trivy-action@0.33.1
38+
uses: aquasecurity/trivy-action@0.34.1
3939
with:
4040
scan-type: 'fs'
4141
scan-ref: '.'

Cargo.lock

Lines changed: 10 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ homepage = "https://github.com/DefGuard/proxy"
77
repository = "https://github.com/DefGuard/proxy"
88

99
[dependencies]
10-
defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "8649a9ba225d7bd2066a09c9e1347705c34bd158" }
11-
defguard_certs = { git = "https://github.com/DefGuard/defguard.git", rev = "3304a76f1262eb381a44a0d6906595215cb740b8" }
10+
defguard_certs = { git = "https://github.com/DefGuard/defguard.git", rev = "9c6cbd5108470f9c8dc9b4ee740a9a08f071468c" }
11+
defguard_version = { git = "https://github.com/DefGuard/defguard.git", rev = "9c6cbd5108470f9c8dc9b4ee740a9a08f071468c" }
1212
# base `axum` deps
1313
axum = { version = "0.8", features = ["ws"] }
1414
axum-client-ip = "0.7"
@@ -20,7 +20,7 @@ axum-extra = { version = "0.10", features = [
2020
# match axum-extra -> cookies
2121
time = { version = "0.3", default-features = false }
2222
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
23-
tokio-stream = { version = "0.1" }
23+
tokio-stream = "0.1"
2424
tower-http = { version = "0.6", features = ["fs", "trace"] }
2525
# logging/tracing
2626
tracing = "0.1"
@@ -52,9 +52,9 @@ mime_guess = "2.0"
5252
base64 = "0.22"
5353
tower = "0.5"
5454
futures-util = "0.3"
55-
ammonia = "4.1.1"
55+
ammonia = "4.1"
56+
bytes = "1.11"
5657
chrono = "0.4"
57-
bytes = { version = "1.11" }
5858

5959
[build-dependencies]
6060
tonic-prost-build = "0.14"

src/http.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(unix)]
2+
use std::{fs::Permissions, os::unix::fs::PermissionsExt};
13
use std::{
24
io::ErrorKind,
35
net::{IpAddr, Ipv4Addr, SocketAddr},
@@ -20,7 +22,7 @@ use axum_extra::extract::cookie::Key;
2022
use clap::crate_version;
2123
use defguard_version::{server::DefguardVersionLayer, Version};
2224
use serde::Serialize;
23-
use tokio::{net::TcpListener, task::JoinSet};
25+
use tokio::{fs::OpenOptions, io::AsyncWriteExt, net::TcpListener, task::JoinSet};
2426
use tower_governor::{
2527
governor::GovernorConfigBuilder, key_extractor::SmartIpKeyExtractor, GovernorLayer,
2628
};
@@ -127,11 +129,8 @@ async fn core_version_middleware(
127129
}
128130

129131
let core_connected = app_state.grpc_server.connected.load(Ordering::Relaxed);
130-
let core_connected_header = if core_connected {
131-
HeaderValue::from_static("true")
132-
} else {
133-
HeaderValue::from_static("false")
134-
};
132+
let core_connected_header =
133+
HeaderValue::from_static(if core_connected { "true" } else { "false" });
135134

136135
response
137136
.headers_mut()
@@ -164,6 +163,8 @@ pub async fn run_setup(
164163
err.into()
165164
}
166165
})?;
166+
#[cfg(unix)]
167+
tokio::fs::set_permissions(cert_dir, Permissions::from_mode(0o700)).await?;
167168
}
168169

169170
// Only attempt setup if not already configured
@@ -189,9 +190,19 @@ pub async fn run_setup(
189190

190191
let cert_path = cert_dir.join(GRPC_CERT_NAME);
191192
let key_path = cert_dir.join(GRPC_KEY_NAME);
192-
tokio::fs::write(&cert_path, grpc_cert_pem)
193-
.await
194-
.map_err(|err| {
193+
// Certificate and its key will be accessed only to this process's user.
194+
let mut options = OpenOptions::new();
195+
options.write(true).create(true).truncate(true);
196+
#[cfg(unix)]
197+
options.mode(0o600); // rw-------
198+
199+
// Write certificate to a file.
200+
options
201+
.clone()
202+
.open(&cert_path)
203+
.await?
204+
.write_all(grpc_cert_pem.as_bytes())
205+
.await.map_err(|err| {
195206
if err.kind() == ErrorKind::PermissionDenied {
196207
anyhow::anyhow!(
197208
"Cannot write certificate file {}. Permission denied for certificate directory {}.",
@@ -202,7 +213,11 @@ pub async fn run_setup(
202213
err.into()
203214
}
204215
})?;
205-
tokio::fs::write(&key_path, grpc_key_pem)
216+
// Write key to a file.
217+
options
218+
.open(&key_path)
219+
.await?
220+
.write_all(grpc_key_pem.as_bytes())
206221
.await
207222
.map_err(|err| {
208223
if err.kind() == ErrorKind::PermissionDenied {
@@ -334,8 +349,8 @@ pub async fn run_server(
334349
// build application
335350
debug!("Setting up API server");
336351
let shared_state = AppState {
337-
cookie_key,
338352
grpc_server,
353+
cookie_key,
339354
};
340355

341356
// Setup tower_governor rate-limiter

0 commit comments

Comments
 (0)