Skip to content

Commit 2341c13

Browse files
committed
feat: [torrust#878] extract tsl_config in toml config
TSL configuration for HTTP trackers and the Tracker API is still optional. However, when it's provided is enabled. The `ssl_enabled` field was removed. You can remove the whole `tsl_config` to disable TSL. If you want to kee a copy in the TOML file you can just comment the lines. ```toml [[http_trackers]] ... [http_trackers.tsl_config] ssl_cert_path = "./storage/tracker/lib/tls/localhost.crt" ssl_key_path = "./storage/tracker/lib/tls/localhost.key" [http_api] ... [http_api.tsl_config] ssl_cert_path = "./storage/tracker/lib/tls/localhost.crt" ssl_key_path = "./storage/tracker/lib/tls/localhost.key" ```
1 parent 7b2f757 commit 2341c13

19 files changed

+90
-131
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ axum = { version = "0", features = ["macros"] }
3737
axum-client-ip = "0"
3838
axum-extra = { version = "0", features = ["query"] }
3939
axum-server = { version = "0", features = ["tls-rustls"] }
40-
camino = { version = "1.1.6", features = ["serde"] }
40+
camino = { version = "1.1.6", features = ["serde", "serde1"] }
4141
chrono = { version = "0", default-features = false, features = ["clock"] }
4242
clap = { version = "4", features = ["derive", "env"] }
4343
crossbeam-skiplist = "0.1"

docs/containers.md

+11-12
Original file line numberDiff line numberDiff line change
@@ -330,24 +330,23 @@ The storage folder must contain your certificates:
330330

331331
```s
332332
storage/tracker/lib/tls
333-
├── localhost.crt
334-
└── localhost.key
333+
├── localhost.crt
334+
└── localhost.key
335+
storage/http_api/lib/tls
336+
├── localhost.crt
337+
└── localhost.key
335338
```
336339

337340
You have not enabled it in your `tracker.toml` file:
338341

339342
```toml
343+
[http_trackers.tsl_config]
344+
ssl_cert_path = "./storage/tracker/lib/tls/localhost.crt"
345+
ssl_key_path = "./storage/tracker/lib/tls/localhost.key"
340346

341-
[[http_trackers]]
342-
# ...
343-
ssl_enabled = true
344-
# ...
345-
346-
[http_api]
347-
# ...
348-
ssl_enabled = true
349-
# ...
350-
347+
[http_api.tsl_config]
348+
ssl_cert_path = "./storage/http_api/lib/tls/localhost.crt"
349+
ssl_key_path = "./storage/http_api/lib/tls/localhost.key"
351350
```
352351

353352
> NOTE: you can enable it independently for each HTTP tracker or the API.

packages/configuration/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ rust-version.workspace = true
1515
version.workspace = true
1616

1717
[dependencies]
18-
camino = { version = "1.1.6", features = ["serde"] }
18+
camino = { version = "1.1.6", features = ["serde", "serde1"] }
1919
derive_more = "0"
2020
figment = { version = "0.10.18", features = ["env", "test", "toml"] }
2121
serde = { version = "1", features = ["derive"] }

packages/configuration/src/lib.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::sync::Arc;
1313
use camino::Utf8PathBuf;
1414
use derive_more::Constructor;
1515
use serde::{Deserialize, Serialize};
16-
use serde_with::{serde_as, NoneAsEmptyString};
16+
use serde_with::serde_as;
1717
use thiserror::Error;
1818
use torrust_tracker_located_error::{DynError, LocatedError};
1919

@@ -215,24 +215,23 @@ impl From<figment::Error> for Error {
215215
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Default)]
216216
pub struct TslConfig {
217217
/// Path to the SSL certificate file.
218-
#[serde_as(as = "NoneAsEmptyString")]
219218
#[serde(default = "TslConfig::default_ssl_cert_path")]
220-
pub ssl_cert_path: Option<Utf8PathBuf>,
219+
pub ssl_cert_path: Utf8PathBuf,
220+
221221
/// Path to the SSL key file.
222-
#[serde_as(as = "NoneAsEmptyString")]
223222
#[serde(default = "TslConfig::default_ssl_key_path")]
224-
pub ssl_key_path: Option<Utf8PathBuf>,
223+
pub ssl_key_path: Utf8PathBuf,
225224
}
226225

