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.
