Main       Comic       Forums       Anime       Tools       Fun       
Categories
Recent Articles
Recent Posts
Buy DSG Items
Do you know what S.H.Y.S.
stands for? Visit the comic
to decipher the clues.
Recent Posts       Popular Articles       Popular Threads       [ View All Recent Posts ]
1. New Server:  Rules Discussion by DranoK -- 3H 13M ago.
2. Unknown by noggin -- 3H 25M ago.
3. New Server:  Rules Discussion by <LCC> -- 8H 16M ago.
4. DeadGod Survival Game - Cycle 11 by DSG -- 11H 40M ago.
 
[ Login | Register ]
 
Viewing 'Temporarily force a server to queue outgoing mail'
May
16
Wednesday, May 16th, 2007 (16196 Views)
Intermediate
DranoK
Email is often used as a tool for servers to send reports, notifications and customer correspondence. It can be difficult to troubleshoot the content of messages, however, without resorting to lots of messy code changes or setting up a network of test mailboxes.

This tutorial will show you how to temporarily stop all mail from being sent on a single server so you can inspect the individual mail messages and delete them before they're delivered to an actual person. Any legit mail will not be lost and will be sent once your debugging is complete.

Prerequisites:
o Familiarity with the bash shell
o Familiarity with firewall concepts
o Familiarity with the SMTP protocol
o Basic familiarity with the iptables command

Most web and app servers run a local MTA (Mail Transfer Agent) for system crons and users to send mail with. Frequently this MTA is bound to the localhost interface (127.0.0.1) so external hosts can't access it.

Most applications use their host's local MTA instead of directly opening an outgoing SMTP connection to some random host on port 25. Apps that don't directly use the local MTA are usually configured to use localhost (127.0.0.1) as their mail server so messages aren't lost if there is a network failure.

All mainstream MTAs store mail messages in a queue if they are not able to be immediately sent (if they are disconnected from the network, for example, or if the relay they are trying to send mail to is down). While a mail message is queued it is stored on the file system in plain text.

We have two requirements while trying to debug our app's outgoing mail:

1) We don't want our test messages to reach actual recipients who may be confused by the mail.
2) We want real mail that wasn't part of our test to be delivered normally when we are finished.

Yes, we could mess with the MTA's configuration to try to do this. We could modify the app sending the messages to store them to a file instead.

A much simpler method, however, is to use iptables instead.

Since we want all outgoing messages to be queued we need to prevent the MTA from reaching any external host over port 25 (SMTP). However, since our app may be trying to send mail to localhost (127.0.0.1), we must ensure that port 25 on localhost remains open. To do this we need two iptable rules:

Listing 1:
iptables -A OUTPUT -p tcp -d 127.0.0.1 --dport 25 -j ACCEPT
iptables -A OUTPUT -p tcp  --dport 25 -j REJECT

Most iptables rules are put on the INPUT chain--that is, they manage incoming traffic. In this case we use "-A OUTPUT" because we want to manage outgoing traffic.

The first rule says to ACCEPT all tcp traffic going to localhost (127.0.0.1) on port 25 (SMTP).

The second rule says to REJECT all tcp traffic going to any destination on port 25.

Since the rule to accept localhost traffic is above the rule to deny all outgoing port 25 traffic we are still able to connect to port 25 of localhost. Also note that it is important to use REJECT instead of DROP, since REJECT will cause the MTA's outgoing connection to fail immediatly, while DROP would cause it to hang until it times out.

Running "iptables -L" should now report something similar to the following:

Listing 2:
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             localhost.localdomaintcp dpt:smtp
REJECT     tcp  --  anywhere             anywhere           tcp dpt:smtp reject-with
icmp-port-unreachable

Now all mail being sent will be queued. Your MTA's log file will most likely say the mail has been deferred due to a connection timeout.

Where these messages are stored is entirely dependent on your MTA software and how it was configured. In the case of sendmail, they will likely be in /var/spool/mqueue. Sendmail separates the envelope header from the body. The reasons for this are outside the scope of this article, however it is sufficient to explain that you may need to look at two separate files in order to see an entire email.

Different MTAs use different naming schemes and IDs for these files, however it is generally fairly simple to figure out what each of these files is. Once you find where your MTA stores it's queued messages it shouldn't be difficult to find the debug info you were looking for regardless of how much or little you know about the SMTP protocol and your specific MTA.

Once you have what you need you should delete any files that you don't want sent. Naming schemes vary, but in the case of sendmail all queue files are a string of letters followed by the message ID. It's generally safe to just replace the first 3-5 characters of a file you want to delete in the queue directory with * so you delete all files associated with that message.

For example, if you need to delete a file named "dfj2BIK8802525", use "rm *K8802525" to make sure you delete all associated envelope files. If no legit mail was sent during this time you can safely remove all files in the spool directly.

Remove the iptables rules with "iptables -F" to clear the entire chain. Note that this will remove ALL iptables rules, not just the two you added above. If your had custom iptables rules setup you should either restore them after running "iptables -F" or selectively remove the two rules we added in this tutorial.

The queued mail will now be sent the next time the MTA processes its queue, generally within an hour. Most MTAs have the ability to force processing its queue--using sendmail, for example, you can issue "/usr/sbin/sendmail -q" to force processing of the queue.

See Also:
o IPTables
  http://en.wikipedia.org/wiki/Iptables
o The SMTP Protocol
  http://en.wikipedia.org/wiki/Smtp
o Sendmail
  http://en.wikipedia.org/wiki/Sendmail
o Postfix
  http://en.wikipedia.org/wiki/Postfix_%28software%29


Permalink - Forum Thread - Reply to this - Subscribe!Social Bookmark Button



0 Comments -- Post a Comment



Post a Comment
Name (Required)
Register an account to gain access to all the great features of DeadGod.Net! It's fast, and free. Register now!

You may use BBCode in your post.


Older Articles
 
 
DeadGod.Net - Cute Evil Atheists
Encouraging critical thought and general enjoyment since 2001.
Want to join our community? Have suggestions or comments?
Contact Us or Visit our forums.