Skip to content

Commit

Permalink
Keytab setting is bound to server
Browse files Browse the repository at this point in the history
  • Loading branch information
vruello committed Oct 1, 2023
1 parent 8cb71d2 commit 2c25309
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Remove `OperationID` from responses because we don't support "Robust Connection" (#37)
- Clear in-memory subscriptions when a SIGHUP signal is received, resulting in all file descriptors used by subscriptions being closed (#37)
- `heartbeats_queue_size` now defaults to 2048 instead of 32 (#37)
- **Breaking change**: Keytab file path must be specified only once for all collectors (using Kerberos authentication)

## [0.1.0] - 2023-05-30

Expand Down
20 changes: 13 additions & 7 deletions common/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,17 @@ impl Collector {
#[derive(Debug, Deserialize, Clone)]
pub struct Kerberos {
service_principal_name: String,
keytab: String,
}

impl Kerberos {
pub fn service_principal_name(&self) -> &str {
&self.service_principal_name
pub fn empty() -> Self {
Kerberos {
service_principal_name: String::new(),
}
}

pub fn keytab(&self) -> &str {
&self.keytab
pub fn service_principal_name(&self) -> &str {
&self.service_principal_name
}
}

Expand Down Expand Up @@ -186,6 +187,7 @@ pub struct Server {
flush_heartbeats_interval: Option<u64>,
heartbeats_queue_size: Option<u64>,
node_name: Option<String>,
keytab: Option<String>,
}

impl Server {
Expand All @@ -208,6 +210,10 @@ impl Server {
pub fn heartbeats_queue_size(&self) -> u64 {
self.heartbeats_queue_size.unwrap_or(2048)
}

pub fn keytab(&self) -> Option<&String> {
self.keytab.as_ref()
}
}

#[derive(Debug, Deserialize, Clone)]
Expand Down Expand Up @@ -253,6 +259,7 @@ mod tests {
const CONFIG_KERBEROS_SQLITE: &str = r#"
[server]
verbosity = "debug"
keytab = "wec.windomain.local.keytab"
[database]
type = "SQLite"
Expand All @@ -267,7 +274,6 @@ mod tests {
[collectors.authentication]
type = "Kerberos"
service_principal_name = "http/wec.windomain.local@WINDOMAIN.LOCAL"
keytab = "wec.windomain.local.keytab"
"#;

#[test]
Expand All @@ -284,7 +290,7 @@ mod tests {
Authentication::Kerberos(kerb) => kerb,
_ => panic!("Wrong authentication type"),
};
assert_eq!(kerberos.keytab(), "wec.windomain.local.keytab");
assert_eq!(s.server().keytab().unwrap(), "wec.windomain.local.keytab");
assert_eq!(
kerberos.service_principal_name(),
"http/wec.windomain.local@WINDOMAIN.LOCAL"
Expand Down
5 changes: 1 addition & 4 deletions doc/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ Write the following content in `/etc/openwec.conf.toml`:
```toml
# /etc/openwec.conf.toml
[server]
verbosity = "info"
db_sync_interval = 5
flush_heartbeats_interval = 5
keytab = "/etc/wec.windomain.local.keytab"

[database]
type = "SQLite"
Expand All @@ -50,7 +48,6 @@ listen_address = "0.0.0.0"
[collectors.authentication]
type = "Kerberos"
service_principal_name = "http/wec.windomain.local@WINDOMAIN.LOCAL"
keytab = "/etc/wec.windomain.local.keytab"
```

See [openwec.conf.sample.toml](../openwec.conf.sample.toml) for further information on available parameters.
Expand Down
15 changes: 9 additions & 6 deletions openwec.conf.sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
# This may be used by outputs. Unset by default.
# node_name = unsef

# [Optional]
# Keytab file path that contains secrets for Kerberos SPNs used by collectors.
# Required if Kerberos authentication is used by at least one collector.
# It must contain entries for service principals used by collectors.
# It can contain other entries that aren't used by openwec.
# keytab = "/etc/krb5.keytab"

##########################
## Databases settings ##
##########################
Expand Down Expand Up @@ -148,17 +155,13 @@

## Kerberos configuration

# [server.keytab] is required when using Kerberos authentication

# [Required]
# Service Principal Name of the openwec account
# Should be something like "HTTP/openwec.mydomain.local@MYDOMAIN.LOCAL"
# service_principal_name = ""

# [Required]
# Keytab file that contains secrets of the openwec account.
# It must contain an entry for the principal <kerberos.service_principal_name>.
# It may contains other entries, which won't be used by openwec.
# keytab = "/etc/krb5.keytab"

## End of Kerberos configuration

## TLS configuration
Expand Down
19 changes: 16 additions & 3 deletions server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ use soap::Serializable;
use std::boxed::Box;
use std::collections::HashMap;
use std::convert::Infallible;
use std::env;
use std::future::ready;
use std::io::Cursor;
use std::net::{IpAddr, SocketAddr};
use std::str::FromStr;
use std::sync::Mutex;
use std::sync::{Arc, RwLock};
use std::time::Instant;
use std::{env, mem};
use subscription::{reload_subscriptions_task, Subscriptions};
use tls_listener::TlsListener;
use tokio::signal::unix::SignalKind;
Expand Down Expand Up @@ -443,8 +443,6 @@ fn create_kerberos_server(
collector_server_settings: ServerSettings,
addr: SocketAddr,
) -> Pin<Box<dyn Future<Output = hyper::Result<()>> + Send>> {
env::set_var("KRB5_KTNAME", kerberos_settings.keytab());

let principal = kerberos_settings.service_principal_name().to_owned();
// Try to initialize a security context. This is to be sure that an error in
// Kerberos configuration will be reported as soon as possible.
Expand Down Expand Up @@ -645,6 +643,21 @@ pub async fn run(settings: Settings) {
heartbeat_task(update_task_db, interval, heartbeat_rx, heartbeat_exit_rx).await
});

// Set KRB5_KTNAME env variable if necessary (i.e. if at least one collector uses
// Kerberos authentication)
if settings.collectors().iter().any(|x| {
mem::discriminant(x.authentication())
== mem::discriminant(&Authentication::Kerberos(Kerberos::empty()))
}) {
env::set_var(
"KRB5_KTNAME",
settings
.server()
.keytab()
.expect("Kerberos authentication requires the server.keytab setting to be set"),
);
}

for collector in settings.collectors() {
let collector_db = db.clone();
let collector_subscriptions = subscriptions.clone();
Expand Down

0 comments on commit 2c25309

Please sign in to comment.