最後更新: 2020-12-09
介紹
HomePage: http://www.procmail.org/
原理
[A] invoked automatically over the .forward (sendmail)
[B] invoked from within the mailer immediately (postfix - mailbox_command)
目錄
- Installation
-
Postfix Configure
[方式 1] By Postfix 's mailbox_command
[方式 2] By Postfix 's transport_maps - rcfile
- Rule Syntax
- Procmail Flags
- Sending to Dovecot
- Example
- Work with spamassassin
Installation
# Centos 6
yum install procmail
# Check Version
procmail -v
procmail v3.22 2001/09/10
Postfix Configure
[方式 1] By Postfix 's mailbox_command
[方式 2] By Postfix ' s transport_maps
[方式 1] By Postfix 's mailbox_command
vi /etc/postfix/main.cf
mailbox_command = /usr/bin/procmail
service postfix restart
[方式 2] By Postfix 's transport_maps
Postfix Setting
main.cf
procmail_destination_recipient_limit = 1 transport_maps = hash:/etc/postfix/cf/transport_maps_user, ...
master.cf
procmail unix - n n - - pipe flags=RO user=vmail argv=/usr/bin/procmail -t -m USER=${user} DOMAIN=${domain} EXTENSION=${extension} /etc/postfix/procmailrc/${recipient}
${extension} # postfix variable
This macro expands to the extension part of a recipient address.
For example, with an address user+foo@domain the extension is foo.
${mailbox} # postfix variable
This macro expands to the complete local part of a recipient address.
For example, with an address user+foo@domain the mailbox is user+foo.
${user}
user+foo@domain => user
Remark
A command-line argument that contains ${extension} / ${mailbox}
expands into as many command-line arguments as there are recipients.
This information is modified by the u flag for case folding.
h # postfix pipe flag
Fold the command-line $original_recipient and $recipient address domain part to lower case
u # postfix pipe flag
Fold the command-line $original_recipient and $recipient address localpart to lower case.
q # postfix pipe flag
Quote white space and other special characters in the command-line $sender,
$original_recipient and $recipient address localparts
The q flag affects only entire addresses, not the partial address information from the $user,
$extension or $mailbox command-line macros.
-a argument # procmail Opts
This will set $1 to be equal to argument.
Each succeeding -a argument will set the next number variable ($2, $3, etc).
-t # procmail Opts
Make procmail fail softly
i.e.
if procmail cannot deliver the mail to any of the destinations you gave,
the mail will not bounce, but will return to the mailqueue.
-m # procmail Opts
Turns procmail into a general purpose mail filter.
In this mode one rcfile must be specified on the command line.
transport_maps_user
U@D procmail
procmailrc.common
# comment ... ORGMAIL=${HOME}/$DOMAIN/$USER/ DEFAULT=${ORGMAIL} VERBOSE=off LOGFILE=${ORGMAIL}/procmail.log LOG="`date` " MAILDIR=${ORGMAIL}
U@D
INCLUDERC=/etc/postfix/procmailrc/procmailrc.common VERBOSE=off # deliver to folder test and stop :0 w: .test/
Postfix Log
由
... postfix/virtual[22163]: 654C33219C5: to=<U@D>, relay=virtual, delay=0.07, delays=0.01/0/0/0.06, dsn=2.0.0, status=sent (delivered to maildir)
變成
... postfix/pipe[23771]: 2AE9D3219EC: to=<U@D>, relay=procmail, delay=1104, delays=1103/0.02/0/0.02, dsn=2.0.0, status=sent (delivered via procmail service)
Help
man 5 procmailrc # procmail rcfile
man 5 procmailex # procmail rcfile examples
rcfile
Procmail Configuration
The Procmail configuration file contains important environmental variables.
These variables specify things such as which messages to sort and what to do with the messages that do not match any recipes.
<env-variable>=<value>
支援
- ${VAR:-value}
- ${VAR:+value}
Default rcfile: $HOME/.procmailrc # Environment variable
VERBOSE=on LOGFILE=$HOME/procmail.log LOG=" "
procmail.log
procmail: Match on "^From.*tim@mydomain.*" procmail: Assigning "LASTFOLDER=mydomain" procmail: Opening "mydomain" procmail: Acquiring kernel-lock procmail: Notified comsat: "tim@0:/home/tim/mydomain" From tim@mydomain Fri Apr 1 13:04:38 2016 Subject: test msg Folder: test_folder 2519
LOG
Assigning something to this variable writes out the assigned value to the LOGFILE.
Often, you want to include a final newline <- 用來間開每次的 log
LOG=" "
INCLUDERC
Specifies additional rc files containing more recipes for messages to be checked against.
INCLUDERC=$MAILDIR/spam.rc
DEFAULT
Sets the default mailbox where messages that do not match any recipes are placed.
If procmail can not deliver to the DEFAULT location,
the mail ends up in the location specified in the ORGMAIL variable
ORGMAIL
ORGMAIL=${HOME}/Maildir/
Thus, a better '/etc/procmailrc' that copes with this fact would be:
ORGMAIL=${HOME}/Maildir/ DEFAULT=${ORGMAIL}
MAILDIR
Sets the current working directory for Procmail
If set, all other Procmail paths are relative to this directory.
ie.
MAILDIR=$HOME/vmail/$DOMAIN/$USER/Maildir
Rule Syntax
Syntax
:0 [flags] [ : [locallockfile] ] * <zero or more conditions (one per line)> [special-action-character] <exactly one action line>
Basic Example
:0 * case-insensitive-egrep-regex-1 * case-insensitive-egrep-regex-2 folder_name :0 * another-case-insensitive-egrep-regex folder_name
說明
行1: A line starting with ':' marks the beginning of a recipe.
行2: Conditions start with a leading '*',
everything after that character is passed on to the internal egrep literally
行3: Conditions are ANDed; if there are no conditions the result will be true by default.
Locking
# No locking
:0 flags
# Let Procmail figure out lock file to use.
# use a locallockfile (for this recipe only)
# procmail will use the destination filename
:0 flags:
應用: 沒有加 flag
:0:
# Name a lock file to use.
:0 flags:lockfile
Log
rcfile
# deliver to folder test and stop :0: .test/
log
procmail: Assigning "MAILDIR=/home/vmail/MyDomain/MyUser/" procmail: Locking ".test/.lock" procmail: Assigning "LASTFOLDER=.test/new/1607486477.20033_1.mail.MyDomain" procmail: Unlocking ".test/.lock" Subject: test@1201 Folder: .test/new/1607486477.20033_1.mail.MyDomain 1062
special-action-character
- < — Checks if the message is under a specified number of bytes
- > — Checks if the message is over a specified number of bytes
- | — Starts a specified program to process the message
- ! — In the action line, this character tells Procmail to forward the message to the specified email addresses
- { and } — Constructs a nesting block, used to contain additional recipes to apply to matching messages
egrep regular expressions
- ! # In the condition line, this character inverts the condition.
- ^ # matches the beginning of the line
- $ # matches the end of the line
- . # Matches any single character
- (character)* # match arbitrarily many occurences of (character)
- (character)? # Match 0 or 1 instance of (character)
- [abcdef] # Match any character enclosed in []
- expression1| # expression2 Matches expression1 or expression 2.
Procmail Flags
* case-sensitive
D — Makes the egrep comparison case-sensitive
Default: case-insensitive
* 連 spamassassin 使用
H — Parses the header of the message and looks for matching conditions. This is the default behavior.
w — Tells Procmail to wait for the specified filter or program to finish,
and reports whether or not it was successful before considering the message filtered.
* Generate a carbon copy of this mail
Flag: c
* Ignore any write errors on this recipe
Flag: i
* Parses the body
Flag: B
* Wait
w
Wait for the program in the action line to finish before continuing.
Otherwise, Procmail will spawn off the program and leave it executing on its own.
W
Like w, but additionally suppresses any "program failure" messages from the action pipeline.
* # Clone message and execute the action(s) in a subprocess if the conditions match.
Flag: c
Sending to Dovecot
rcfile
DELIVER="/usr/lib/dovecot/deliver -d $LOGNAME" DEFAULT="$HOME/Maildir/" MAILDIR="$HOME/Maildir/"
-d <username>: Destination username.
If given, the user information is looked up from dovecot-auth.
i.e.
# deliver spam to spam folder :0 w * ^X-Spam-Status: Yes | $DELIVER -m Spam # deliver to INBOX and stop :0 w | $DELIVER
More Example
# 1: Drop Unwanted Sources
:0
* ^From: .*@domain.com
/dev/null
# 2: Forwarding Mail
:0 * ^Subject: .*something-or-other ! [email protected]
# 3: from a particular sender places it in a specified folder (Maildir)
a)
DEFAULT=$HOME/Maildir/
MAILDIR=$HOME/Maildir/
:0
* ^From: @MYDOMAIN
.MYDOMAIN/
b)
DEFAULT=$HOME/Maildir/
MAILDIR=$HOME/Maildir/
:0:
* ^X-Spam-Status: Yes
.Junk/
# 4: {...}
1. Have the word "AAA" in the subject
2. Have the word "BBB" in the text
3. Do not have the words "CCC" or "DDD" in the text
:0 * ^Subject:.*AAA.* # subject condition * !^X-Loop: [email protected] # prevent mail loops { :0 c B # c: make sure you still receive the mail, B: check body instead of header * BBB # body conditions * !CCC * !DDD | (formail -r -A"X-Loop: [email protected]" ; echo "This is my reply") | $SENDMAIL -t }
Work with spamassassin
~/.procmailrc
INCLUDERC=/etc/mail/spamassassin/spamassassin-default.rc # By spamc INCLUDERC=/etc/mail/spamassassin/spamassassin-spamc.rc # By spamd
將 spam mail 放到某 spam 資料夾
:0 Hw * ^X-Spam-Status: Yes spam