date: 2006-04-04 21:45:30+00:00

CentOS 3.6 + Postfix 2.2.9 + TLS + Virtual Users + MySQL backend + ...

categories: - Howto - Linux - Postfix - Red Hat/CentOS - SQL

This article will review my current configuration, this is an update to a previous article : CentOS + Postfix + virtual users + Squirrelmail + …

What I stopped using since the previous article : - vacation message because the script I was using had a few annoying bugs that I haven't figured out yet. - squirrelmail replaced by roundcube webmail (still beta !!), I don't have many webmail users so I can afford using roundcube, which still has a lot of bugs. If you want a rock solid webmail, go for squirrelmail.

The current config : - CentOS 3.6 - New : Postfix 2.2.9 + SSL/TLS (see : http://blog.wains.be/?p=77 & http://www.yocum.org/faqs/postfix-tls-sasl.html) - New : SPF support enabled but not in use (see : http://blog.wains.be/?p=76) - New : Postfix is now using proxy map (proxy_read_maps : see http://blog.wains.be/?p=78) - virtual users (MySQL 3 backend) - New : amavisd-new 2.2.1 + clamav 0.88 (see : http://blog.wains.be/?p=65) - Updated : SpamAssassin 3.1.1 (not using SA from amavisd-new) - courier-imap 3 (imap/imaps/pop3/pop3s) (SSL is new ! see : http://blog.wains.be/?p=70) - pop-before-smtp (See : http://blog.wains.be/?p=47) - still no quota - New : a script checking space used by mailboxes, generates a notification to users when they reach 100 Mb (I have plenty of space though, that's why I don't need to bother with quotas on my small domain) - New : a script generating a report of mailbox space - RBL stats generated by a script - Autosignature added using Altermime : http://www.pldaniels.com/altermime/ - Mime checks : the current config let some zip files get through the system, I still need to figure this issue out - New : not really part of Postfix but an LDAP directory for Thunderbird : http://blog.wains.be/?p=73

What should be done in the (near ?) future : - SMTP auth instead of pop-before-smtp for remote users - make autoreply/vacation/out-of-office work again ? - trying to figure out how to run postfix chrooted when MySQL is used along - ...

**/etc/postfix/main.cf : **

<code>myhostname = mx.domain.be
mydomain = domain.be
myorigin = $mydomain
mydestination = $mydomain, $transport_maps, $myhostname
mynetworks = 127.0.0.0/8, 192.168.250.0/24, 192.168.254.0/24, hash:/etc/postfix/pop-before-smtp

2bounce_notice_recipient = postmaster
bounce_notice_recipient = postmaster
bounce_service_name = bounce
double_bounce_sender = double-bounce
error_notice_recipient = postmaster

queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
mailbox_command = /usr/bin/procmail
inet_interfaces = 127.0.0.1, 192.168.250.3, 192.168.254.3, 192.168.254.4

sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix

mime_header_checks = regexp:/etc/postfix/mime_checks

content_filter = smtp-amavis:[127.0.0.1]:10024

smtpd_banner = mx.domain.be ESMTP
bounce_queue_lifetime = 1d
maximal_queue_lifetime = 1d
delay_warning_time = 30m

message_size_limit = 40971520
mailbox_size_limit = 1048576000
virtual_mailbox_limit = 1048576000
queue_minfree = 150000000

setgid_group = postdrop
mail_owner = postfix
notify_classes = resource,software,policy,delay

disable_vrfy_command = yes
smtpd_helo_required = yes
biff = no

smtpd_error_sleep_time = 10s
smtpd_hard_error_limit = 5
smtpd_soft_error_limit = 2

append_at_myorigin = yes
append_dot_mydomain = no

smtpd_client_restrictions =
        permit_mynetworks
        reject_rbl_client sbl-xbl.spamhaus.org
        reject_rbl_client list.dsbl.org

smtpd_recipient_restrictions =
        permit_mynetworks
        check_recipient_access hash:/etc/postfix/access
        reject_unauth_destination
#        check_policy_service unix:private/spfpolicy

smtpd_sender_restrictions =
        permit_mynetworks
        hash:/etc/postfix/access

proxy_read_maps = $virtual_alias_maps $virtual_mailbox_maps $transport_maps $virtual_uid_maps $virtual_gid_maps

virtual_mailbox_base = /var/spool/postfix/vmail
virtual_minimum_uid = 1000
virtual_mailbox_maps = proxy:mysql:/etc/postfix/vmailsql/vmailbox
virtual_alias_maps = proxy:mysql:/etc/postfix/vmailsql/valias
transport_maps = proxy:mysql:/etc/postfix/vmailsql/transport
virtual_uid_maps = proxy:mysql:/etc/postfix/vmailsql/vuid
virtual_gid_maps = proxy:mysql:/etc/postfix/vmailsql/vgid
local_recipient_maps = $virtual_mailbox_maps

smtpd_tls_auth_only = no
smtp_use_tls = no
smtpd_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key
smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt
smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
tls_daemon_random_source = dev:/dev/urandom

alias_database =
alias_maps =

readme_directory = /usr/share/doc/postfix-2.2.9-documentation/readme
sample_directory = /etc/postfix
html_directory = /usr/share/doc/postfix-2.2.9-documentation/html
manpage_directory = /usr/share/man</code>

/etc/postfix/master.cf :

<code># ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================

#spfpolicy      unix    -       n       n       -       -       spawn
#       user=nobody argv=/usr/bin/perl /etc/postfix/spf-policy.pl

#autoreply    unix  - n n - - pipe
#       flags=DRhu user=vacation argv=/var/spool/vacation/vacation.pl

spamassassin    unix    -       n       n       -       -       pipe
        user=nobody argv=/usr/bin/spamc -f -e /usr/sbin/sendmail.postfix -oi -f ${sender} ${recipient}

smtp-amavis     unix    -       -       n       -       2       smtp
        -o smtp_data_done_timeout=1200
        -o disable_dns_lookups=yes

autosignature   unix    -       n       n       -       -       pipe
        flags=Rq user=filter argv=/etc/postfix/signature/disclaimer -f ${sender} -- ${recipient}

127.0.0.1:10025 inet    n       -       n       -       -       smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o smtpd_helo_restrictions=
        -o smtpd_client_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks=127.0.0.0/8

127.0.0.1:smtp          inet    n       -       n       -       -       smtpd

192.168.250.3:smtp      inet    n       -       n       -       -       smtpd
        -o content_filter=spamassassin

192.168.254.3:smtp      inet    n       -       n       -       -       smtpd
        -o content_filter=autosignature

192.168.254.4:smtp      inet    n       -       n       -       -       smtpd

smtps                   inet    n       -       n       -       -       smtpd
        -o smtpd_tls_wrappermode=yes
        -o smtpd_sasl_auth_enable=no
        -o content_filter=autosignature

#submission     inet    n       -       n       -       -       smtpd
#  -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes
#628      inet  n       -       n       -       -       qmqpd
pickup  fifo    n       -       n       60      1       pickup
cleanup unix    n       -       n       -       0       cleanup
qmgr    fifo    n       -       n       300     1       qmgr
#qmgr     fifo  n       -       n       300     1       nqmgr
#tlsmgr   fifo  -       -       n       300     1       tlsmgr
rewrite unix    -       -       n       -       -       trivial-rewrite
bounce  unix    -       -       n       -       0       bounce
defer   unix    -       -       n       -       0       bounce
flush   unix    n       -       n       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
smtp    unix    -       -       n       -       -       smtp
relay   unix    -       -       n       -       -       smtp
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq   unix    n       -       n       -       -       showq
error   unix    -       -       n       -       -       error
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp    unix    -       -       n       -       -       lmtp
#
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# maildrop. See the Postfix MAILDROP_README file for details.
#
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
#
# The Cyrus deliver program has changed incompatibly, multiple times.
#
old-cyrus unix  -       n       n       -       -       pipe
  flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
# Cyrus 2.1.5 (Amos Gouaux)
cyrus     unix  -       n       n       -       -       pipe
  user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient
trace   unix    -       -       n       -       0       bounce
verify  unix    -       -       n       -       1       verify
anvil   unix    -       -       n       -       1       anvil
scache  unix    -       -       n       -       1       scache
discard unix    -       -       n       -       -       discard
tlsmgr  unix    -       -       n       1000?   1       tlsmgr</code>

Virtual users with MySQL : Unchanged. See http://blog.wains.be/?p=7

Users / domains management : Unchanged.. Still using vmail with personal addons. You should look into Postfix Admin http://high5.net/postfixadmin/ which seems to be a widely used tool.

It allows autoresponders, virtual users/domains, etc... and they have a good howto : http://postfixwiki.org/index.php?title=Virtual_Users_and_Domains_with_Courier-IMAP_and_MySQL

RBL stats (generated daily) :

<code>#!/bin/sh
# © 2005 - http://www.securityteam.us

DATE="$(date --date "1 day ago" +"%b %e")"

SPAMHAUS=`grep -i "blocked using sbl-xbl.spamhaus.org" /var/log/maillog | grep -c "${DATE}"`
SPAMCOP=`grep -i "spamcop.net" /var/log/maillog | grep -c "${DATE}"`
ORDB=`grep -i "ordb.org" /var/log/maillog | grep -c "${DATE}"`
DSBL=`grep -i "blocked using list.dsbl.org" /var/log/maillog | grep -c "${DATE}"`
RESIDENTIAL=`grep -i "Residential" /var/log/maillog | grep -c "${DATE}"`
NJABL=`grep -i "dnsbl.njabl.org" /var/log/maillog | grep -c "${DATE}"`
DYNABLOCK=`grep -i "dynablock.njabl.org" /var/log/maillog | grep -c "${DATE}"`
CHINA=`grep -i "china.rominet.net" /var/log/maillog | grep -c "${DATE}"`
BRAZIL=`grep -i "brazil.blackholes.us" /var/log/maillog | grep -c "${DATE}"`
KOREA=`grep -i "korea.rominet.net" /var/log/maillog | grep -c "${DATE}"`
TAIWAN=`grep -i "taiwan.rominet.net" /var/log/maillog | grep -c "${DATE}"`
HONGKONG=`grep -i "hong-kong.rominet.net" /var/log/maillog | grep -c "${DATE}"`
SORBS=`grep -i "sorbs.net" /var/log/maillog | grep -c "${DATE}"`
BLITZED=`grep -i "blitzed.org" /var/log/maillog | grep -c "${DATE}"`
MAILABUSE=`grep -i "mail-abuse.org" /var/log/maillog | grep -c "${DATE}"`
ABUSEAT=`grep -i "abuseat.org" /var/log/maillog | grep -c "${DATE}"`
CNKR=`grep -i "cn-kr.blackholes.us" /var/log/maillog | grep -c "${DATE}"`
TOTAL=`grep -i "554 Service unavailable" /var/log/maillog | grep -c "${DATE}"`

echo ""
echo "    :: RBL STATS for ${DATE} ::"
echo "------------------------------------"
echo "  LIST                        COUNT "
echo "------------------------------------"
echo "  sbl-xbl.spamhaus.org ...: ${SPAMHAUS}"
echo "  list.dsbl.org ..........: ${DSBL}"
echo "===================================="
echo "  TOTAL:                    ${TOTAL}"
echo ""</code>

Mailbox space usage script : It will send a notice to the owner (and a cc to the admin) of a box using at least 100 Mb

<code>#!/bin/sh
# © 2006, Sébastien Wains - http://blog.wains.be

MAILDIR=/var/spool/postfix/vmail
DOMAINS="domain.be"
MESSAGE=/root/bin/ADMIN/MAILDIR_CHECK.MESG
SUBJECT="ESPACE DISQUE BOITE MAIL > 100 MB"
ADMIN=admin@domain.be

for DOMAIN in $DOMAINS
do

for OVERQUOTAACCOUNT in `du -h --max-depth=2 $MAILDIR/$DOMAINS | egrep './[a-z]{1}/' | egrep '^[0-9]{3,}M' | awk '{print $2}' | cu
t -d "/" -f 8`

do
cat $MESSAGE | mail $OVERQUOTAACCOUNT@$DOMAIN -s "$SUBJECT" -c $ADMIN
done

done</code>

**Mailbox storage reporting script (generated daily) : **

<code>#!/bin/sh
# © 2006, Sébastien Wains - http://blog.wains.be

DOMAINS="domain1.be domain2.be"
TIMESTAMP=`date +%d/%m/%Y`

echo "REPORT DATE : $TIMESTAMP"
echo " "
for domains in $DOMAINS

do
echo "---------------------------"
echo "$domains"
echo "===================================================="
echo "Size               Accounts"
echo "---------------------------"
echo " "
du -h /var/spool/postfix/vmail/$domains/ --max-depth=2 -c | 
        egrep "/var/spool/postfix/vmail/$domains/[a-z]/" | 
        sed -re "s//var/spool/postfix/vmail/$domains/[a-z]///g" | 
        egrep "[0-9]{4}M" | 
        awk '{print $1, "               ",$2}' | 
        sort -r

du -h /var/spool/postfix/vmail/$domains/ --max-depth=2 -c | 
        egrep "/var/spool/postfix/vmail/$domains/[a-z]/" | 
        sed -re "s//var/spool/postfix/vmail/$domains/[a-z]///g" | 
        egrep -v "[0-9]{4}" | 
        egrep "[0-9]{3}M" | 
        awk '{print $1, "               ",$2}' | 
        sort -r

du -h /var/spool/postfix/vmail/$domains/ --max-depth=2 -c | 
        egrep "/var/spool/postfix/vmail/$domains/[a-z]/" | 
        sed -re "s//var/spool/postfix/vmail/$domains/[a-z]///g" | 
        egrep -v "[0-9]{3}" | 
        egrep "[0-9]{2}M" | 
        awk '{print $1, "               ",$2}' | 
        sort -r

du -h /var/spool/postfix/vmail/$domains/ --max-depth=2 -c | 
        egrep "/var/spool/postfix/vmail/$domains/[a-z]/" | 
        sed -re "s//var/spool/postfix/vmail/$domains/[a-z]///g" | 
        egrep "[0-9]{1}.[0-9]{1}M" | 
        awk '{print $1, "       ",$2}' | 
        sort -r

du -h /var/spool/postfix/vmail/$domains/ --max-depth=2 -c | 
        egrep "/var/spool/postfix/vmail/$domains/[a-z]/" | 
        sed -re "s//var/spool/postfix/vmail/$domains/[a-z]///g" | 
        egrep "[0-9]{4}K" | 
        awk '{print $1, "       ",$2}' | 
        sort -r

du -h /var/spool/postfix/vmail/$domains/ --max-depth=2 -c | 
        egrep "/var/spool/postfix/vmail/$domains/[a-z]/" | 
        sed -re "s//var/spool/postfix/vmail/$domains/[a-z]///g" | 
        egrep -v "[0-9]{4}" | 
        egrep "[0-9]{3}K" | 
        awk '{print $1, "       ",$2}' | 
        sort -r

du -h /var/spool/postfix/vmail/$domains/ --max-depth=2 -c | 
        egrep "/var/spool/postfix/vmail/$domains/[a-z]/" | 
        sed -re "s//var/spool/postfix/vmail/$domains/[a-z]///g" | 
        egrep -v "[0-9]{3}" | 
        egrep "[0-9]{2}K" | 
        awk '{print $1, "       ",$2}' | 
        sort -r

        echo " "
done

total=`du -h /var/spool/postfix/vmail/ --max-depth=1 -c | grep total | sed -re "s/total//"`
echo "---------------------------"
echo "TOTAL SIZE = $total"
echo "---------------------------"
</code>

Autosignature : Unchanged, any mail sent through 192.168.254.3 will have a signature/disclaimer added to the end of the body That's the purpose of interface eth1:0, if you want to bypass the signature you will use 192.168.254.4 as the smtp server

Again : http://blog.wains.be/?p=7 for the directions