mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Improve TLS configuration errors (#2447)
This improves the errors during TLS configuration to localise them to the error site, as well as calling our file path diagnostics tool to assist with permission errors.
This commit is contained in:
parent
3698d65982
commit
967bc7c9df
|
@ -7,7 +7,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use kanidm_proto::constants::DEFAULT_SERVER_ADDRESS;
|
use kanidm_proto::constants::DEFAULT_SERVER_ADDRESS;
|
||||||
|
@ -75,9 +75,9 @@ fn default_online_backup_versions() -> usize {
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct TlsConfiguration {
|
pub struct TlsConfiguration {
|
||||||
pub chain: String,
|
pub chain: PathBuf,
|
||||||
pub key: String,
|
pub key: PathBuf,
|
||||||
pub client_ca: Option<String>,
|
pub client_ca: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the Server Configuration as read from `server.toml`.
|
/// This is the Server Configuration as read from `server.toml`.
|
||||||
|
@ -648,9 +648,9 @@ impl Configuration {
|
||||||
match (chain, key) {
|
match (chain, key) {
|
||||||
(None, None) => {}
|
(None, None) => {}
|
||||||
(Some(chainp), Some(keyp)) => {
|
(Some(chainp), Some(keyp)) => {
|
||||||
let chain = chainp.to_string();
|
let chain = PathBuf::from(keyp.clone());
|
||||||
let key = keyp.to_string();
|
let key = PathBuf::from(chainp.clone());
|
||||||
let client_ca = client_ca.clone();
|
let client_ca = client_ca.clone().map(PathBuf::from);
|
||||||
self.tls_config = Some(TlsConfiguration {
|
self.tls_config = Some(TlsConfiguration {
|
||||||
chain,
|
chain,
|
||||||
key,
|
key,
|
||||||
|
|
|
@ -93,30 +93,49 @@ pub fn check_privkey_minimums(privkey: &PKeyRef<Private>) -> Result<(), String>
|
||||||
|
|
||||||
/// From the server configuration, generate an OpenSSL acceptor that we can use
|
/// From the server configuration, generate an OpenSSL acceptor that we can use
|
||||||
/// to build our sockets for HTTPS/LDAPS.
|
/// to build our sockets for HTTPS/LDAPS.
|
||||||
pub fn setup_tls(config: &Configuration) -> Result<Option<SslAcceptor>, ErrorStack> {
|
pub fn setup_tls(config: &Configuration) -> Result<Option<SslAcceptor>, ()> {
|
||||||
match &config.tls_config {
|
match &config.tls_config {
|
||||||
Some(tls_config) => {
|
Some(tls_config) => {
|
||||||
// Signing algorithm minimums are enforced by the SSLAcceptor - it won't start up with a sha1-signed cert.
|
// Signing algorithm minimums are enforced by the SSLAcceptor - it won't start up with a sha1-signed cert.
|
||||||
let mut ssl_builder = SslAcceptor::mozilla_modern(SslMethod::tls())?;
|
// https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||||
ssl_builder.set_certificate_chain_file(&tls_config.chain)?;
|
let mut ssl_builder =
|
||||||
|
SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).map_err(|openssl_err| {
|
||||||
|
error!("Failed to start TLS builder");
|
||||||
|
error!(?openssl_err);
|
||||||
|
})?;
|
||||||
|
|
||||||
ssl_builder.set_private_key_file(&tls_config.key, SslFiletype::PEM)?;
|
ssl_builder
|
||||||
ssl_builder.check_private_key()?;
|
.set_certificate_chain_file(&tls_config.chain)
|
||||||
|
.map_err(|openssl_err| {
|
||||||
|
error!("Failed to access certificate chain file");
|
||||||
|
error!(?openssl_err);
|
||||||
|
let diag = kanidm_lib_file_permissions::diagnose_path(&tls_config.chain);
|
||||||
|
info!(%diag);
|
||||||
|
})?;
|
||||||
|
|
||||||
|
ssl_builder
|
||||||
|
.set_private_key_file(&tls_config.key, SslFiletype::PEM)
|
||||||
|
.map_err(|openssl_err| {
|
||||||
|
error!("Failed to access private key file");
|
||||||
|
error!(?openssl_err);
|
||||||
|
let diag = kanidm_lib_file_permissions::diagnose_path(&tls_config.chain);
|
||||||
|
info!(%diag);
|
||||||
|
})?;
|
||||||
|
|
||||||
|
ssl_builder.check_private_key().map_err(|openssl_err| {
|
||||||
|
error!("Failed to validate private key");
|
||||||
|
error!(?openssl_err);
|
||||||
|
})?;
|
||||||
|
|
||||||
let acceptor = ssl_builder.build();
|
let acceptor = ssl_builder.build();
|
||||||
|
|
||||||
// let's enforce some TLS minimums!
|
// let's enforce some TLS minimums!
|
||||||
#[allow(clippy::expect_used)]
|
let privkey = acceptor.context().private_key().ok_or_else(|| {
|
||||||
let privkey = acceptor
|
error!("Failed to access acceptor private key");
|
||||||
.context()
|
})?;
|
||||||
.private_key()
|
|
||||||
.expect("Couldn't pull TLS key after configuring one!");
|
|
||||||
|
|
||||||
check_privkey_minimums(privkey).map_err(|err| {
|
check_privkey_minimums(privkey).map_err(|err| {
|
||||||
#[cfg(any(test, debug_assertions))]
|
error!("{}", err);
|
||||||
println!("{}", err);
|
|
||||||
admin_error!("{}", err);
|
|
||||||
ErrorStack::get() // this probably should be a real errorstack but... how?
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Some(acceptor))
|
Ok(Some(acceptor))
|
||||||
|
|
|
@ -397,7 +397,10 @@ async fn server_loop(
|
||||||
|
|
||||||
// If configured, setup TLS client authentication.
|
// If configured, setup TLS client authentication.
|
||||||
if let Some(client_ca) = tls_param.client_ca.as_ref() {
|
if let Some(client_ca) = tls_param.client_ca.as_ref() {
|
||||||
debug!("Configuring client certificates from {}", client_ca);
|
debug!(
|
||||||
|
"Configuring client certificates from {}",
|
||||||
|
client_ca.display()
|
||||||
|
);
|
||||||
|
|
||||||
let verify = SslVerifyMode::PEER;
|
let verify = SslVerifyMode::PEER;
|
||||||
// In future we may add a "require mTLS option" which would necesitate this.
|
// In future we may add a "require mTLS option" which would necesitate this.
|
||||||
|
|
|
@ -36,7 +36,6 @@ mod repl;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::path::Path;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::utils::touch_file_or_quit;
|
use crate::utils::touch_file_or_quit;
|
||||||
|
@ -628,10 +627,7 @@ pub fn cert_generate_core(config: &Configuration) {
|
||||||
// Get the cert root
|
// Get the cert root
|
||||||
|
|
||||||
let (tls_key_path, tls_chain_path) = match &config.tls_config {
|
let (tls_key_path, tls_chain_path) = match &config.tls_config {
|
||||||
Some(tls_config) => (
|
Some(tls_config) => (tls_config.key.as_path(), tls_config.chain.as_path()),
|
||||||
Path::new(tls_config.key.as_str()),
|
|
||||||
Path::new(tls_config.chain.as_str()),
|
|
||||||
),
|
|
||||||
None => {
|
None => {
|
||||||
error!("Unable to find tls configuration");
|
error!("Unable to find tls configuration");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
@ -820,8 +816,8 @@ pub async fn create_server_core(
|
||||||
// Setup TLS (if any)
|
// Setup TLS (if any)
|
||||||
let _opt_tls_params = match crypto::setup_tls(&config) {
|
let _opt_tls_params = match crypto::setup_tls(&config) {
|
||||||
Ok(opt_tls_params) => opt_tls_params,
|
Ok(opt_tls_params) => opt_tls_params,
|
||||||
Err(e) => {
|
Err(()) => {
|
||||||
error!("Failed to configure TLS parameters -> {:?}", e);
|
error!("Failed to configure TLS parameters");
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1017,8 +1013,8 @@ pub async fn create_server_core(
|
||||||
Some(la) => {
|
Some(la) => {
|
||||||
let opt_ldap_ssl_acceptor = match crypto::setup_tls(&config) {
|
let opt_ldap_ssl_acceptor = match crypto::setup_tls(&config) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(e) => {
|
Err(()) => {
|
||||||
error!("Failed to configure LDAP TLS parameters -> {:?}", e);
|
error!("Failed to configure LDAP TLS parameters");
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue