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
impl Auditor
Sourcepub fn from_config(
cfg: &AuditConfig,
dns: &DnsConfig,
database: Arc<Database>,
metrics: Arc<Metrics>,
) -> Result<Self>
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.
Sourcepub fn with_resolver(
database: Arc<Database>,
resolver: Option<Arc<dyn Resolver>>,
ptr_timeout: Duration,
) -> Self
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.
Sourcepub async fn reverse(&self, ip: Option<IpAddr>) -> Option<String>
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.
Sourcepub async fn client(&self, request: &RequestContext) -> ClientContext
pub async fn client(&self, request: &RequestContext) -> ClientContext
Resolves a RequestContext into the ClientContext a row stores,
running the reverse lookup on the way.
Sourcepub fn with_metrics(self, metrics: Arc<Metrics>) -> Self
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.
Sourcepub async fn record(&self, record: AuditRecord)
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§
Auto Trait Implementations§
impl !RefUnwindSafe for Auditor
impl !UnwindSafe for Auditor
impl Freeze for Auditor
impl Send for Auditor
impl Sync for Auditor
impl Unpin for Auditor
impl UnsafeUnpin for Auditor
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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