This is an old revision of the document!
Mail received from the Internet flows through the system as described below.
An email message is received from a remote SMTP client by the mail transport agent Postfix.
Postfix feeds the message to the software program OpenDKIM in real time, i.e., while the SMTP transaction is in progress. OpenDKIM checks for DKIM records in DNS and also checks for any DKIM digital signature in the message, and adds headers to the message containing the result of these checks.
Postfix then feeds the same message to Rspamd in real time, i.e., while the same SMTP transaction is in progress.
Rspamd does a large number of spam checks, including checking the headers added by OpenDKIM, and checking for DMARC and SPF records in DNS.
Rspamd feeds the same message to Clamd, which checks for viruses and returns a result to Rspamd.
Rspamd then returns its final findings to Postfix, which may ask Postfix to:
Postfix acts on these findings. It will accept the message from the remote SMTP client, or it will send a permanent rejection reply to the remote SMTP client, or it will do greylisting by sending a temporary rejection to the remote SMTP client (which means try again later).1)
If Postfix accepts the message, it expands aliases and domain names until it determines the final recipient, which in Classic Linux is always a Linux user. Let's call that user the first user, also called USER.
Postfix checks to see if the first user USER has a .forward file in their home directory. If the message was addressed using plus addressing, then Postfix will also first look for a .forward file whose name is of the form .forward-extension or .forward+extension where -extension or +extension is the extension part of the recipient address. If the message was addressed to USERfirstname.lastname@example.org, Postfix will first look for a file called .forward-abc and then for a file called .forward. If the message was addressed to USERemail@example.com, Postfix will first look for a file called .forward+xyz and then for a file called .forward.
Postfix will follow instructions in first such file that was found,if any. So the message might be forwarded to some other address, or fed to a program, or some combination of these.
If no .forward (or .forward-extension or .forward+extension) file was found, Postfix now runs the Procmail program, and feeds it the message.
At this point Postfix's role for this message is over, and Procmail has taken over.
Procmail now feeds the message to SpamAssassin, which checks the message for spam and returns a status back to Procmail. Procmail also consults the first user's preferences as to whether or not spam as determined by SpamAssassin should go into the first user's normal inbox or into a spam folder, and whether spam above a certain level should be discarded, and follows these preferences.
Taking into account these preferences, Procmail now does the final mail delivery. If the first user has a .procmailrc file, then instructions in it will be followed. Otherwise Procmail simply delivers the message into the first user's Maildir directory in maildir format, either into the user's inbox, or into the spam folder.
Because spam-checking is done in sequence by Rspamd and SpamAssassin, you will often find two sets of headers in a message, some added by Rspamd and some by SpamAssassin. Rspamd adds headers only if it finds at least a little spam. SpamAssasin always adds headers, but makes them verbose only if it finds some spam, otherwise the SpamAssasin headers for not-spam are quite brief.
If the first user has a .forward file that sends mail elsewhere, Procmail is not run, and therefore SpamAssassin is not run.
If the first user's .forward file causes mail to go to a second user, then Postfix goes back to the step check for .forward file above, and looks for the second user's .forward file, if any. If the second user doesn't have a .forward file, then Procmail will run for the second user and Procmail will call SpamAssassin for the user.
If the first user's .forward file causes mail to go off-site (i.e., mail is forwarded to some other place like Gmail, Yahoo, etc.), then SpamAssassin will never run for the first user. However, Rspamd already ran, so anything recognized as spam with high certainty has already been rejected. But likely spam, not recognized as spam with high certainty, will be forwarded.
The threshold for rejecting spam based on Rspamd's findings is kept somewhat high, so that we avoid false positives that would cause legitimate mail to be rejected and thus never reach the recipient. So although Rspamd effectively detects spam, it still allows quite a bit of spam to go through. When SpamAssassin runs, no mail is rejected outright, but merely put into a spam folder. This way we may misfile some legitimate mail as spam but it will not be lost.
Because of Rspamd's high threshold for rejecting spam, and because SpamAssassin does not run when a .forward file is used, mail forwarded with a .forward file will contain some spam. You can make the amount of spam much lower by forwarding mail with a Procmail script and not with a .forward file.