The web server: the status UI and the admin API, served with Plug and
Cowboy on admin.address and admin.port (127.0.0.1:9025 by
default), with TLS from the certificate store when admin.tls is set.
/api/...- the admin API (Sovite.Core.Web.API), forsovitectl, monitoring, and the UI./metrics- Prometheus metrics (Sovite.Core.Metrics).- Everything else - the UI: the static build of
lib/core/sovite_web, fromadmin.web_root, orpriv/webin the release.
Ports 80 and 443 stay with ACME (tls.acme) and the MTA-STS policy
server (mta_sts.serve).
Security
The UI will have users of its own, so the web server is built for untrusted clients:
- Only clients in
admin.allowed_networks(loopback by default) get an answer other than403. - The API and
/metricsneed the bearer token fromadmin.token_file(created with a random token, mode0600, if it does not exist), compared in constant time./metricscan be made public withadmin.public_metrics. - Wrong tokens count as failed logins, like SMTP
AUTHones: they are logged asauth.failure(for fail2ban), and afterauth.max_failureswithinauth.failure_windowthe client gets429forauth.ban_time. - Requests that change something (
POST) from another site, by theirOriginorSec-Fetch-Site, get403, and no cross-origin (CORS) access is granted, so pages elsewhere can neither read the API nor act on it. - Every response has strict security headers: a
Content-Security-Policythat allows the UI's own scripts only (inline scripts of its pages by their hash), no framing, no referrer,nosniff, same-origin opener and resource policies, a permissions policy that turns off device access, and with TLS,Strict-Transport-Security. API responses are never cached. - Request lines, headers, and connections are limited, and slow clients time out.
Telemetry
[:sovite, :web, :request, :stop]-%{duration},%{method, path, status, remote_ip}[:sovite, :web, :request, :exception]-%{},%{method, path, kind, reason}: a request that crashed, answered with500.[:sovite, :auth, :failure]withmechanism: "TOKEN"andreason: :invalid_tokenfor a wrong token.
Summary
Functions
The child specs of the web server for config: the failed-token
counter and the Cowboy listener. [] with admin.enabled = false, or
when the token file cannot be used (logged).
Reads the token in path, or creates the file with a random token if
it does not exist. Returns {:error, text} if it cannot.
Functions
@spec child_specs(Sovite.Core.Config.t(), map()) :: [Supervisor.child_spec()]
The child specs of the web server for config: the failed-token
counter and the Cowboy listener. [] with admin.enabled = false, or
when the token file cannot be used (logged).
Reads the token in path, or creates the file with a random token if
it does not exist. Returns {:error, text} if it cannot.