mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-15 12:10:37 +00:00
support mtls
This commit is contained in:
@@ -134,6 +134,9 @@ struct ProxyCliArgs {
|
||||
/// tls-key and tls-cert are for backwards compatibility, we can put all certs in one dir
|
||||
#[clap(short = 'c', long, alias = "ssl-cert")]
|
||||
tls_cert: Option<PathBuf>,
|
||||
/// path to mTLS certs for client postgres connections
|
||||
#[clap(long)]
|
||||
mtls_certs: Option<PathBuf>,
|
||||
/// Allow writing TLS session keys to the given file pointed to by the environment variable `SSLKEYLOGFILE`.
|
||||
#[clap(long, alias = "allow-ssl-keylogfile")]
|
||||
allow_tls_keylogfile: bool,
|
||||
@@ -625,6 +628,7 @@ fn build_config(args: &ProxyCliArgs) -> anyhow::Result<&'static ProxyConfig> {
|
||||
(Some(key_path), Some(cert_path)) => Some(config::configure_tls(
|
||||
key_path,
|
||||
cert_path,
|
||||
args.mtls_certs.as_deref(),
|
||||
args.certs_dir.as_deref(),
|
||||
args.allow_tls_keylogfile,
|
||||
)?),
|
||||
|
||||
@@ -493,6 +493,7 @@ pub(crate) async fn refresh_config_inner(
|
||||
tls_config.key_path.as_ref(),
|
||||
tls_config.cert_path.as_ref(),
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -4,8 +4,10 @@ use std::sync::Arc;
|
||||
|
||||
use anyhow::{Context, bail};
|
||||
use itertools::Itertools;
|
||||
use rustls::RootCertStore;
|
||||
use rustls::crypto::ring::{self, sign};
|
||||
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
|
||||
use rustls::server::WebPkiClientVerifier;
|
||||
use rustls::sign::CertifiedKey;
|
||||
use x509_cert::der::{Reader, SliceReader};
|
||||
|
||||
@@ -24,12 +26,37 @@ pub struct TlsConfig {
|
||||
pub fn configure_tls(
|
||||
key_path: &Path,
|
||||
cert_path: &Path,
|
||||
mtls_certs_dir: Option<&Path>,
|
||||
certs_dir: Option<&Path>,
|
||||
allow_tls_keylogfile: bool,
|
||||
) -> anyhow::Result<TlsConfig> {
|
||||
// add default certificate
|
||||
let mut cert_resolver = CertResolver::parse_new(key_path, cert_path)?;
|
||||
|
||||
let verifier = match mtls_certs_dir {
|
||||
Some(dir) => {
|
||||
let mut roots = RootCertStore::empty();
|
||||
|
||||
for entry in std::fs::read_dir(dir)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
|
||||
if path.is_file() {
|
||||
let cert_chain_bytes = std::fs::read(&path).context(format!(
|
||||
"Failed to read TLS cert file at '{}.'",
|
||||
path.display()
|
||||
))?;
|
||||
|
||||
for cert in rustls_pemfile::certs(&mut &cert_chain_bytes[..]) {
|
||||
roots.add(cert?)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
WebPkiClientVerifier::builder(Arc::new(roots)).build()?
|
||||
}
|
||||
None => WebPkiClientVerifier::no_client_auth(),
|
||||
};
|
||||
|
||||
// add extra certificates
|
||||
if let Some(certs_dir) = certs_dir {
|
||||
for entry in std::fs::read_dir(certs_dir)? {
|
||||
@@ -55,7 +82,7 @@ pub fn configure_tls(
|
||||
rustls::ServerConfig::builder_with_provider(Arc::new(ring::default_provider()))
|
||||
.with_protocol_versions(&[&rustls::version::TLS13, &rustls::version::TLS12])
|
||||
.context("ring should support TLS1.2 and TLS1.3")?
|
||||
.with_no_client_auth()
|
||||
.with_client_cert_verifier(verifier)
|
||||
.with_cert_resolver(cert_resolver.clone());
|
||||
|
||||
config.alpn_protocols = vec![PG_ALPN_PROTOCOL.to_vec()];
|
||||
|
||||
Reference in New Issue
Block a user