Browse Source

Match Go HTTP tls policy semantics

rust-volume-server
Chris Lu 5 days ago
parent
commit
4ecb965a17
  1. 88
      seaweed-volume/src/main.rs

88
seaweed-volume/src/main.rs

@ -124,6 +124,20 @@ fn build_outgoing_http_client(
Ok((builder.build()?, scheme.to_string())) Ok((builder.build()?, scheme.to_string()))
} }
fn tls_policy_is_configured(policy: &TlsPolicy) -> bool {
!policy.min_version.is_empty()
|| !policy.max_version.is_empty()
|| !policy.cipher_suites.is_empty()
}
fn effective_http_tls_policy(ca_path: &str, configured_policy: &TlsPolicy) -> TlsPolicy {
if ca_path.is_empty() {
TlsPolicy::default()
} else {
configured_policy.clone()
}
}
fn build_grpc_server_tls_acceptor( fn build_grpc_server_tls_acceptor(
cert_path: &str, cert_path: &str,
key_path: &str, key_path: &str,
@ -156,6 +170,41 @@ fn build_grpc_server_tls_acceptor(
Some(TlsAcceptor::from(Arc::new(server_config))) Some(TlsAcceptor::from(Arc::new(server_config)))
} }
fn build_http_server_tls_acceptor(
config: &VolumeServerConfig,
) -> Result<Option<TlsAcceptor>, Box<dyn std::error::Error>> {
if config.https_cert_file.is_empty() || config.https_key_file.is_empty() {
return Ok(None);
}
let effective_policy = effective_http_tls_policy(&config.https_ca_file, &config.tls_policy);
let tls_config = match build_rustls_server_config(
&config.https_cert_file,
&config.https_key_file,
&config.https_ca_file,
&effective_policy,
) {
Ok(tls_config) => tls_config,
Err(e)
if !config.https_ca_file.is_empty() && tls_policy_is_configured(&config.tls_policy) =>
{
warn!(
"Failed to apply HTTP TLS policy '{}', falling back to default rustls policy",
e
);
build_rustls_server_config(
&config.https_cert_file,
&config.https_key_file,
&config.https_ca_file,
&TlsPolicy::default(),
)?
}
Err(e) => return Err(e.into()),
};
Ok(Some(TlsAcceptor::from(Arc::new(tls_config))))
}
async fn run(config: VolumeServerConfig) -> Result<(), Box<dyn std::error::Error>> { async fn run(config: VolumeServerConfig) -> Result<(), Box<dyn std::error::Error>> {
// Initialize the store // Initialize the store
let mut store = Store::new(config.index_type); let mut store = Store::new(config.index_type);
@ -396,13 +445,7 @@ async fn run(config: VolumeServerConfig) -> Result<(), Box<dyn std::error::Error
"TLS enabled for HTTP server (cert={}, key={})", "TLS enabled for HTTP server (cert={}, key={})",
config.https_cert_file, config.https_key_file config.https_cert_file, config.https_key_file
); );
let tls_config = build_rustls_server_config(
&config.https_cert_file,
&config.https_key_file,
&config.https_ca_file,
&config.tls_policy,
)?;
Some(TlsAcceptor::from(Arc::new(tls_config)))
build_http_server_tls_acceptor(&config)?
} else { } else {
None None
}; };
@ -745,7 +788,9 @@ async fn serve_https<F>(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::build_grpc_server_tls_acceptor;
use super::{
build_grpc_server_tls_acceptor, effective_http_tls_policy, tls_policy_is_configured,
};
use seaweed_volume::security::tls::TlsPolicy; use seaweed_volume::security::tls::TlsPolicy;
fn write_pem(dir: &tempfile::TempDir, name: &str, body: &str) -> String { fn write_pem(dir: &tempfile::TempDir, name: &str, body: &str) -> String {
@ -820,4 +865,31 @@ mod tests {
) )
.is_none()); .is_none());
} }
#[test]
fn test_effective_http_tls_policy_ignores_tls_policy_without_ca() {
let configured = TlsPolicy {
min_version: "TLS 1.3".to_string(),
max_version: "TLS 1.3".to_string(),
cipher_suites: "TLS_AES_128_GCM_SHA256".to_string(),
};
assert_eq!(
effective_http_tls_policy("", &configured),
TlsPolicy::default()
);
assert_eq!(
effective_http_tls_policy("/etc/seaweedfs/http-ca.pem", &configured),
configured
);
}
#[test]
fn test_tls_policy_is_configured_detects_non_empty_fields() {
assert!(!tls_policy_is_configured(&TlsPolicy::default()));
assert!(tls_policy_is_configured(&TlsPolicy {
min_version: "TLS 1.2".to_string(),
max_version: String::new(),
cipher_suites: String::new(),
}));
}
} }
Loading…
Cancel
Save