Skip to main content

TlsMitmRelay

Struct TlsMitmRelay 

pub struct TlsMitmRelay<Issuer> { /* private fields */ }
Available on crate feature boring only.
Expand description

A utility that can be used by MITM services such as transparent proxies, in order to relay (and MITM a TLS connection between a client and server, as part of a deep protocol inspection protocol (DPI) flow.

With the http feature, a per-flow TargetHttpVersion is a best-effort preference. The relay narrows its upstream ALPN offer only when a peeked ingress ClientHello can negotiate the same protocol (or when HTTP/1.1 is its natural no-ALPN fallback). Otherwise the preference is ignored because this TLS relay does not translate HTTP versions and the intercepted client remains authoritative. Upstream negotiation may also decline the preferred protocol. Without an applicable preference, normal ClientHello mirroring and upstream negotiation decide the concrete HTTP version.

Implementations§

§

impl<Issuer> TlsMitmRelay<Issuer>

pub fn new(issuer: Issuer) -> TlsMitmRelay<Issuer>

Create a new TlsMitmRelay.

pub fn with_grease_enabled(self, enabled: bool) -> TlsMitmRelay<Issuer>

Set whether GREASE should be enabled for the ingress-side TLS acceptor.

By default is is enabled (true).

pub fn set_grease_enabled(&mut self, enabled: bool) -> &mut TlsMitmRelay<Issuer>

Set whether GREASE should be enabled for the ingress-side TLS acceptor.

By default is is enabled (true).

pub fn with_keylog_intent(self, intent: KeyLogIntent) -> TlsMitmRelay<Issuer>

Set the KeyLogIntent.

Default is KeyLogIntent::Environment, matching Chrome, Firefox, curl, and most TLS stacks: a non-empty SSLKEYLOGFILE env var enables key logging. In a MITM relay this exports session keys for both the ingress (relay-mirrored) and egress (upstream) sides, so anyone with read access to the keylog file can decrypt every relayed flow. Treat the file as security-sensitive (restricted dir, rotate, delete when done) and pick KeyLogIntent::Disabled if your deployment shouldn’t honour the env var at all.

pub fn set_keylog_intent( &mut self, intent: KeyLogIntent, ) -> &mut TlsMitmRelay<Issuer>

Set the KeyLogIntent.

Default is KeyLogIntent::Environment, matching Chrome, Firefox, curl, and most TLS stacks: a non-empty SSLKEYLOGFILE env var enables key logging. In a MITM relay this exports session keys for both the ingress (relay-mirrored) and egress (upstream) sides, so anyone with read access to the keylog file can decrypt every relayed flow. Treat the file as security-sensitive (restricted dir, rotate, delete when done) and pick KeyLogIntent::Disabled if your deployment shouldn’t honour the env var at all.

pub fn keylog_intent_ref(&self) -> &KeyLogIntent

Borrow the currently-configured KeyLogIntent. Useful when constructing a sibling relay (e.g. after a CA rotation) that should share the same sink — a Custom(Arc<dyn KeyLogSink>) cloned this way keeps writing through the same backing toggle.

pub fn maybe_with_egress_server_auth( self, policy: Option<TlsMitmEgressServerAuth>, ) -> TlsMitmRelay<Issuer>

Set the optional server-authentication policy for upstream TLS.

This policy controls only upstream certificate and identity verification. It cannot override the ClientHello fingerprint, protocol negotiation, client authentication, or key logging.

Upstream certificate verification is disabled by default, both with no policy and for TlsMitmEgressServerAuth::default. This preserves transparent relay behavior for certificates the intercepted client may choose to accept. Select rama_tls::client::ServerVerifyMode::Auto explicitly to enforce upstream certificate and hostname verification.

Direct Self::handshake calls apply this policy when their connector_data argument is None. Explicit connector data is authoritative because it is already a fully-resolved backend configuration; TlsMitmRelayService supplies such data only after applying this policy itself.

pub fn maybe_set_egress_server_auth( &mut self, policy: Option<TlsMitmEgressServerAuth>, ) -> &mut TlsMitmRelay<Issuer>

Set the optional server-authentication policy for upstream TLS.

This policy controls only upstream certificate and identity verification. It cannot override the ClientHello fingerprint, protocol negotiation, client authentication, or key logging.

Upstream certificate verification is disabled by default, both with no policy and for TlsMitmEgressServerAuth::default. This preserves transparent relay behavior for certificates the intercepted client may choose to accept. Select rama_tls::client::ServerVerifyMode::Auto explicitly to enforce upstream certificate and hostname verification.

Direct Self::handshake calls apply this policy when their connector_data argument is None. Explicit connector data is authoritative because it is already a fully-resolved backend configuration; TlsMitmRelayService supplies such data only after applying this policy itself.

pub fn with_egress_server_auth( self, policy: TlsMitmEgressServerAuth, ) -> TlsMitmRelay<Issuer>

Set the optional server-authentication policy for upstream TLS.

This policy controls only upstream certificate and identity verification. It cannot override the ClientHello fingerprint, protocol negotiation, client authentication, or key logging.

Upstream certificate verification is disabled by default, both with no policy and for TlsMitmEgressServerAuth::default. This preserves transparent relay behavior for certificates the intercepted client may choose to accept. Select rama_tls::client::ServerVerifyMode::Auto explicitly to enforce upstream certificate and hostname verification.

Direct Self::handshake calls apply this policy when their connector_data argument is None. Explicit connector data is authoritative because it is already a fully-resolved backend configuration; TlsMitmRelayService supplies such data only after applying this policy itself.

pub fn set_egress_server_auth( &mut self, policy: TlsMitmEgressServerAuth, ) -> &mut TlsMitmRelay<Issuer>

Set the optional server-authentication policy for upstream TLS.

This policy controls only upstream certificate and identity verification. It cannot override the ClientHello fingerprint, protocol negotiation, client authentication, or key logging.

Upstream certificate verification is disabled by default, both with no policy and for TlsMitmEgressServerAuth::default. This preserves transparent relay behavior for certificates the intercepted client may choose to accept. Select rama_tls::client::ServerVerifyMode::Auto explicitly to enforce upstream certificate and hostname verification.

Direct Self::handshake calls apply this policy when their connector_data argument is None. Explicit connector data is authoritative because it is already a fully-resolved backend configuration; TlsMitmRelayService supplies such data only after applying this policy itself.

pub fn without_egress_server_auth(self) -> TlsMitmRelay<Issuer>

Set the optional server-authentication policy for upstream TLS.

This policy controls only upstream certificate and identity verification. It cannot override the ClientHello fingerprint, protocol negotiation, client authentication, or key logging.

Upstream certificate verification is disabled by default, both with no policy and for TlsMitmEgressServerAuth::default. This preserves transparent relay behavior for certificates the intercepted client may choose to accept. Select rama_tls::client::ServerVerifyMode::Auto explicitly to enforce upstream certificate and hostname verification.

Direct Self::handshake calls apply this policy when their connector_data argument is None. Explicit connector data is authoritative because it is already a fully-resolved backend configuration; TlsMitmRelayService supplies such data only after applying this policy itself.

pub fn unset_egress_server_auth(&mut self) -> &mut TlsMitmRelay<Issuer>

Set the optional server-authentication policy for upstream TLS.

This policy controls only upstream certificate and identity verification. It cannot override the ClientHello fingerprint, protocol negotiation, client authentication, or key logging.

Upstream certificate verification is disabled by default, both with no policy and for TlsMitmEgressServerAuth::default. This preserves transparent relay behavior for certificates the intercepted client may choose to accept. Select rama_tls::client::ServerVerifyMode::Auto explicitly to enforce upstream certificate and hostname verification.

Direct Self::handshake calls apply this policy when their connector_data argument is None. Explicit connector data is authoritative because it is already a fully-resolved backend configuration; TlsMitmRelayService supplies such data only after applying this policy itself.

pub fn egress_server_auth_ref(&self) -> Option<&TlsMitmEgressServerAuth>

Borrow the configured upstream server-authentication policy, if any.

§

impl<Issuer> TlsMitmRelay<CachedBoringMitmCertIssuer<Issuer>>

pub fn new_with_cached_issuer( issuer: Issuer, ) -> TlsMitmRelay<CachedBoringMitmCertIssuer<Issuer>>

Create a new TlsMitmRelay, with a cache layer on top top of the provided issuer toprovide reuse functionality of previously issued certs.

pub fn new_with_cached_issuer_and_config( issuer: Issuer, cfg: BoringMitmCertIssuerCacheConfig, ) -> TlsMitmRelay<CachedBoringMitmCertIssuer<Issuer>>

Create a new TlsMitmRelay, with a cache layer (created by given config) on top of the provided issuer to provide reuse functionality of previously issued certs.

§

impl TlsMitmRelay<InMemoryBoringMitmCertIssuer>

pub fn try_new_with_self_signed_issuer( data: &SelfSignedCaConfig, ) -> Result<TlsMitmRelay<InMemoryBoringMitmCertIssuer>, Box<dyn Error + Send + Sync>>

Create a new TlsMitmRelay with self-signed CA using the given data.

pub fn new_in_memory( crt: X509, key: PKey<Private>, ) -> TlsMitmRelay<InMemoryBoringMitmCertIssuer>

Create a new TlsMitmRelay with the provided CA pair.

§

impl TlsMitmRelay<CachedBoringMitmCertIssuer<InMemoryBoringMitmCertIssuer>>

pub fn try_new_with_cached_self_signed_issuer( data: &SelfSignedCaConfig, ) -> Result<TlsMitmRelay<CachedBoringMitmCertIssuer<InMemoryBoringMitmCertIssuer>>, Box<dyn Error + Send + Sync>>

Create a new TlsMitmRelay with self-signed CA using the given data, with a cache layer on top to provide reuse functionality of previously issued certs.

pub fn try_new_with_cached_self_signed_issuer_and_config( data: &SelfSignedCaConfig, cfg: BoringMitmCertIssuerCacheConfig, ) -> Result<TlsMitmRelay<CachedBoringMitmCertIssuer<InMemoryBoringMitmCertIssuer>>, Box<dyn Error + Send + Sync>>

Create a new TlsMitmRelay with self-signed CA using the given data, with a cache layer (created by given config) on top to provide reuse functionality of previously issued certs.

pub fn new_cached_in_memory( crt: X509, key: PKey<Private>, ) -> TlsMitmRelay<CachedBoringMitmCertIssuer<InMemoryBoringMitmCertIssuer>>

Create a new TlsMitmRelay with the provided CA pair, with a cache layer on top to provide reuse functionality of previously issued certs.

pub fn new_cached_in_memory_with_config( crt: X509, key: PKey<Private>, cfg: BoringMitmCertIssuerCacheConfig, ) -> TlsMitmRelay<CachedBoringMitmCertIssuer<InMemoryBoringMitmCertIssuer>>

Create a new TlsMitmRelay with the provided CA pair, with a cache layer (created by given config) on top to provide reuse functionality of previously issued certs.

§

impl<Issuer> TlsMitmRelay<Issuer>
where Issuer: BoringMitmCertIssuer, <Issuer as BoringMitmCertIssuer>::Error: Into<Box<dyn Error + Send + Sync>>,

pub async fn handshake<Ingress, Egress>( &self, input: BridgeIo<Ingress, Egress>, connector_data: Option<TlsConnectorData>, ) -> Result<BridgeIo<TlsStream<Ingress>, TlsStream<Egress>>, TlsMitmRelayError>
where Ingress: Io + Unpin + ExtensionsRef, Egress: Io + Unpin + ExtensionsRef,

Establish and MITM a handshake between the client (ingress) and server (egress).

When connector_data is None, the relay derives it from its key-log intent and TlsMitmEgressServerAuth. With no authentication policy, upstream verification remains disabled to preserve transparent relay behavior. The direct handshake has no peeked ClientHello to mirror; it can use a ConnectorTarget from the ingress extensions as a fallback identity only when verification or pinning requires one.

Explicit connector_data is authoritative. This is primarily used by TlsMitmRelayService, which has already combined the relay policy with the peeked ClientHello and per-flow preferences.

Trait Implementations§

§

impl<Issuer> Clone for TlsMitmRelay<Issuer>
where Issuer: Clone,

§

fn clone(&self) -> TlsMitmRelay<Issuer>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl<Issuer> Debug for TlsMitmRelay<Issuer>
where Issuer: Debug,

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<S, Issuer> Layer<S> for TlsMitmRelay<Issuer>
where Issuer: Clone,

§

type Service = TlsMitmRelayService<Issuer, S>

The service produced by the layer.
§

fn layer(&self, inner: S) -> <TlsMitmRelay<Issuer> as Layer<S>>::Service

Wrap the given service with the middleware, returning a new service.
§

fn into_layer(self, inner: S) -> <TlsMitmRelay<Issuer> as Layer<S>>::Service

Same as layer but consuming self after the service was created. Read more

Auto Trait Implementations§

§

impl<Issuer> !RefUnwindSafe for TlsMitmRelay<Issuer>

§

impl<Issuer> !UnwindSafe for TlsMitmRelay<Issuer>

§

impl<Issuer> Freeze for TlsMitmRelay<Issuer>
where Issuer: Freeze,

§

impl<Issuer> Send for TlsMitmRelay<Issuer>
where Issuer: Send,

§

impl<Issuer> Sync for TlsMitmRelay<Issuer>
where Issuer: Sync,

§

impl<Issuer> Unpin for TlsMitmRelay<Issuer>
where Issuer: Unpin,

§

impl<Issuer> UnsafeUnpin for TlsMitmRelay<Issuer>
where Issuer: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a rama_grpc::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
§

impl<T, U> RamaFrom<T> for U
where U: From<T>,

§

fn rama_from(value: T) -> U

§

impl<T, U, CrateMarker> RamaInto<U, CrateMarker> for T
where U: RamaFrom<T, CrateMarker>,

§

fn rama_into(self) -> U

§

impl<T, U> RamaTryFrom<T> for U
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

§

fn rama_try_from(value: T) -> Result<U, <U as RamaTryFrom<T>>::Error>

§

impl<T, U, CrateMarker> RamaTryInto<U, CrateMarker> for T
where U: RamaTryFrom<T, CrateMarker>,

§

type Error = <U as RamaTryFrom<T, CrateMarker>>::Error

§

fn rama_try_into(self) -> Result<U, <U as RamaTryFrom<T, CrateMarker>>::Error>

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<V, F> ValueFormatter<&V> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &&V)

Write value to writer
§

impl<V, F> ValueFormatter<Arc<V>> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &Arc<V>)

Write value to writer
§

impl<V, F> ValueFormatter<Box<V>> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &Box<V>)

Write value to writer
§

impl<V, F> ValueFormatter<Cow<'_, V>> for F
where V: ToOwned + ?Sized, F: ValueFormatter<V> + ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &Cow<'_, V>)

Write value to writer
§

impl<V, F> ValueFormatter<Option<V>> for F
where F: ValueFormatter<V> + ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &Option<V>)

Write value to writer
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more