A small library, command-line utility, Prometheus exporter, and JSON/HTTP/FastAPI service to check DANE/TLSA-RRs against SMTP servers.
Project description
What is SMTP-DANE-Verify ?
Problems with DANE usally stem from TLSA Resource Records (TLSA-RR) that don’t matchcthe SMTP service’s x509 certificate fingerprint. This happens if not only the certificate was renewed, but also the private key because then the certificates fingerprint changes. It also happens if a certificate from a new vendor is used in production and, of course, also if those creating the TLSA Resource Record get something wrong and the TLSA record doesn’t match right from the start. Whatever reason if no TLSA-RR matches DANE verification will fail and DANE verifying servers will not send messages to a mismatching SMTP service.
SMTP DANE Verify will not prevent you from publishing mismatching TLSA Resource Records, but it will help you to detect that there is a mismatch. It provides a service that verifies one of more TLSA-RRs, published for a SMTP service, match the service’s x509 certificate fingerprint.
Use it as external probing service in your monitoring platform. Tell it which host to verify and it will reply if the test was valid or not. Designed as a standalone service meant to be used as probing tool by monitoring services it exposes a REST API that communicates in JSON. Internally it uses openssl routines to do the probing.
You can install and run smtp-dane-verify as a service and run it on a machine or you download and run smtp-dane-verify as docker container. We recommend the latter. It’s hassle free.
Using the command-line interface (CLI)
After installing the dane-smtp the command danesmtp is available. The
shell status code of the command is 0 when validation is completed
succesfully, 1 (or greater) otherwise.
% danesmtp --help
usage: danesmtp [--help] [-u USAGES] [-o OPENSSL] [-n NAMESERVER] [--no-strict-dnssec] [-f FORMAT] [-h HOSTNAME] [-a ADDRESS] [-d DOMAIN]
Verify that your DANE records and your SMTP server are configured correctly.
options: --help show this help message and exit -u USAGES, --usages
USAGES The usages parameter (default: 2,3) -o OPENSSL, --openssl OPENSSL
Path to the openssl binary, default: "openssl" -n NAMESERVER,
--nameserver NAMESERVER Optional IP address of an external nameserver,
by default the default resolver will be used. -f FORMAT, --format FORMAT
Select the output format. Available formats: json, text -h HOSTNAME,
--hostname HOSTNAME, --host HOSTNAME The SMTP server hostname to be
checked (either --hostname or --domain is required) -a ADDRESS,
--address ADDRESS Overwrite the address of the mail server, only to be
used with --hostname. -d DOMAIN, --domain DOMAIN The domain to be
checked (either --hostname or --domain is required) --no-strict-dnssec
Relax on the DNSSEC verification of the TLSA records.
The CLI can easily be used with other tool by switcing the output format to JSON:
[source,console]
% danesmtp -f json -h mail.example.com { "host_dane_verified": true, "protocol_version": "TLSv1.2", "hostname": "mail.example.com", "ciphersuite": "ECDHE-RSA-AES256-GCM-SHA384", "peer_certificate": "CN=mail.example.com", "hash_used": "SHA256", "signature_type": "RSA", "verification": "OK", "openssl_return_code": 0, "log_messages": [] }
With additional toolin like "jq" you can easily extract data from the JSON output,
example:
[source,console]
% danesmtp -f json -h mail.example.com | jq .verification "OK"
== Running smtp-dane-verify as docker container
smtp-dane-verify expects the service that queries for a probe to authenticate
itself using an API key. This API key must be known to smtp-dane-verify
beforehand. Create an API key e.g. executing `base64 /dev/urandom | head -c30`
on the command line like this:
[source,console]
% base64 /dev/urandom | head -c30 SAsMTaxKPbTZwD0c25cCZE/JXJAtqi
Then use the output as `APIKEY` environment variable in smtp-dane-verify's
`docker-compose.yml` configuration file. By default smtp-dane-verify will use on
any available network interface on port `3000`. The following example changes
that and binds smtp-dane-verify explicitly on `::1`. Still it exposes port
`3000` to the outside and forwards it internally to the same port:
[source,yaml]
.docker-compose.yml
name: smtp-dane-verify services: smtp-tlsa-verify: image: sys4ag/smtp-dane-verify container_name: smtp-dane-verify environment: APIKEY: SAsMTaxKPbTZwD0c25cCZE/JXJAtqi ports: - "[::]:3000:3000" restart: always
In this example all docker instances are located in `/opt/$CONTAINER` on the
host machine. To start smtp-dane-verify either change into
`/opt/smtp-dane-verify` and excute:
% docker up -d
Or, alternatively and if you use systemd, create a systemd service unit file
`/etc/systemd/system/docker-compose@.service` like this:
[source,ini]
.docker-compose@.service
Description=%i service with docker compose Requires=docker.service After=docker.service
WorkingDirectory=/opt/%i ExecStartPre=-/usr/bin/docker compose pull ExecStart=/usr/bin/docker compose up --remove-orphans ExecStop=/usr/bin/docker compose down ExecReload=/usr/bin/docker compose pull ExecReload=/usr/bin/docker compose up --remove-orphans
WantedBy=multi-user.target
Then use the systemd service template and create a systemd unit file for
`smtp-dane-verify` like this:
% systemctl enable --now docker-compose@smtp-dane-verify.service
This will enable *and* start the service. If you start `smtp-dane-verify` for
the first time, docker will initially download the container
`sys4ag/smtp-dane-verify` and then it will start it. If this step was
successfull you will be able to verify `smtp-dane-verify` has bound itself to
port `3000/tcp` listening on IPv6 only:
[source,console]
lsof -Pni tcp:3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME docker-pr 481892 root 7u IPv6 3259319 0t0 TCP *:3000 (LISTEN)
Your `smtp-dane-verify` docker container should now be ready to probe hosts.
Verify it works using the following command and your personal APIKEY:
[source,console]
curl --header "x-apikey: SAsMTaxKPbTZwD0c25cCZE/JXJAtqi" \ --header "Content-Type: application/json" \ --request POST \ --data '{"hostname":"mail2.ietf.org"}' \ http://[::1]:3000/verify/
Upon return `smtp-dane-verify` will output
https://www.rfc-editor.org/rfc/rfc8259[RFC 8259] formatted JSON data:
[source,json]
{ "host_dane_verified":true, "protocol_version":"TLSv1.3", "hostname":"mail2.ietf.org.", "ciphersuite":"TLS_AES_256_GCM_SHA384", "peer_certificate":"CN = *.ietf.org", "hash_used":"SHA256", "signature_type":"ECDSA", "verification":"OK", "openssl_return_code":0, "log_messages": [] }
If `smtp-dane-verify` works like this for you you can start integrating it into
your monitoring service.
== Monitoring services
=== Prometheus
In order for the Prometheus exporter to work you need to add the following environment variables:
METRICS_DOMAINS=example.com,mysecondexample.com
Multiple domains need to by separated by commas.
The variable METRICS_INTERVAL=<int:interval in seconds> controls the interval at which the SMTP-DANE records are queried an checked in the background.
[source,yaml]
scrape_configs: - job_name: dane-smtp-verify params: api_key: - <insert your API key here> static_configs: - labels: {} targets: - localhost:8080
=== Uptime Kuma
[quote,Uptime Kuma,Website]
Uptime Kuma is an easy-to-use self-hosted monitoring tool.
.Uptime Kuma "Add New Monitor" dialogue
image::assets/kuma_add_new_monitor.png[]
Follow these steps to integrate `smtp-dane-verify` into Uptime Kuma:
. Choose menu:Add New Monitor[] and select menu:HTTP(s) - Json Query[] as
menu:Monitor Type[] in the
menu:General[] section of the menu:Add New Monitor[] dialogue.
. Give the Monitor a menu:Friendly Name[] e.g. `SMTP DANE Verify`.
. Enter `http://[::1]:3000/verify/` as menu:URL[].
. Enter `host_dane_verified` into the menu:Json Query[] form field
. Enter `true` in the menu:Expected Value[] form field.
. Then turn to the menu:HTTP Options[] section and add the host you want to
probe as JSON DATA e.g. like this: `{ "hostname": "mail2.ietf.org" }`
. Finally provide your `APIKEY` by writing it into the menu:Headers[] form field like
this: `{ "x-apikey": "SAsMTaxKPbTZwD0c25cCZE/JXJAtqi" }`
. btn:[Save] the menu:Add New Monitor[] dialogue
// By default the docker container will be available on port 3000.
//
// ```
// docker run -p3000:3000 smtp-tlsa-verify
// ```
//
// In order to run the command under a different port number, please use the
// "-p" parameter:
//
// ```
// docker run -p4000:4000 smtp-tlsa-verify -p 4000
// ```
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smtp_dane_verify-0.3.0.tar.gz.
File metadata
- Download URL: smtp_dane_verify-0.3.0.tar.gz
- Upload date:
- Size: 1.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f14bdb3671f2eb08db9c4f98391d43f92cb7e856be5b4f83e689f0db652e316
|
|
| MD5 |
25a9998b73297c9be178b4ebbf529c33
|
|
| BLAKE2b-256 |
51c2c600380c7dd2096e772af2be312631d1283c77e0f11565e17aa151ba73bb
|
File details
Details for the file smtp_dane_verify-0.3.0-py3-none-any.whl.
File metadata
- Download URL: smtp_dane_verify-0.3.0-py3-none-any.whl
- Upload date:
- Size: 28.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b45a21a53c99bda6b75c855ce689c6df5dec5db01edb1e14168b4e1eeaaa900a
|
|
| MD5 |
529e2a16e28935a489b6f9868ad45799
|
|
| BLAKE2b-256 |
fd518475e7775b80a2e637c061b6aa70fb5b8b9e9e0e9206e66ac8f045d10179
|