Skip to main content

Auditor

Struct Auditor 

Source
pub struct Auditor { /* private fields */ }
Expand description

Writes audit rows, and resolves the reverse names that go in them.

One per process, shared by the ACME listener (crate::AppState), the web admin (crate::webadmin::AdminState) and the CLI. Process-wide because [audit] is: the trail describes the CA, not one of its endpoints.

Implementations§

Source§

impl Auditor

Source

pub fn from_config( cfg: &AuditConfig, dns: &DnsConfig, database: Arc<Database>, metrics: Arc<Metrics>, ) -> Result<Self>

Builds the auditor, and with it the cached resolver its PTR lookups go through.

Cached, unlike the shared resolver Profile::build_all threads through the challenge and signer subsystems, and for the reason filter::reverse_dns makes the same choice: a PTR record for an address that keeps connecting is exactly what a cache is for, and there is no just-published-record problem here — the answer being a few minutes old is not a failure mode for a column that says “the name this address had at the time”.

A second cached resolver rather than sharing reverse_dns’s: that one is per-profile and built only when the filter is enabled, and reaching across for it would tie the audit trail’s completeness to whether an unrelated filter happens to be switched on. metrics is a required argument and deliberately not a builder step. It was one, briefly, and the omission it invited happened immediately: the serving path built its auditor without ever calling the builder, so acme_proxy_certificates_issued_total stayed at zero in production while every test passed — the test harness wired the registry itself, so what the tests proved was the harness’s wiring and not the server’s. A parameter cannot be forgotten. Test scaffolding that genuinely has no registry uses Auditor::with_resolver instead.

Source

pub fn with_resolver( database: Arc<Database>, resolver: Option<Arc<dyn Resolver>>, ptr_timeout: Duration, ) -> Self

Same, against a caller-supplied resolver — or none, for the reverse lookup switched off. Used by tests and by Self::from_config.

Source

pub async fn reverse(&self, ip: Option<IpAddr>) -> Option<String>

The reverse name for ip, or None.

Every failure is None: no PTR record, a resolver that timed out, a SERVFAIL, audit.reverse_dns off, or no client address at all. Nothing downstream distinguishes them, because nothing downstream authorises on this value — it is a label on a row, and a label that is sometimes missing is worth more than a request that failed to get one.

The first name only when several PTR records answer. Storing all of them would make the column a list nothing queries; filter.reverse_dns is where multiple candidates genuinely matter, and it looks them up itself.

Source

pub async fn client(&self, request: &RequestContext) -> ClientContext

Resolves a RequestContext into the ClientContext a row stores, running the reverse lookup on the way.

Source

pub fn with_metrics(self, metrics: Arc<Metrics>) -> Self

Attaches the Prometheus registry to an auditor built by Auditor::with_resolver.

Exists for the test harness, which builds its auditor with a stub resolver and still wants the counters. The serving path does not use this — Auditor::from_config takes the registry as a parameter, so it cannot be left off.

Source

pub async fn record(&self, record: AuditRecord)

Writes one row, and counts it.

The counter is driven off the same AuditRecord that is about to be stored, which is what makes “how many certificates did we issue” answer identically whether it is asked of the metrics endpoint or of acme-proxy audit list. A second set of call sites incrementing counters beside the audit writes would have been free to drift.

See write(), which this is the stateful spelling of.

Trait Implementations§

Source§

impl Debug for Auditor

Source§

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

Renders the configured policy. dyn Resolver is not Debug, so the resolver shows as whether there is one — which is the whole of what it contributes to behaviour here.

Auto Trait Implementations§

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
Source§

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

Source§

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

Source§

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

Source§

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
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

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

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

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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

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

Initializes a with the given initializer. Read more
Source§

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

Dereferences the given pointer. Read more
Source§

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

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

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

impl<T> Same for T

Source§

type Output = T

Should always be Self
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, <T as TryFrom<U>>::Error>

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.
Source§

impl<T> WithSubscriber for T

Source§

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
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

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