Difference between revisions of "Procmail/Mail ping"

From braindump
Jump to navigation Jump to search
(Created page with "{{DISPLAYTITLE:Create a mail ping with procmail}} There was a time when as my job included checking if outbound mail was working as part of a morning check routine. After doi...")
 
Line 9: Line 9:


== Howto ==
== Howto ==
For this example we assume mail is sent from an address of *@foobar.office to ping@foobar.outside. In order to prevent the whole world from using your server as ping host the recipe should sport a From filter.
For this example we assume mail is sent from an address of <tt>*@foobar.office</tt> to <tt>ping@foobar.outside</tt>. In order to prevent the whole world from using your server as ping host the recipe should sport a <tt>From</tt> filter.


=== Recipe ===
=== Recipe ===


PONG_FORMAT="
<span class="highlight">PONG_FORMAT=</span>"
-------------------------------------------------------------------
-------------------------------------------------------------------
pong %s
pong %s
Line 39: Line 39:
{
{
RECEIVED=`formail -X 'Received'`
<span class="highlight">RECEIVED=</span>`formail -X 'Received'`
PONG_TIME=`date "+%H%M %F %T %z (%Z) %s.%N"`
<span class="highlight">PONG_TIME=</span>`date "+%H%M %F %T %z (%Z) %s.%N"`
:0:
:0:
* ^From:.*@foobar.office
* ^<span class="highlight">From:</span>.*@foobar.office
| (formail -r; printf "$PONG_FORMAT" $PONG_TIME "$RECEIVED";) | \
| (<span class="highlight">formail -r</span>; <span class="highlight">printf</span> "$PONG_FORMAT" $PONG_TIME "$RECEIVED";) | \
$SENDMAIL -oi -t -f 'ping@foobar.outside'
<span class="highlight">$SENDMAIL</span> -oi -t -f 'ping@foobar.outside'
# Send to the bit bucket if no match
:0:
:0:
/dev/null
/dev/null
Line 52: Line 53:
=== Explanation ===
=== Explanation ===
==== Variables ====
==== Variables ====
;PONG_FORMAT: Holds the message to in a format usable by the printf unix command. When modifiying this message the printf command must be modified to reflect the changes.
;PONG_FORMAT: Holds the message to in a format usable by the <tt>printf</tt> unix command. When modifiying this message the <tt>printf</tt> arguments must be modified to reflect the number of placeholders.
;RECEIVED: Holds the header of the incoming mail. This is great to find out how many hops the mail took and how long it took at each hop.
;RECEIVED: Holds the header of the incoming mail. This is great to find out how many hops the mail took and how long it took at each hop.
;PONG_TIME: Hold the time when the mail was first processed by the procmail rule. The receiving server should be in the same time zone as the sender. If they differ the command can be prefixed with TZ=<zone> date ...
;PONG_TIME: Hold the time when the mail was first processed by the <tt>procmail</tt> rule. The receiving server should be in the same time zone as the sender. If they differ the command can be prefixed with <tt>TZ=<zone> date ...</tt>.
;SENDMAIL: Automatically assigned by <tt>procmail</tt>. Holds the full path to the <tt>sendmail</tt> binary.
;HOME: Is the home directory of the users the running the procmail rule. This is the same as when opening a shell on the server.
;SENDMAIL: Automatically assigned by procmail. Holds the full path to the sendmail binary.


==== Commands ====
==== Commands ====
;formail -r: Generate an auto-reply header. Will throw away all the existing headers. Hence the formail -X command further up in the script!
;formail -r: Generate an auto-reply header. Will throw away all the existing headers. Hence the <tt>formail -X</tt> command further up in the script!
;printf: Print the new message body based on the PONG_FORMAT template.
;printf: Print the new message body based on the <tt>PONG_FORMAT</tt> template.
;sendmail: Send the message straight back to the sender.
;sendmail: Send the message straight back to the sender.
The command <tt>formail -r</tt> and <tt>printf</tt> are executed in a subshell so the messages is properly concatenated sent to <tt>sendmail</tt>.




=== Sample reply ===
=== Sample reply ===
Variable content in green.
-------------------------------------------------------------------
-------------------------------------------------------------------
pong 2149
pong <span class="input">2149</span>
-------------------------------------------------------------------
-------------------------------------------------------------------
full pong 2013-12-14 21:49:52 +0100 (CET)
full pong <span class="input">2013-12-14 21:49:52 +0100 (CET)</span>
-------------------------------------------------------------------
-------------------------------------------------------------------
epoch-nano pong 1387054192.776386000
epoch-nano pong <span class="input">1387054192.776386000</span>
-------------------------------------------------------------------
-------------------------------------------------------------------
Line 76: Line 78:
Original Received Headers:
Original Received Headers:
-------------------------------------------------------------------
-------------------------------------------------------------------
Received: from mxout.foobar.office (mxout.foobar.office [IPv6:XXXX::XXXX])
<span class="input">Received: from mxout.foobar.office (mxout.foobar.office [IPv6:XXXX::XXXX])
by mail.foobar.outside (Postfix) with ESMTPS id EA6F7C8D901B
by mail.foobar.outside (Postfix) with ESMTPS id EA6F7C8D901B
for <ping@foobar.outside>; Sat, 14 Dec 2013 21:49:49 +0100 (CET)
for <ping@foobar.outside>; Sat, 14 Dec 2013 21:49:49 +0100 (CET)
Line 89: Line 91:
(envelope-from <morning-check@foobar.office>)
(envelope-from <morning-check@foobar.office>)
id 1Vrw9k-00080q-N2
id 1Vrw9k-00080q-N2
for ping@foobar.outside; Sat, 14 Dec 2013 21:49:48 +0100
for ping@foobar.outside; Sat, 14 Dec 2013 21:49:48 +0100</span>
-------------------------------------------------------------------
-------------------------------------------------------------------
Notice: This is an automated messages and will only work from the
Notice: This is an automated messages and will only work from the

Revision as of 21:45, 14 December 2013


There was a time when as my job included checking if outbound mail was working as part of a morning check routine. After doing it a few times sending mail to an external address and then sending it back again. After a few times doing it I used my gray cells and came up with this procmail recipe cutting. With the time I saved I could now take a longer coffee break :).

Prerequisites

  • procmail
  • formail
  • MTA (postfix or sendmail to name but 2)

Howto

For this example we assume mail is sent from an address of *@foobar.office to ping@foobar.outside. In order to prevent the whole world from using your server as ping host the recipe should sport a From filter.

Recipe

PONG_FORMAT="
-------------------------------------------------------------------
pong %s
-------------------------------------------------------------------
full pong %s %s %s %s
-------------------------------------------------------------------
epoch-nano pong %s
-------------------------------------------------------------------

-------------------------------------------------------------------
Original Received Headers:
-------------------------------------------------------------------
%s
-------------------------------------------------------------------
Notice: This is an automated messages and will only work from the
foobar.office domain
-------------------------------------------------------------------
"

## ----------------------------------------------------------------------------
## morning check
## ----------------------------------------------------------------------------
:0:
* ^To:.*ping@foobar.outside
{

  RECEIVED=`formail -X 'Received'`
  PONG_TIME=`date "+%H%M %F %T %z (%Z) %s.%N"`
  :0:
  * ^From:.*@foobar.office
  | (formail -r; printf "$PONG_FORMAT" $PONG_TIME "$RECEIVED";) | \
    $SENDMAIL -oi -t -f 'ping@foobar.outside'

  # Send to the bit bucket if no match
  :0:
  /dev/null
}

Explanation

Variables

PONG_FORMAT
Holds the message to in a format usable by the printf unix command. When modifiying this message the printf arguments must be modified to reflect the number of placeholders.
RECEIVED
Holds the header of the incoming mail. This is great to find out how many hops the mail took and how long it took at each hop.
PONG_TIME
Hold the time when the mail was first processed by the procmail rule. The receiving server should be in the same time zone as the sender. If they differ the command can be prefixed with TZ=<zone> date ....
SENDMAIL
Automatically assigned by procmail. Holds the full path to the sendmail binary.

Commands

formail -r
Generate an auto-reply header. Will throw away all the existing headers. Hence the formail -X command further up in the script!
printf
Print the new message body based on the PONG_FORMAT template.
sendmail
Send the message straight back to the sender.

The command formail -r and printf are executed in a subshell so the messages is properly concatenated sent to sendmail.


Sample reply

Variable content in green.

-------------------------------------------------------------------
pong 2149 
-------------------------------------------------------------------
full pong 2013-12-14 21:49:52 +0100 (CET)
-------------------------------------------------------------------
epoch-nano pong 1387054192.776386000
-------------------------------------------------------------------

-------------------------------------------------------------------
Original Received Headers:
-------------------------------------------------------------------
Received: from mxout.foobar.office (mxout.foobar.office [IPv6:XXXX::XXXX])
	by mail.foobar.outside (Postfix) with ESMTPS id EA6F7C8D901B
	for <ping@foobar.outside>; Sat, 14 Dec 2013 21:49:49 +0100 (CET)
Received: from [10.3.4.45] (helo=smtp.foobar.office)
	by mxout.foobar.office with esmtp (Exim 4.80.1 (FreeBSD))
	(envelope-from <morning-check@foobar.office>)
	id 1Vrw9k-000JOr-Q3
	for ping@foobar.outside; Sat, 14 Dec 2013 21:49:48 +0100
Received: from [xx.xx.xx.xx] (helo=mail.foobar.office)
	by smtp.foobar.office with esmtpsa (TLSv1:DHE-RSA-AES256-SHA:256)
	(Exim 4.80.1 (FreeBSD))
	(envelope-from <morning-check@foobar.office>)
	id 1Vrw9k-00080q-N2
	for ping@foobar.outside; Sat, 14 Dec 2013 21:49:48 +0100
-------------------------------------------------------------------
Notice: This is an automated messages and will only work from the
foobar.office domain
-------------------------------------------------------------------