From e8c519f54e7bfb7653459bac2eeee48d0e483965 Mon Sep 17 00:00:00 2001 From: Zhang Jingqiang Date: Thu, 19 Oct 2023 17:40:20 +0800 Subject: [PATCH] allow to use session ticket for rustls session resumption --- g3proxy/doc/configuration/values/tls.rst | 12 ++++++++++++ g3tiles/src/config/server/rustls_proxy/host.rs | 13 ++++++++++++- lib/g3-json/src/value/rustls.rs | 5 +++++ lib/g3-types/src/net/rustls/server.rs | 12 +++++++++++- lib/g3-yaml/src/value/rustls.rs | 6 ++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/g3proxy/doc/configuration/values/tls.rst b/g3proxy/doc/configuration/values/tls.rst index c7cf77af..9646a5c1 100644 --- a/g3proxy/doc/configuration/values/tls.rst +++ b/g3proxy/doc/configuration/values/tls.rst @@ -449,6 +449,18 @@ The map is consists of the following fields: Set if you want to enable client auth. + **default**: disabled + +* use_session_ticket + + **optional**, **type**: bool + + Set if we should enable TLS session ticket to do TLS Session Resumption without Server-Side State. + + .. versionchanged:: 1.7.28 + + **default**: disabled + * ca_certificate | client_auth_certificate **optional**, **type**: :ref:`tls certificates ` diff --git a/g3tiles/src/config/server/rustls_proxy/host.rs b/g3tiles/src/config/server/rustls_proxy/host.rs index d780ae79..f88109cd 100644 --- a/g3tiles/src/config/server/rustls_proxy/host.rs +++ b/g3tiles/src/config/server/rustls_proxy/host.rs @@ -19,7 +19,7 @@ use std::time::Duration; use anyhow::{anyhow, Context}; use rustls::server::AllowAnyAuthenticatedClient; -use rustls::{Certificate, RootCertStore, ServerConfig}; +use rustls::{Certificate, RootCertStore, ServerConfig, Ticketer}; use yaml_rust::Yaml; use g3_types::collection::NamedValue; @@ -38,6 +38,7 @@ pub(crate) struct RustlsHostConfig { cert_pairs: Vec, client_auth: bool, client_auth_certs: Vec, + use_session_ticket: bool, pub(crate) accept_timeout: Duration, pub(crate) request_alive_max: Option, pub(crate) request_rate_limit: Option, @@ -53,6 +54,7 @@ impl Default for RustlsHostConfig { cert_pairs: Vec::with_capacity(1), client_auth: false, client_auth_certs: Vec::new(), + use_session_ticket: false, accept_timeout: Duration::from_secs(60), request_alive_max: None, request_rate_limit: None, @@ -110,6 +112,10 @@ impl RustlsHostConfig { let mut config = config_builder.with_cert_resolver(Arc::new(cert_resolver)); config.session_storage = Arc::new(RustlsServerSessionCache::default()); + if self.use_session_ticket { + config.ticketer = + Ticketer::new().map_err(|e| anyhow!("failed to create ticketer: {e}"))?; + } if !self.services.is_empty() { for protocol in self.services.protocols() { @@ -150,6 +156,11 @@ impl YamlMapCallback for RustlsHostConfig { .context(format!("invalid value for key {key}"))?; Ok(()) } + "use_session_ticket" => { + self.use_session_ticket = g3_yaml::value::as_bool(value) + .context(format!("invalid value for key {key}"))?; + Ok(()) + } "ca_certificate" | "ca_cert" | "client_auth_certificate" | "client_auth_cert" => { let lookup_dir = g3_daemon::config::get_lookup_dir(doc)?; let certs = g3_yaml::value::as_rustls_certificates(value, Some(lookup_dir)) diff --git a/lib/g3-json/src/value/rustls.rs b/lib/g3-json/src/value/rustls.rs index dfe64dc7..bf68eb0b 100644 --- a/lib/g3-json/src/value/rustls.rs +++ b/lib/g3-json/src/value/rustls.rs @@ -236,6 +236,11 @@ pub fn as_rustls_server_config_builder(value: &Value) -> anyhow::Result { + let enable = + crate::value::as_bool(v).context(format!("invalid value for key {k}"))?; + builder.set_use_session_ticket(enable); + } "ca_certificate" | "ca_cert" | "client_auth_certificate" | "client_auth_cert" => { let certs = as_rustls_certificates(v).context(format!("invalid value for key {k}"))?; diff --git a/lib/g3-types/src/net/rustls/server.rs b/lib/g3-types/src/net/rustls/server.rs index 2d54ccd3..6e3cc5be 100644 --- a/lib/g3-types/src/net/rustls/server.rs +++ b/lib/g3-types/src/net/rustls/server.rs @@ -19,7 +19,7 @@ use std::time::Duration; use anyhow::{anyhow, Context}; use rustls::server::AllowAnyAuthenticatedClient; -use rustls::{Certificate, RootCertStore, ServerConfig}; +use rustls::{Certificate, RootCertStore, ServerConfig, Ticketer}; use super::{MultipleCertResolver, RustlsCertificatePair, RustlsServerSessionCache}; use crate::net::tls::AlpnProtocol; @@ -35,6 +35,7 @@ pub struct RustlsServerConfigBuilder { cert_pairs: Vec, client_auth: bool, client_auth_certs: Option>, + use_session_ticket: bool, accept_timeout: Duration, } @@ -44,6 +45,7 @@ impl RustlsServerConfigBuilder { cert_pairs: Vec::with_capacity(1), client_auth: false, client_auth_certs: None, + use_session_ticket: false, accept_timeout: Duration::from_secs(10), } } @@ -56,6 +58,10 @@ impl RustlsServerConfigBuilder { Ok(()) } + pub fn set_use_session_ticket(&mut self, enable: bool) { + self.use_session_ticket = enable; + } + pub fn enable_client_auth(&mut self) { self.client_auth = true; } @@ -120,6 +126,10 @@ impl RustlsServerConfigBuilder { } }; config.session_storage = Arc::new(RustlsServerSessionCache::default()); + if self.use_session_ticket { + config.ticketer = + Ticketer::new().map_err(|e| anyhow!("failed to create ticketer: {e}"))?; + } if let Some(protocols) = alpn_protocols { for proto in protocols { diff --git a/lib/g3-yaml/src/value/rustls.rs b/lib/g3-yaml/src/value/rustls.rs index cea34f58..a7776fc9 100644 --- a/lib/g3-yaml/src/value/rustls.rs +++ b/lib/g3-yaml/src/value/rustls.rs @@ -280,6 +280,12 @@ pub fn as_rustls_server_config_builder( } Ok(()) } + "use_session_ticket" => { + let enable = + crate::value::as_bool(v).context(format!("invalid value for key {k}"))?; + builder.set_use_session_ticket(enable); + Ok(()) + } "ca_certificate" | "ca_cert" | "client_auth_certificate" | "client_auth_cert" => { let certs = as_rustls_certificates(v, lookup_dir) .context(format!("invalid value for key {k}"))?;