cloudflare / cloudflare/pingora

Provide TlsRef details to HTTP/2 requests

Open
#775 3 comments 2 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
27.4k
Forks
1.7k
Avg merge
6h 22m
Merged PRs (30d)
3

Description

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

TLS information can be valuable for security purposes. Cloudflare implements JA4 fingerprinting in its own security services.

https://blog.foxio.io/ja4+-network-fingerprinting
https://blog.cloudflare.com/ja4-signals/

Currently Pingora appears to discard TLS information on HTTP/2 requests. It is very possible to make a JA4 fingerprint inside `request_filter` if the request is HTTP/1. HTTP/2 does not provide the same information.

pingora::http::client.rs
```
/// Get the reference of the [Stream] that this HTTP/1 session is operating upon.
/// None if the HTTP session is over H2
pub fn stream(&self) -> Option<&Stream> {
match self {
Self::H1(s) => Some(s.stream()),
Self::H2(_) => None,
Self::Custom(_) => None,
}
}
```

## Describe the solution you'd like

Please provide some way to access `TlsRef` for HTTP/2 requests via `.stream()`, same as HTTP/1.

If Pingora is adverse to creating a lookup table for SSL information, please provide callbacks with useful information (SocketAddr?) that would allow the developer to create his own.

## Describe alternatives you've considered

Accessing this information with HTTP2 has been very frustrating. The underlying TLS information is discarded before the first request cycle begins, so there is no promise `request_filter` is ever called as HTTP/1.1 before movnig to HTTP/2. The developer has no appropriate window to begin tracking this information.

I had the idea to try and record the SocketAddr being used for that HTTP2 session using `set_client_hello_callback`, but unfortunately OpenSSL does not provide any information on the client ip or ephemeral port being used for that session. I attempted to look in C-land for ways to associate the handshake with subsequent requests but it is not obvious and I really don't know what I'm doing there. I can JA4 fingerprint in this callback, but I cannot store it in any meaningful way.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.