227226
impl TslConfig {
228227
#[allow(clippy::unnecessary_wraps)]
229-
fn default_ssl_cert_path() -> Option<Utf8PathBuf> {
230-
Some(Utf8PathBuf::new())
228+
fn default_ssl_cert_path() -> Utf8PathBuf {
229+
Utf8PathBuf::new()
231230
}
232231

233232
#[allow(clippy::unnecessary_wraps)]
234-
fn default_ssl_key_path() -> Option<Utf8PathBuf> {
235-
Some(Utf8PathBuf::new())
233+
fn default_ssl_key_path() -> Utf8PathBuf {
234+
Utf8PathBuf::new()
236235
}
237236
}
238237

packages/configuration/src/v1/http_tracker.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,25 @@ pub struct HttpTracker {
1212
/// Weather the HTTP tracker is enabled or not.
1313
#[serde(default = "HttpTracker::default_enabled")]
1414
pub enabled: bool,
15+
1516
/// The address the tracker will bind to.
1617
/// The format is `ip:port`, for example `0.0.0.0:6969`. If you want to
1718
/// listen to all interfaces, use `0.0.0.0`. If you want the operating
1819
/// system to choose a random port, use port `0`.
1920
#[serde(default = "HttpTracker::default_bind_address")]
2021
pub bind_address: SocketAddr,
21-
/// Weather the HTTP tracker will use SSL or not.
22-
#[serde(default = "HttpTracker::default_ssl_enabled")]
23-
pub ssl_enabled: bool,
24-
/// TSL config. Only used if `ssl_enabled` is true.
25-
#[serde(flatten)]
26-
#[serde(default = "TslConfig::default")]
27-
pub tsl_config: TslConfig,
22+
23+
/// TSL config.
24+
#[serde(default = "HttpTracker::default_tsl_config")]
25+
pub tsl_config: Option<TslConfig>,
2826
}
2927

3028
impl Default for HttpTracker {
3129
fn default() -> Self {
3230
Self {
3331
enabled: Self::default_enabled(),
3432
bind_address: Self::default_bind_address(),
35-
ssl_enabled: Self::default_ssl_enabled(),
36-
tsl_config: TslConfig::default(),
33+
tsl_config: Self::default_tsl_config(),
3734
}
3835
}
3936
}
@@ -47,7 +44,7 @@ impl HttpTracker {
4744
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 7070)
4845
}
4946

50-
fn default_ssl_enabled() -> bool {
51-
false
47+
fn default_tsl_config() -> Option<TslConfig> {
48+
None
5249
}
5350
}

packages/configuration/src/v1/mod.rs

+5-15
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,16 @@
176176
//!
177177
//! ```s
178178
//! [[http_trackers]]
179-
//! enabled = true
180179
//! ...
180+
//!
181+
//! [http_trackers.tsl_config]
181182
//! ssl_cert_path = "./storage/tracker/lib/tls/localhost.crt"
182183
//! ssl_key_path = "./storage/tracker/lib/tls/localhost.key"
183184
//!
184185
//! [http_api]
185-
//! enabled = true
186186
//! ...
187+
//!
188+
//! [http_api.tsl_config]
187189
//! ssl_cert_path = "./storage/tracker/lib/tls/localhost.crt"
188190
//! ssl_key_path = "./storage/tracker/lib/tls/localhost.key"
189191
//! ```
@@ -225,16 +227,10 @@
225227
//! [[http_trackers]]
226228
//! enabled = false
227229
//! bind_address = "0.0.0.0:7070"
228-
//! ssl_enabled = false
229-
//! ssl_cert_path = ""
230-
//! ssl_key_path = ""
231230
//!
232231
//! [http_api]
233232
//! enabled = true
234233
//! bind_address = "127.0.0.1:1212"
235-
//! ssl_enabled = false
236-
//! ssl_cert_path = ""
237-
//! ssl_key_path = ""
238234
//!
239235
//! [http_api.access_tokens]
240236
//! admin = "MyAccessToken"
@@ -419,16 +415,10 @@ mod tests {
419415
[[http_trackers]]
420416
enabled = false
421417
bind_address = "0.0.0.0:7070"
422-
ssl_enabled = false
423-
ssl_cert_path = ""
424-
ssl_key_path = ""
425-
418+
426419
[http_api]
427420
enabled = true
428421
bind_address = "127.0.0.1:1212"
429-
ssl_enabled = false
430-
ssl_cert_path = ""
431-
ssl_key_path = ""
432422
433423
[http_api.access_tokens]
434424
admin = "MyAccessToken"

packages/configuration/src/v1/tracker_api.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,18 @@ pub struct HttpApi {
1515
/// Weather the HTTP API is enabled or not.
1616
#[serde(default = "HttpApi::default_enabled")]
1717
pub enabled: bool,
18+
1819
/// The address the tracker will bind to.
1920
/// The format is `ip:port`, for example `0.0.0.0:6969`. If you want to
2021
/// listen to all interfaces, use `0.0.0.0`. If you want the operating
2122
/// system to choose a random port, use port `0`.
2223
#[serde(default = "HttpApi::default_bind_address")]
2324
pub bind_address: SocketAddr,
24-
/// Weather the HTTP API will use SSL or not.
25-
#[serde(default = "HttpApi::default_ssl_enabled")]
26-
pub ssl_enabled: bool,
25+
2726
/// TSL config. Only used if `ssl_enabled` is true.
28-
#[serde(flatten)]
29-
#[serde(default = "TslConfig::default")]
30-
pub tsl_config: TslConfig,
27+
#[serde(default = "HttpApi::default_tsl_config")]
28+
pub tsl_config: Option<TslConfig>,
29+
3130
/// Access tokens for the HTTP API. The key is a label identifying the
3231
/// token and the value is the token itself. The token is used to
3332
/// authenticate the user. All tokens are valid for all endpoints and have
@@ -41,8 +40,7 @@ impl Default for HttpApi {
4140
Self {
4241
enabled: Self::default_enabled(),
4342
bind_address: Self::default_bind_address(),
44-
ssl_enabled: Self::default_ssl_enabled(),
45-
tsl_config: TslConfig::default(),
43+
tsl_config: Self::default_tsl_config(),
4644
access_tokens: Self::default_access_tokens(),
4745
}
4846
}
@@ -57,8 +55,9 @@ impl HttpApi {
5755
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 1212)
5856
}
5957

60-
fn default_ssl_enabled() -> bool {
61-
false
58+
#[allow(clippy::unnecessary_wraps)]
59+
fn default_tsl_config() -> Option<TslConfig> {
60+
None
6261
}
6362

6463
fn default_access_tokens() -> AccessTokens {

share/default/config/tracker.container.mysql.toml

+2-6
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,5 @@ driver = "MySQL"
33
path = "mysql://db_user:db_user_secret_password@mysql:3306/torrust_tracker"
44

55
[[http_trackers]]
6-
ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt"
7-
ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key"
8-
9-
[http_api]
10-
ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt"
11-
ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key"
6+
bind_address = "0.0.0.0:7070"
7+
enabled = true
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,2 @@
11
[core.database]
22
path = "/var/lib/torrust/tracker/database/sqlite3.db"
3-
4-
[[http_trackers]]
5-
ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt"
6-
ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key"
7-
8-
[http_api]
9-
ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt"
10-
ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key"

share/default/config/tracker.e2e.container.sqlite3.toml

-6
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ enabled = true
66

77
[[http_trackers]]
88
enabled = true
9-
ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt"
10-
ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key"
11-
12-
[http_api]
13-
ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt"
14-
ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key"
159

1610
[health_check_api]
1711
# Must be bound to wildcard IP to be accessible from outside the container

src/bootstrap/jobs/http_tracker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub async fn start_job(
4242
if config.enabled {
4343
let socket = config.bind_address;
4444

45-
let tls = make_rust_tls(config.ssl_enabled, &config.tsl_config)
45+
let tls = make_rust_tls(&config.tsl_config)
4646
.await
4747
.map(|tls| tls.expect("it should have a valid http tracker tls configuration"));
4848

src/bootstrap/jobs/mod.rs

+35-35
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,33 @@ pub struct Started {
2020
pub address: std::net::SocketAddr,
2121
}
2222

23-
pub async fn make_rust_tls(enabled: bool, tsl_config: &TslConfig) -> Option<Result<RustlsConfig, Error>> {
24-
if !enabled {
25-
info!("TLS not enabled");
26-
return None;
27-
}
23+
pub async fn make_rust_tls(opt_tsl_config: &Option<TslConfig>) -> Option<Result<RustlsConfig, Error>> {
24+
match opt_tsl_config {
25+
Some(tsl_config) => {
26+
let cert = tsl_config.ssl_cert_path.clone();
27+
let key = tsl_config.ssl_key_path.clone();
2828

29-
if let (Some(cert), Some(key)) = (tsl_config.ssl_cert_path.clone(), tsl_config.ssl_key_path.clone()) {
30-
info!("Using https: cert path: {cert}.");
31-
info!("Using https: key path: {key}.");
32-
33-
Some(
34-
RustlsConfig::from_pem_file(cert, key)
35-
.await
36-
.map_err(|err| Error::BadTlsConfig {
37-
source: (Arc::new(err) as DynError).into(),
38-
}),
39-
)
40-
} else {
41-
Some(Err(Error::MissingTlsConfig {
42-
location: Location::caller(),
43-
}))
29+
if !cert.exists() || !key.exists() {
30+
return Some(Err(Error::MissingTlsConfig {
31+
location: Location::caller(),
32+
}));
33+
}
34+
35+
info!("Using https: cert path: {cert}.");
36+
info!("Using https: key path: {key}.");
37+
38+
Some(
39+
RustlsConfig::from_pem_file(cert, key)
40+
.await
41+
.map_err(|err| Error::BadTlsConfig {
42+
source: (Arc::new(err) as DynError).into(),
43+
}),
44+
)
45+
}
46+
None => {
47+
info!("TLS not enabled");
48+
None
49+
}
4450
}
4551
}
4652

@@ -54,29 +60,23 @@ mod tests {
5460

5561
#[tokio::test]
5662
async fn it_should_error_on_bad_tls_config() {
57-
let err = make_rust_tls(
58-
true,
59-
&TslConfig {
60-
ssl_cert_path: Some(Utf8PathBuf::from("bad cert path")),
61-
ssl_key_path: Some(Utf8PathBuf::from("bad key path")),
62-
},
63-
)
63+
let err = make_rust_tls(&Some(TslConfig {
64+
ssl_cert_path: Utf8PathBuf::from("bad cert path"),
65+
ssl_key_path: Utf8PathBuf::from("bad key path"),
66+
}))
6467
.await
6568
.expect("tls_was_enabled")
6669
.expect_err("bad_cert_and_key_files");
6770

68-
assert!(matches!(err, Error::BadTlsConfig { source: _ }));
71+
assert!(matches!(err, Error::MissingTlsConfig { location: _ }));
6972
}
7073

7174
#[tokio::test]
7275
async fn it_should_error_on_missing_cert_or_key_paths() {
73-
let err = make_rust_tls(
74-
true,
75-
&TslConfig {
76-
ssl_cert_path: None,
77-
ssl_key_path: None,
78-
},
79-
)
76+
let err = make_rust_tls(&Some(TslConfig {
77+
ssl_cert_path: Utf8PathBuf::from(""),
78+
ssl_key_path: Utf8PathBuf::from(""),
79+
}))
8080
.await
8181
.expect("tls_was_enabled")
8282
.expect_err("missing_config");

src/bootstrap/jobs/tracker_apis.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub async fn start_job(
6363
if config.enabled {
6464
let bind_to = config.bind_address;
6565

66-
let tls = make_rust_tls(config.ssl_enabled, &config.tsl_config)
66+
let tls = make_rust_tls(&config.tsl_config)
6767
.await
6868
.map(|tls| tls.expect("it should have a valid tracker api tls configuration"));
6969

0 commit comments

Comments
 (0)