Postfix hacks
From Cheatsheet
Contents |
commands
mailq
- shows all the mail sitting on your server, you delete one using one of the scripts at the bottom of this page
postsuper -d ALL
- removes all mail in the queue
postsuper -d ALL deferred
- removes all mail in the deferred queue
postqueue -f
- attempt to deliver all the mail in the queue
postcat -q C95D57032E
- see details of that e-mail
Here's an IP blocker, that will measure for spam attacks from the same IP in a short time, and block them before they ever get to Postfix, so Postfix doesn't have to think about it very hard.
/sbin/iptables -I INPUT -p tcp --dport 25 -i eth0 -m state --state NEW -m recent \ --set /sbin/iptables -I INPUT -p tcp --dport 25 -i eth0 -m state --state NEW -m recent \ --update --seconds 60 --hitcount 25 -j DROP
that's a modified version of the script that lives here: http://www.debian-administration.org/articles/187 I'm going to watch it and see what happens if you want to see how many failed attempts there are to login, run this:
grep "FAILED" /var/log/maillog | sed "s/.*for\( invalid user\)*\(.*\)\(from.*\)/\2/" | sort | uniq -c | wc -l
if you want to remove your Iptables rules, do this:
/sbin/iptables -F /sbin/iptables -X
It looks like that did very little, for some reason
sending mail out some single interface
Luigi Rosa wrote: > Given a Linux server with three network cards: > > eth0: 192.168.1.1 (local LAN) > eth1: 20.20.20.20 (default GW, hi speed Internet, dynamic address) > eth2: 30.30.30.30 (Internet, reserved to e-mail, static address) > > This server is the default gateway of the organization and NATs the > local addresses via 20.20.20.20. Al traffic must go through 20.20.20.20 > EXECPT e-mail that should go through 30.30.30.30. > > Binding Postfix (via inet_interfaces directive) to 192.168.1.1 and > 30.30.30.30 (and localhost) will be enough to tell Postfix to deliver > mail via 30.30.30.30 and NOT via the system default gateway 20.20.20.20? > >
You will need smtp_bind_address in main.cf for that purpose. Depending on your configuration need, you could create extra service in master.cf as well, example:
smtp-external unix - - y - - smtp
-o smtp_bind_address=30.30.30.30
and then in main.cf:
default_transport=smtp-external
Don't forget about relay service definition either, as it's smtp as
well, and uses global smtp_bind_address, unless explicitely overridden
in master.cf
binding postfix will set the IP in the packets, but it won't change the network routes (by default, routing is done by destination). so you also need to play with "advanced" routing to make sure the packets go out of eth2. this is linux question.
http://lartc.org/howto/index.html http://linux-ip.net/html/ http://www.policyrouting.org/PolicyRoutingBook/ONLINE/TOC.html
smtp settings
good starting point, according to mouss
smtpd_recipient_restrictions =
permit_mynetworks
reject_unauth_destination
reject_non_fqdn_sender
reject_non_fqdn_recipient
reject_invalid_helo_hostname
reject_unlisted_recipient
reject_unlisted_sender
#reject_non_fqdn_helo_hostname
reject_rbl_client zen.spamhaus.org
delete mail
from user@example.com
mailq | tail +2 | grep -v ’^ *(’ | awk ´BEGIN { RS = "" }
# $7=sender, $8=recipient1, $9=recipient2
{ if ($8 == "user@example.com" && $9 == "")
print $1 }
´ | tr -d ’*!’ | postsuper -d -
delete mail with specific text in it somewhere
example ./postfix-delete fromsomebaddomain.com
vi postfix-delete.pl
#!/usr/bin/perl
$REGEXP = shift || die "no email-adress given (regexp-style, e.g. bl.*\@yahoo.com)!";
@data = qx</usr/sbin/postqueue -p>;
for (@data) {
if (/^(\w+)(\*|\!)?\s/) {
$queue_id = $1;
}
if($queue_id) {
if (/$REGEXP/i) {
$Q{$queue_id} = 1;
$queue_id = "";
}
}
}
#open(POSTSUPER,"|cat") || die "couldn't open postsuper" ;
open(POSTSUPER,"|postsuper -d -") || die "couldn't open postsuper" ;
foreach (keys %Q) {
print POSTSUPER "$_\n";
};
close(POSTSUPER);
iptables
$IPTABLES -N SMTP-BLOCK $IPTABLES -A SMTP-BLOCK -m limit --limit 1/m --limit-burst 3 -j LOG - --log-level notice --log-prefix "iptables SMTP-BLOCK " $IPTABLES -A SMTP-BLOCK -m recent --name SMTPBLOCK --set -j DROP $IPTABLES -A INPUT -p tcp --dport 25 -m state --state NEW -m recent - --name SMTPBLOCK --rcheck --seconds 360 -j SMTP-BLOCK $IPTABLES -A INPUT -p tcp --dport 25 -m state --state NEW -m recent - --name SMTP --set $IPTABLES -A INPUT -p tcp --dport 25 -m state --state NEW -m recent - --name SMTP --rcheck --seconds 60 --hitcount 15 -j SMTP-BLOCK $IPTABLES -A INPUT -p tcp --dport 25 -m state --state NEW -j ACCEPT
It creates some trap for hosts which open too many connections in a short timeframe. Be aware of the limitations :
- The recent module can only handle a limited number of entries to compare so if you have high traffic this list may be overflow/cycled before the offender get caught.
- You must adjust the connection/time to match your needs.
- For larger sites you maybe have to adjust the size of the blocklist.
from me to me
you know what domains are yours so you can simply use an access list:
check_sender_access hash:/etc/postfix/mydomain
== mydomain example.com REJECT you cannot send on behalf of example.com .example.com REJECT you cannot send on behalf of example.com
please do not advocate SPF on this list. check the archives and you'll see that it is taboo here.
