Skip to content

Be able to get the SNI from the HTTP filter context #547

@pszabop

Description

@pszabop

What is the problem your feature solves, or the need it fulfills?

I would like to be able to get the SNI when in the req_filter() callback, so that I can do some business logic on it with the HTTP HOST header.

Describe the solution you'd like

In the self or more likely the session, store the SNI (e.g. in the downstream session) so it can be retrieved. The SSL Digest is available in the req_filter and that would be a suitable place to put it. (session.digest();)

Describe alternatives you've considered

I tried to dive into the stream and get to the get_ssl() function, but was unable to figure out how (or if it is possible) to downcast stream to the SslStream.

if let Some(stream) = session.stream() {
    println!("session stream: {:?}", stream);
    println!("Actual type of stream: {}", std::any::type_name_of_val(&stream));
    // downcast it somehow
    // then
        if let Some(ssl) = ssl_stream.get_ssl() {
            if let Some(sni) = ssl.servername(pingora::tls::ssl::NameType::HOST_NAME) {

but the 5-6 methods I tried for downcasting didn't work. It would also be a lot of insider baseball even if it did work and likely fragile.

Additional context

From looking at the code, the SNI is not extracted anywhere. It is available in the TLS callback via a call to the underlying ssl instance but since there's no HTTP context there's no place to put it.

#[async_trait]
impl pingora::listeners::TlsAccept for DynamicCert {
    async fn certificate_callback(&self, ssl: &mut pingora::tls::ssl::SslRef) {
        // Inspect the SNI
        if let Some(sni) = ssl.servername(pingora::tls::ssl::NameType::HOST_NAME) {
            println!("SNI: {}", sni);
        }
        ext::ssl_use_certificate(ssl, &self.cert).unwrap();
        ext::ssl_use_private_key(ssl, &self.key).unwrap();
    }
}

It's possible I missed an ext field somewhere where the SNI could be stuffed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions