smtpd-starttls-proxy
Software
skarnet.org
The qmail-remote program
qmail-remote is an SMTP client, meant to be used as a drop-in
replacement to the
qmail-remote
implementation in the original
qmail MTA, its
netqmail distribution, or its modern
notqmail successor.
It is not meant to be invoked directly by the user; it only makes sense
in the context of a qmail, netqmail or notqmail installation.
Interface
qmail-remote follows the exact same interface as the stock
qmail-remote.
The binary can literally be dropped
in /var/qmail/bin, replacing the previous binary by the same name.
With certain qmail patches, it can also be used without overwriting anything,
by running qmail with the QMAILREMOTE environment variable set to the path
where this version of qmail-remote is installed.
Differences with other implementations of qmail-remote
The main benefits of this qmail-remote implementations are the following:
- If the underlying OS and skalibs
support IPv6, then this qmail-remote does as well, and uses IPv4 and IPv6
addresses indiscriminately when connecting to an MX.
- It will use STARTTLS if the server supports it.
- All its DNS resolutions are done in parallel, which eliminates some
pathological cases where the original qmail-remote can hang around doing
nothing for a long time.
Control files
qmail-remote uses the following control files in /var/qmail/control:
- me, helohost, smtproutes, timeoutconnect, timeoutremote
- These files are used in the exact same way as in
stock qmail-remote.
- timeoutdns
- Number of seconds will wait for any given DNS resolution to succeed. Default:
0, which means infinite (never time out on a resolution).
- ipme
- A list of the network IP addresses of the local machine, one per line. These can be
IPv4 or IPv6, in textual format. These addresses are used to eliminate SMTP loops:
qmail-remote will never connect to these addresses and never deliver mail
to them. Note that the stock qmail-remote automatically detects the local
IP addresses; this has several problems, one being OS portability, and another
being that this autodetection is just impossible in IPv6 — so we
delegate the listing of local IPs to the user here. Also, the best way to avoid
SMTP loops remains making sure that your locals and virtualdomains
files are correct and up-to-date, so that qmail-remote will never be
invoked on a recipient that should be handled locally.
- trustanchors
- Contains the path to the certificates for known trust anchors for X.509
certificate validation. If the path ends with a slash, like /etc/ssl/certs/,
then it is interpreted as a directory containing hashes to the certificates. If
it does not, like /etc/ssl/cert.pem, then it is interpreted as a big
PEM file containing all the trust anchors. If the file is nonexistent or empty,
or only contains a newline, then STARTTLS is not attempted. Note that the
trust anchor list is only useful when tlsstrictness is 2 (see below),
but you still need a non-empty list in order to attempt STARTTLS.
- clientcert
- If this file exists and is nonempty, it must contain the path to a client
certificate. This certificate will be sent to the server during a TLS negotiation.
This is useful in certain setups requiring client authentication.
- clientkey
- This file must be used in conjunction with clientcert. It contains
the path to the private key used to sign the client certificate. Note that access
to the private key file should be as restricted as possible, but the qmailr
user (or whatever user qmail-remote runs as) must be able to read it.
- tlsstrictness
- This file contains an integer representing the strictness level expected of
TLS connections. The default is 0, and means that an SMTP exchange
will attempt to use STARTTLS if the trustanchors information is provided
and the server advertises the capability, but will
proceed in cleartext if the server does not advertise STARTTLS support, or if the
STARTTLS command fails. 1 means that qmail-remote will
attempt to find a server that supports STARTTLS in order to transmit its e-mail,
but will fallback to cleartext if it cannot find any. 2 means that
qmail-remote will flat out refuse to send e-mail to servers that do not
support STARTTLS or fail to set it up. It will also properly verify certificates,
whereas a value lower than 2 doesn't care if the certificate chain does not begin
with a trusted anchor (since it would eventually fall back on an insecure
transport anyway).
Implementation notes
- At installation time, qmail-remote creates the
/var/qmail/run directory, to host run-time information, and
the /var/qmail/run/qmail-remote directory, writable by user
qmailr. You can customize the qmail location and users at
configure time.
- At run-time, qmail-remote stores some information under
/var/qmail/run/qmail-remote:
- smtproutes.cdb is a cdb file containing the artificial
SMTP routes, automatically compiled from /var/qmail/control/smtproutes
whenever it changes. qmail-remote reads its route information
from the cdb file. This is a more efficient mechanism than the original
"constmap" one.
- smtproutes.lock, a lock file used when reading and
writing smtproutes.cdb.
- tcpto6, a binary file hosting connection timeout information
in a similar way to /var/qmail/queue/lock/tcpto, but for IPv6.
qmail-remote reuses the same tcpto file as the original
for IPv4 timeouts, and is still compatible with the
qmail-tcpto
program; however, a new file was necessary for IPv6, and creating it
under /var/qmail/queue/lock was tricky because the qmail queue
has very precise permissions and it is better to leave it untouched.
Since qmail-remote needed a new directory writable by qmailr
to host its SMTP routes map anyway, storing the tcpto6 files in the
same place is a logical decision.
- qmail-remote uses the
skadns library
to perform DNS resolutions asynchronously. If you see a weird skadnsd
process running as a child of qmail-remote, that's why.
- The whole SMTP exchange can happen either over a TLS-encrypted connection
after a STARTTLS command, or over a cleartext connection. To separate TLS
management from the SMTP client and avoid duplication of code, the SMTP
exchange is actually handled by a separate binary:
qmail-remote-io. If your process list
shows a qmail-remote-io process under qmail-rspawn instead
of the regular qmail-remote, that is normal, it means that
qmail-remote has found a suitable server and is transmitting its
data. If qmail-remote has a qmail-remote-io
child that itself has a
s6-tlsc-io
child, it means that the transfer is happening under TLS.