feat(targets): enhance webhook TLS support with custom CA and skip-verify (#1994)

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: houseme <4829346+houseme@users.noreply.github.com>
Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
houseme
2026-02-27 21:24:49 +08:00
committed by GitHub
parent bdb2a9e9b7
commit d17d2083d4
19 changed files with 182 additions and 83 deletions
+16 -17
View File
@@ -15,11 +15,11 @@
use crate::get_env_bool;
use rustfs_config::{RUSTFS_TLS_CERT, RUSTFS_TLS_KEY};
use rustls::RootCertStore;
use rustls::server::danger::ClientCertVerifier;
use rustls::server::{ClientHello, ResolvesServerCert, ResolvesServerCertUsingSni, WebPkiClientVerifier};
use rustls::server::{
ClientHello, ResolvesServerCert, ResolvesServerCertUsingSni, WebPkiClientVerifier, danger::ClientCertVerifier,
};
use rustls::sign::CertifiedKey;
use rustls_pemfile::{certs, private_key};
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
use rustls_pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject};
use std::collections::HashMap;
use std::io::Error;
use std::path::Path;
@@ -42,7 +42,7 @@ pub fn load_certs(filename: &str) -> io::Result<Vec<CertificateDer<'static>>> {
let mut reader = io::BufReader::new(cert_file);
// Load and return certificate.
let certs = certs(&mut reader)
let certs = CertificateDer::pem_reader_iter(&mut reader)
.collect::<Result<Vec<_>, _>>()
.map_err(|e| certs_error(format!("certificate file {filename} format error:{e:?}")))?;
if certs.is_empty() {
@@ -65,7 +65,7 @@ pub fn load_cert_bundle_der_bytes(path: &str) -> io::Result<Vec<Vec<u8>>> {
let pem = fs::read(path)?;
let mut reader = io::BufReader::new(&pem[..]);
let certs = certs(&mut reader)
let certs = CertificateDer::pem_reader_iter(&mut reader)
.collect::<Result<Vec<_>, _>>()
.map_err(|e| certs_error(format!("Failed to parse PEM certs from {path}: {e}")))?;
@@ -139,7 +139,8 @@ pub fn load_private_key(filename: &str) -> io::Result<PrivateKeyDer<'static>> {
let mut reader = io::BufReader::new(keyfile);
// Load and return a single private key.
private_key(&mut reader)?.ok_or_else(|| certs_error(format!("no private key found in {filename}")))
PrivateKeyDer::from_pem_reader(&mut reader)
.map_err(|e| certs_error(format!("failed to parse private key in {filename}: {e}")))
}
/// error function
@@ -319,13 +320,14 @@ pub fn create_multi_cert_resolver(
/// * A boolean indicating whether TLS key logging is enabled based on the `RUSTFS_TLS_KEYLOG` environment variable.
///
pub fn tls_key_log() -> bool {
crate::get_env_bool(rustfs_config::ENV_TLS_KEYLOG, rustfs_config::DEFAULT_TLS_KEYLOG)
get_env_bool(rustfs_config::ENV_TLS_KEYLOG, rustfs_config::DEFAULT_TLS_KEYLOG)
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use std::io::ErrorKind;
use tempfile::TempDir;
#[test]
@@ -333,7 +335,7 @@ mod tests {
let error_msg = "Test error message";
let error = certs_error(error_msg.to_string());
assert_eq!(error.kind(), std::io::ErrorKind::Other);
assert_eq!(error.kind(), ErrorKind::Other);
assert_eq!(error.to_string(), error_msg);
}
@@ -343,7 +345,7 @@ mod tests {
assert!(result.is_err());
let error = result.unwrap_err();
assert_eq!(error.kind(), std::io::ErrorKind::Other);
assert_eq!(error.kind(), ErrorKind::Other);
assert!(error.to_string().contains("failed to open"));
}
@@ -353,7 +355,7 @@ mod tests {
assert!(result.is_err());
let error = result.unwrap_err();
assert_eq!(error.kind(), std::io::ErrorKind::Other);
assert_eq!(error.kind(), ErrorKind::Other);
assert!(error.to_string().contains("failed to open"));
}
@@ -393,7 +395,7 @@ mod tests {
assert!(result.is_err());
let error = result.unwrap_err();
assert!(error.to_string().contains("no private key found"));
assert!(error.to_string().contains("failed to parse private key in"));
}
#[test]
@@ -406,7 +408,7 @@ mod tests {
assert!(result.is_err());
let error = result.unwrap_err();
assert!(error.to_string().contains("no private key found"));
assert!(error.to_string().contains("failed to parse private key in"));
}
#[test]
@@ -585,11 +587,8 @@ mod tests {
#[test]
fn test_memory_efficiency() {
// Test that error types are reasonably sized
use std::mem;
let error = certs_error("test".to_string());
let error_size = mem::size_of_val(&error);
let error_size = std::mem::size_of_val(&error);
// Error should not be excessively large
assert!(error_size < 1024, "Error size should be reasonable, got {error_size} bytes");