7. Malware Protection
We consider the following types of malware:
- Infected mails with virii and trojan horses targeting the operating system of the MDA, the MUA, or perhaps the MTA. However, most likely the MUA running on top of the Windows (TM) Operating System.
- Advanced Persistent Threat (APT) malware targeting the specific user to react upon receiving and reading the mail.
- Spam mails, also known as Unsolicited Commercial E-Mails UCE, being distributed deliberately for commercial or fraud reasons and wide-spread targeting unspecified.
What can we do about it?
Virus protection is actually .... almost impossible. Spam protection ist at least difficult and may lead to unwanted results. There exist two scenarios:
- The virus (or pattern) is known and fed to an anti-virus tool.
- The virus is new (zero day attack); no chance or just by luck.
A virus may originate from
- a (untrusted) host in the Internet
- a trusted sender (host of originating mail address).
Beware of the sender ...
Spam - on the other side - originates mostly from unknown senders (MTA). Thus, there is a good chance to at least control the level of finally accepted spam mails such, neither the MTA nor the final recipient is bothered to much.
Email forgery ...
qmail-smtpd provides some methods to deal with email forgery. Email forgery means, that the purported sender uses an identity (given by the 'Mail From:' SMTP envelope variable or perhaps the authenticated user) is faked, thus does not represent the 'original' sender.
Emails can be easily forged. Most MUAs or MDAs are not able to 'understand' forged emails. Even worse: Some MUAs don't require to insist on coherent sending information. Thus, the recipient can not judge the quality of the received identity.
However, lets at first make some abbreviations and usual terms clear:
- MTA (Mail Transfer Agent) is the sending or recipient host transmitting a (email) message based on the SMTP protocol and is responsible to obey the the rules of the SMTP envelope.
- MUA (Mail User Agent) is the software the user is aware of to read and to send email from. The MUA usually uses SMTP to send, POP3 and/or IMAP4 to receive those.
- MDA (Mail Delivery Agent) is a piece of software transferring (and perhaps filering) the message from the MTA to the Mailbox (or Maildir) of the user. Under Unix, procmail is a common MDA, my QMVC is another one.
Quick links:
- 7.1 Delivery pipeline
- 7.2 The BADMIMETYPE Filter
- 7.3 The BADLOADERTYPE Filter
- 7.4 STARTTLS and SMTPS support for qmail-remote
- 7.5 Spam Prevention
- 7.6 Greylisting in qmail-smtpd
- 7.7 Preventing email forgery
- 7.8 Interrogating SMTP envelope and connection variables
- 7.9 Qmail QUEUE_EXTRA
7.1 Delivery pipeline to protect from malware
The methods to protect against malware can be categorized:
- Pre-receipt: The sender has to undergo a certain qualification, or dis-qualified sender are not permitted. Usual mechanisms are Greylisting, Greetdelay Relay Black Lists, and other DNS based approaches.
- During-receipt: While the content is received from the sender, it is analysed by internal mechanisms or external tools, like a Virus or Spam scanner. Once the content is identified as 'malware' the SMTP transaction is closed ungracefully.
- Post-receipt: The email is accepted by the MTA but now the MDA is responsible.
With qmail-smtpd joined by typically
- sslserver and
- rblsmtpd and now in addition with
- qmail-postgrey (using a Postgrey daemon)
you can setup a 'malware protection pipeline' which is able to qualify mail/malware at the earliest step in the reception process. Here, you find the 'big picture' including all the possible steps:
As one can see, there exist essentialy two checklines:
- The numbers 1 to 6 denote qualification checks on the sender and potentially for the recipient as well. The first steps are carried out by sslserver and rblsmtpd; in particular considering Greetdelay.
- The letters a, b and c are a defense line against the content of the mail.
Here, we have:
- Internal: The WARLORD extension.
- Semi-internal: The Qmail High Performance Scanner Interface QHPSI.
- External: The 'standard' Qmail QUEUE-EXTRA mechanism.
7.1.1 Mailware mail prevention
The early detection of potential malware senders is the clue to protect users and the email system itself, since virus mail detection is (apart from WARLORD) resource intensive. Thus the following steps can be applied:
- Check, if the sending MTA is properly listed in the DNS.
- Is the sending MTA able to cope with Greetdelay?
- Does a RBL signature exist for the sending IP address of the MTA?
- Is the HELLO/EHLO greeting of the MTA valid?
- Can the Mail From: address/domain found in the DNS?
- Is there and existing SPF record available to point to forgery?
- Is the recpient address valid (Recipients extension)?
- Can the sending client cope with Greylisting?
- What does eventually SpamAssassin say?
As we can see from the previous picture, the Q/A's are provided in different modules. The earlier a (potential negative) answer is given, the less resources are required. In the following sections, we discuss the methods which are inherent to s/qmail and in partcular qmail-smtpd.
7.1.2 Virus mail detection
s/qmail and in particular qmail-smtpd includes my WARLORD extension, which is a much robuster and efficient filter for BASE64 encoded MIME attachments and bundled with the Qmail High Performance Scanner Interface (QHPSI):
- BASE64 encoded MIME attachments are detected and can be filtered accordingly to an easily extendable badmimetypes file.
- Within the BASE64 encoded MIME attachments so-called specific loader assignments (ie. for Windows OS) can be detected and messages - containing these suspicious badloadertypes patterns - are rejected.
- Additional and optional on-the-fly scanning of emails through the QHPSI.
- Initial badmimetype or badloadertype flagged messages are not subject of the QHPSI.
- Employing the environment variable BASE64, QHPSI is advised to by-pass virus scanning if no BASE64 encoded attachment is found.
In case a badmimetype or badloadertype filter condition is met or a virus is detected, qmail-smtpd sends a SMTP 554 reply to the sender "554 sorry, invalid message content (#5.3.2)". Populating the REPLY554 environment variable, allows to include additional information (typically an URL), which can be used to deal with potential false-positives.
The 'traditional' QUEUE-EXTRA mechanism allows s/qmail to plug-in any other other Spam or virus scanner, for instance:
... and probably many others (like AMaViS).
7.2 The BADMIMETYPE filter
The badmimetype filter becomes active if
Note: Setting BADMIMETYPE="+" without a cdb is equivalent to BADMIMETYPE="!" for none-RELAYCLIENTS.
7.2.1 Control file badmimetypes and badmimetypes.cdb
The control file control/badmimetypes.cdb is populated by the additional program qmail-badmimetypes which takes the input of control/badmimetypes. New MIME signatures can be added/removed on-the-fly. Bad MIME Type signatures have to have the length of at least 9 significant characters.
The currently included MIME signatures are:
Adding new badmimetypes is simple:
- Send an E-Mail to a Unix account with corresponding attachment (i.e. *.zip).
- Use an editor to view the E-Mail and spot the corresponding BASE64 encoded content-type.
- Take the first nine significant characters (for type "zip" its "UEsDBAkAA") and include them into control/badmimetypes.
- Run qmail-badmimetypes .
Comments (starting with "#") are allowed in badmimetypes; the length of the signature will be truncated to nine characters.
7.3 The BADLOADERTYPE-Filter
The badloadertype filter becomes active if
- the environment variable BADLOADERTYPE="M" is set (see below)
- and the control file badloadertypes is populated and readable by qmail-smtpd.
- As exception, you can define BADLOADERTYPE="-" to disable the check. This is useful for particular hosts as provided within rules.smtpd.tcp.cdb.
- The badloadertypes check can be conditionally disabled for RELAYCLIENTS (eg. once authenticated), in case BADLOADERTYPE="+" is set.
The BADLOADERTYPE mechanism deals in particular with "transport stealth" worms, ie. UPX encoded Windows executables.
7.3.1 Control file badloadertypes and badloadertypes.cdb
badloadertypes.cdb is populated by the additional program qmail-badloadertypes which takes the input of control/badloadertypes The badloadertype mechanism looks for five significant strings in the BASE64 encoded data-stream which is matched against an entry in control/badloadertypes.cdb. badloadertype signatures can be added/removed on-the-fly employing qmail-badloadertypes.
The currently included Windows OS badloadertype signatures are:
Comments (starting with "#") are allowed in badloadertypes; the length of the signature will be truncated to five characters.
Caution: Unlike the badmimetype, the badloadertype signatures are placed anywhere in the BASE64 encoded datastream and are difficult to find out. In order to make the search efficient, a common character has to be providen in the environment variable BADLOADERTYPE. The provided pattern look basically for a string like "32.dll" as a subpart of "Kernel32.dll" which is an indication for an executable for the Windows OS. However, there is a small chance for false positives. Some - lets say - Word document attached as BASE64 MIME part in the message containing the buzz words "kernel32.dll" might become flagged and finally rejected as well.
7.4 Employing an AV Scanner with QHPSI
Unlike all other AV Scanners currently in use for Qmail, with Qmail High Performance Scanner Interface (QHPSI) there is no need for any other umbrella program, neither qmail-scanner, AMAViS, qscanq or whatsoever. Further, no additional MIME analyzing program like reformime, metamail, or ripmime is required. Even better, no "staging" area for temporary files are needed, except the one, the AV Scanners requires for itself.
Today's AV Scanners - and in particular Clam AV - are able to read the BASE64 encoded message and eventually dig out the files in archives, ie. in zip format. In order to use an AV Scanner with QHPSI, the AV Scanner has to have the following qualifications:
- Correct interpretation of the BASE64 and perhaps the uudecoded data in order to detect the virii/worms therein.
- Results have to be made available on STDERR/STDOUT.
- (And perhaps) Suppression of 'negative' scan results.
The QHPSI allows to use the following environment variables:
- QHPSI="av_scanner" - this is the path to the involved AV Scanner.
- QHPSIARG1, QHAPSIARG2, QHPSIARG3 - to call the AV Scanner with three arbitrary arguments.
- QHPSIRC="RC" - if the AV Scanner does not return with RC=1 in case of a detected infection, you can specify one here.
- QHPSIMINSIZE="size-in-bytes" - the minimum size of the message to scan.
- QHPSIMAXSIZE="size-in-bytes" - the maximum size of the message to scan.
The AV Scanner is directly called in the start scripts of Qmail (i.e. the run script for qmail-smtpd) or by means of tcpserver or sslserver's capabilities. Here is a typical example, how to customize QHPSI together with Clam AV (clamd/clamdscan) for a rules.smptd.tcp control file:
Comments:
- The path of clamdscan can be omitted, because it is in the standard path (/usr/local/bin).
- The argument QHPSIARG1='--disable-summary' tells Clam AV to provide a single line output of the scan results.
- In clamd's clamav.conf configuration file the "Mail support" has to be enabled, clamd has to run as root.
Note:
- qmail-start does not pass environment variables to qmail-queue.
- If you need to scan in addition outgoing emails, you have to write a wrapper for e.g. qmail-inject:
The quality of virus scanning of ClamAV is questionable. Currently, ClamAV's version is 0.99.2 (January, 2017). It seems the development is stalled somehow. Virus detection - regarding new virii - is bad.
7.4.1 QHPSI SMTP Reply messages
Results:
- In case a client sends an infected email by means of SMTP, it receives the SMTP return code and error message: "554 mail server permanently rejected message (#5.3.0)"
- In case the virus scanner can not be called properly or has an internal problem, the following SMTP message is given: "454 mail server temporarily rejected message (#4.3.0)"
- Eventually, the scan results show up in the logs.
7.4.2 QHPSI logging
Here is a sample of Clam AV without and with the argument "--disable-summary":
Note: Even in case no virus is detected, the "SCAN SUMMARY" is provided.
Attention:
- The virus scanner has to be able to read the messages in
the Qmail queue:
# ls -ld /var/qmail/queue/mess/
drwxr-x--- 25 qmailq qmail 4096 Jun 13 00:19 /var/qmail/queue/mess/ - If the virus scanner drops privileges during execution, it might be necessary to make the executable sticky (ie. clamscan).
Note: As with this writing, clamav 0.8x is broken, since it writes all logs to STDOUT instead of STDERR; thus no scanning messages will appear in the qmail-smtpd log.
7.4.3 QHPSI performance improvements for Virus Scanning
The badmimtypes and badloadertypes mechanism provides a wire-speed filtering of incoming emails. However, typically all not-filtered emails are subject of the AV Scannner as defined via the QHPSI. Almost all worms and virii are transported as BASE64 encoded attachments (except some trojans, encapsulated as HTML files). By means of the environment variable
- BASE64=""
one can advice QHPSI to scan only those emails which contain a BASE64 encoded attachment.
Calling an AV-scanner is resource intensive. On the one hand, it is impossible to include a virus in 'small' messages (see SQL-Slammer); on the other hand, it is unlikely, that a 'large' email is used to transport a virus; since this is not efficient.
QHPSI can be advised to invoke the virus scanner only under the following conditions:
- QHPSIMINSIZE: The received email is above a certain size (in byte; lets say 1024 byte).
- QHPSIMAXSIZE: The received email is below a certain size. AV-scanning of large files takes a lot of resources and can be omitted.
Note: Phishing emails might be small. Depending on your AV scanner, phishing mails may be detected.
7.5 Spam Prevention
While classical spam prevention is closely connected understand and do an interpretation of the content of the email message, the much more effective and efficient mechanism is to recognize and deal with the sending conditions of spam mails:
- Spam (and virus mails) are send from bot-net computers; however this is less frequent now (2021).
- Some spam mails are send via misconfigured MTAs (open relays).
- Some spam mails are send over 'legitimate' MTAs.
Once, a handle regarding sending from bot-nets is given, control can be re-established. Two means are used for this purpose:
- Greylisting: The sender is initially greylisted and a sending attempt is accepted only after n>seconds. This requires to set up a state-table per connection attempt.
- Greetdelay: The sender is 'halted' for n seconds before sending the required 'Helo' greeting from the server. This feature discourages any illegitimate sender since it sucks up resources to send the mail.
Both methods work equally well; but both have their pros and cons. Using rblsmtpd Greetdelay is supported and works incredible well; without the need to maintain a state table for SMTP connections.
7.5.1 Relay-Black-Lists (RBL) (rblsmtpd)
rblsmtpd is typically invoked before qmail-smtpd and one or several Relay-Blacklists (RBL) or even Anti-Relay-Blacklists can be looked up. Please read rblsmtpd for more details how to set up.
7.5.2 X-RBL-Info Header (rblsmtpd)
Instead of rejecting emails on behalf of a bad RBL repudiation, it is possible to include received information in the received email's header for further filtering. Now, rblsmtpd has to be setup in interrogation mode by means of the option -i. The provided environment variable RBLSMTPD is now in turn filled with the evaluated RBL lookup information. qmail-smtpd will include this now in the email's header:
This information can be used by a MUA/LDA to filter the mail.
Note: Currently only ucspi-tcp6 supports this with its rblsmtpd program invoked in interrogation mode.
7.5.3 Greetdelay (rblsmtpd)
Greetdelay is the preferred method to reduce Malware, spam, and email forgery. Over the last decade, it has not dropped in efficiency. Unlike other means, it tackles the source of the those unwanted email: the bot-nets and infected PCs (or today: even IoT devices).
The figure below originates from 2007 and shows a substantial reduction of ill-legitimated emails and also infected mails:
The Greetdelay option is now part of rblsmtpd and is typically invoked thru tcpserver's or sslserver's cdb per host. Typically, one would use:
7.6 Greylisting in qmail-smtpd
In s/qmail 4.1 the module qmail-postgrey available and included as opt-in for qmail-smtpd. Thus, we need to do the following:
- Setting up a Greylisting daemon.
- Calling qmail-postgrey and instructing it to communicate with the daemon.
7.6.1 Setting up the Postgrey daemon
qmail-postgrey is compatible with David Schweikert's Postgrey daemon, which is commonly used for Postfix as well, using its policy server.
Postgrey depends on PERL and the BerkeleyDB, but there exist preconfigured packages to be easy installable on different Unix OS.
Next we have to customize Postgrey. Here, I use the standard Daemontools run script to fire up the service:
Of course, Postgrey uses Postfix' conventions, but as seen above, can be easily adjusted to the s/qmail environment.
It should be noted, that particular Whitelist Clients and Whitelist Recipients can be specified, but using sslserver's CDB the need is pretty much close to zero.
The implementation of the Postgrey daemon includes housekeeping procedures and doesn't need additional efforts. In practice, the service runs reliably, given my small environment.
7.6.2 s/qmail's qmail-postgrey
The qmail-postgrey client included in s/qmail follows the (not well defined) Postgrey API and talks natively to the Postgrey server.
There are two things, which need to be considered:
- qmail-postgrey needs to be called.
- qmail-postgrey needs to be customized to contact the Postgrey server.
This is actually done in one step using the environment variable POSTGREY sslserver's CDB providing a connection IP address and the port (separated by a semi-colon!), the servers listens to:
Here, we call qmail-postgrey for any unspecified connections from the CDB. Alternatively, you can define POSTGREY als exported variable in your run script. In order to avoid qmail-postgrey to become called, specify on individual connections POSTGREY="-". You can of course alternatively use an IPv6 address (even ::1, or fe80::1%eth0;59999) to setup the service and some other arbitrary port.
Note: Postgrey is in-effective for authenticated connections like Submission or any other authenticated SMTP connections.
7.7 Preventing email forgery
Email forgery, thus using forged or special crafted SMTP Return-Path (and of course email header) addresses is quite common. Therefore, mechanisms like RMX, SPF, DKIM, DMARC have been invented which work more or less well; however since those mechanisms are not mandatory for SMTP traffic (neither generating nor evaluating the required) information, those can be considered as add-on.
Two mechanisms are used in the wild:
- Sender Policy Framework (SPF): A DNS based sending-MTA based scheme. This is fully supported by qmail-smtpd.
- Domain Key Identified Mails (DKIM): A cryptographic signature added to every email and provides none-repudiation for every email send from a domain. qmail-smtpd supports this with some patches.
7.7.1 SPF query
Details about the SPF query and setup are given here.
7.7.2 'Mail From: Address Verification' (MAV)
The abuse or SMTP Return-Path addresses within s/qmail's administrative domain can be omitted using the 'Mail From: Address Verification' (MAV) mechanism which works for email received by qmail-smtpd from a MUA belonging to you administrative domain, considered to be RELAYCLIENTS:
Upon reception of RELAYCLIENT email, a href="./man/qmail-smtpd.html">qmail-smtpd can be instructed to do the following:
- In case, relaying is based on IP or DNS information only, emails can be rejected, if the domain part of the provided SMTP envelope 'Mail From:' address is outside the implicit or explicit define name space.
- In case, an authenticated user is provided, the user is forced to always use allowed 'Mail From:' envelope addresses upon sending.
Thus, MAV binds the IP/FQDN of the MUA or the provided user information to a valid SMTP Mail From: envelope address. In order to invoke MAV for qmail-smtpd, the environment variable LOCALMFCHECK needs to be defined. The following cases can be considered:
- LOCALMFCHECK='!': The control file mailfromrules.cdb is evaluated and the MAV is facilitated employing the environment variables TCP(6)REMOTEINFO, TCP(6)REMOTIP, or TCP(6)REMOTEHOST as key for the comparison.
- LOCALMFCHECK='=': TCP(6)REMOTEINFO (i.e. set by Auth) has to match the 'Mail From:' envelope address (case insensitive).
- LOCALMFCHECK='?': The email address embedded in the DN of a X.509 client certificate is used and compared against the 'Mail From:' envelope address.
- LOCALMFCHCEK='example.com': The domain part of the 'Mail From:' envelope address is compared against that given value.
In order to set-up specific bindings, the file mailfromrules needs to be populated. It follows roughly the conventions of the tcpserver' cdb:
The file mailfromrules needs to converted into a binary format prior of usage. This can be accomplished with qmail-mfrules. Changes can be realized while qmail-smtpd is running and are in effect on-the-fly.
If the MAV match fails, the SMTP client receives the generic message
is issued and email sending is prohibited. The environment variable REPLYMAV can be used to include additional custom information (instead of the dots).
7.7.3 DNS qualification of HELO and Return-Path in SMTP Envelope
The HELO/EHLO greeting of the sending's MTA as well as the domain part of the provided 'Return-Path' (aka 'Mail From:' address) to include a resolvable FQDN. qmail-smtpd is able to perform a DNS lookup on both SMTP envelope informations (see 3.5 qmail-smtpd).
Together, with the SPF settings, the following environment variables assure a particular DNS qualification, if provided in the rules.smtpd.tcp file and converted to a cdb:
The :deny rule in rules.smtpd.tcp requires, that tcpserver or sslserver is invoked with the options '-Rp' in order to do DNS lookup for the connection IP address in the the DNS branch ip6.arpa or in-addr.arpa and it validation (paranoid setting) against the forwarding branch.
7.8 Interrogating SMTP envelope and connection variables
For special purposes, it might be necessary to have knowledge of the SMTP envelope information while qmail-smtpd is running and it puts the following informations into the environment - as soon as available:
- HELOHOST - The SMTP client's HELO/EHLO greeting
- MAILFROM - The provided SMTP 'Mail From:' address
- RCPTTO - The received SMTP 'Rcpt To:' addresses concatenated by blanks
- AUTHPROTOCOL - The Authentication mechanism used
- AUTHUSER - The Authentication username provided
- SPFRESULT - The retrieved SPF return values (if any).
- RBLSMTPD - The RBL information (in case rblsmtpd runs in interrogation mode).
The provided qmail-queue.scan script makes use of these variables. You may also populate the DELIVERTO environment variable -- read by qmail-smtpd -- to include additional recipients.
In case of the SSL/TLS session further environment variables a la mod_ssl are available.
7.9 Qmail QUEUE_EXTRA
Bruce Guenter's Qmail QUEUE_EXTRA patch has almost the rank of a recommended patch, because its used by many Qmail extensions like the Qmail-Scanner and qmail-qfilter.
The actual use is controlled via the content of environment variable "QMAILQUEUE", which usually set in tcpserver or sslserver's cdb; ie. rules.smtpd.tcp or globally defined in the qmail-smtpd's run script. A typical use is:
which advices qmail-smtpd to use the executable qmail-qfilter as first stage queueing program instead of qmail-queue itself.
In order to reject during the SMTP DATA phase, vanilla qmail
requires that the qmail-queue replacement returns RC=31.
However, s/qmail enhances this mechanism with the following
additional return codes:
- RC = 32: Virus in message
- RC = 33: Spam message
- RC = 34: Policy rejected message
Those return codes can be extensibly used in a qmail-queue wrapper-script (see below).
Note: The QUEUE_EXTRA patch is not applied against qmail-smtpd but rather against the module qmail.c itself, since it is just an extension to the general queue call-mechanism.
7.9.1 qmail-queue.scan Replacement
The qmail-queue.scan script can be used by the QUEUE_EXTRA mechanism to allow a per (recipient) domain
- virus scanning (ie by ClamAV)
- spam scanning (ie. SpamAssassin).
For high volume/high performance scanning, the incoming message is copied to a tmp directory which typically should be raised on a ramdisk. All scanning actions can be realized now in memory which significantly reduces disk I/0.
You can define individual SpamAssassin detection thresholds per domain using the additional control file:
- control/spamdomains
Here, you include the recipients's domains, followed by a colon, and the spam threshold for this domain:
qmail-smtpd is able to understand the (tagged) messages identified as infected or as spam and will issue a useful SMTP return code.