reconsider handling sni in http1.1 and 2 tls

This commit is contained in:
Jun Kurihara 2022-07-21 11:59:46 +09:00
commit 548fb77c31
No known key found for this signature in database
GPG key ID: 48ADFD173ED22B03
2 changed files with 24 additions and 26 deletions

View file

@ -1,5 +1,7 @@
// use super::proxy_handler::handle_request; // use super::proxy_handler::handle_request;
use crate::{error::*, globals::Globals, log::*, msg_handler::HttpMessageHandler}; use crate::{
backend::ServerNameLC, error::*, globals::Globals, log::*, msg_handler::HttpMessageHandler,
};
use hyper::{client::connect::Connect, server::conn::Http, service::service_fn, Body, Request}; use hyper::{client::connect::Connect, server::conn::Http, service::service_fn, Body, Request};
use std::{net::SocketAddr, sync::Arc}; use std::{net::SocketAddr, sync::Arc};
use tokio::{ use tokio::{
@ -50,7 +52,7 @@ where
stream: I, stream: I,
server: Http<LocalExecutor>, server: Http<LocalExecutor>,
peer_addr: SocketAddr, peer_addr: SocketAddr,
tls_server_name: Option<&[u8]>, tls_server_name: Option<ServerNameLC>,
) where ) where
I: AsyncRead + AsyncWrite + Send + Unpin + 'static, I: AsyncRead + AsyncWrite + Send + Unpin + 'static,
{ {
@ -60,7 +62,7 @@ where
return; return;
} }
let inner = tls_server_name.map_or_else(|| None, |v| Some(v.to_vec())); // let inner = tls_server_name.map_or_else(|| None, |v| Some(v.as_bytes().to_ascii_lowercase()));
self.globals.runtime_handle.clone().spawn(async move { self.globals.runtime_handle.clone().spawn(async move {
timeout( timeout(
self.globals.proxy_timeout + Duration::from_secs(1), self.globals.proxy_timeout + Duration::from_secs(1),
@ -73,7 +75,7 @@ where
peer_addr, peer_addr,
self.listening_on, self.listening_on,
self.tls_enabled, self.tls_enabled,
inner.clone(), tls_server_name.clone(),
) )
}), }),
) )

View file

@ -7,6 +7,7 @@ use hyper::{client::connect::Connect, server::conn::Http};
use rustls::ServerConfig; use rustls::ServerConfig;
use std::sync::Arc; use std::sync::Arc;
use tokio::{net::TcpListener, sync::watch, time::Duration}; use tokio::{net::TcpListener, sync::watch, time::Duration};
use tokio_rustls::TlsAcceptor;
impl<T> Proxy<T> impl<T> Proxy<T>
where where
@ -41,40 +42,35 @@ where
let tcp_listener = TcpListener::bind(&self.listening_on).await?; let tcp_listener = TcpListener::bind(&self.listening_on).await?;
info!("Start TCP proxy serving with HTTPS request for configured host names"); info!("Start TCP proxy serving with HTTPS request for configured host names");
let mut server_crypto: Option<Arc<ServerConfig>> = None; // let mut server_crypto: Option<Arc<ServerConfig>> = None;
let mut tls_acceptor: Option<TlsAcceptor> = None;
loop { loop {
select! { select! {
tcp_cnx = tcp_listener.accept().fuse() => { tcp_cnx = tcp_listener.accept().fuse() => {
// First check SNI if tls_acceptor.is_none() || tcp_cnx.is_err() {
let rustls_acceptor = rustls::server::Acceptor::new();
if server_crypto.is_none() || tcp_cnx.is_err() || rustls_acceptor.is_err() {
continue; continue;
} }
let (raw_stream, _client_addr) = tcp_cnx.unwrap();
let acceptor = tokio_rustls::LazyConfigAcceptor::new(rustls_acceptor.unwrap(), raw_stream).await;
if acceptor.is_err() {
continue;
}
let start = acceptor.unwrap();
let client_hello = start.client_hello(); let (raw_stream, _client_addr) = tcp_cnx.unwrap();
// Find server config for given SNI
if client_hello.server_name().is_none(){ if let Ok(stream) = tls_acceptor.as_ref().unwrap().accept(raw_stream).await {
info!("No SNI in ClientHello"); // Retrieve SNI
continue; let (_, conn) = stream.get_ref();
} let server_name = conn.sni_hostname();
let server_name = client_hello.server_name().unwrap().to_ascii_lowercase(); debug!("HTTP/2 or 1.1: SNI in ClientHello: {:?}", server_name);
debug!("SNI in ClientHello: {:?}", server_name); let server_name = server_name.map_or_else(|| None, |v| Some(v.as_bytes().to_ascii_lowercase()));
// Finally serve the TLS connection if server_name.is_none(){
if let Ok(stream) = start.into_stream(server_crypto.clone().unwrap()).await { continue;
self.clone().client_serve(stream, server.clone(), _client_addr, Some(server_name.as_bytes())) }
self.clone().client_serve(stream, server.clone(), _client_addr, server_name); // TODO: don't want to pass copied value...
} }
} }
_ = server_crypto_rx.changed().fuse() => { _ = server_crypto_rx.changed().fuse() => {
if server_crypto_rx.borrow().is_none() { if server_crypto_rx.borrow().is_none() {
break; break;
} }
server_crypto = server_crypto_rx.borrow().clone(); let server_crypto = server_crypto_rx.borrow().clone().unwrap();
tls_acceptor = Some(TlsAcceptor::from(server_crypto));
} }
complete => break complete => break
} }