You are on page 1of 8

Servidor de e-mail completo com Postfix e MySQL

Por Luis Nardella e Tiago Cruz em 4 de julho de 2007 s 11h09


1

Introduo
Introduo
Este documento sugere a instalao de servidor de e-mail rodando postifix com os usurios virtuais guardados
em um banco de dados, e com uma interface administrativa bem simples e eficiente via web. Ha tambm dois
anti-vrus rodando em paralelo, junto com um anti-spam para complementar a privacidade e segurana do
usurio final.
Este documento no tem por objetivo ser um guia completo e detalhado sobre o assunto, e estamos levando em
considerao que voc conhea o ambiente e tenha boas noes de administrao de servidores baseados em
unix.
As instrues esto baseadas em um sistema rodando FreeBSD, mas podem ser facilmente adaptadas para
outras plataformas e sabores do Linux ou BSD. Para tanto:
1. Certifique-se que sua distribuio que distribui pacotes em binrios possui suporte as opes aqui
descritas;
2. A configurao do rc.conf deve ser adaptada para que os daemons sejam iniciados juntos com sua
distribuo;
3. O caminho dos binrios e arquivos de configurao devem ser copiados com sua devida modificao.
E, por fim, este documento fala apenas sobre o Mail Server, imaginando que o Web Server e o DNS Server est
rodando em outra mquina.
Banco de Dados (MySQL)
Instalao
Depois de compilado o mysql-server-4.1.12, coloque uma entrada como 'mysql_enable="YES"' no rc.conf para
que o mesmo seja iniciado durante o boot e defina uma senha de root:
# mysqladmin -u root password senha
Estrutura
A estrutura final a seguinte: PostfixAdmin + plain + city, state, country, sendo que:
A estrutura bsica do PostfixAdmin dever ser criada a partir do arquivo disponvel no mesmo:
# mysql -u root < DATABASE_MYSQL.TXT
O campo plain usado pelo SASL e tambm para guardar a senha do usurio (quando este esquece a
mesma). Esta uma modificao no-oficial feita diretamente no cdigo fonte do PostfixAdmin para a
criao do usurio e tambm no pluginchange_mysqlpass do Squirelmail, no caso do usurio alterar a
mesma.
Os campos city, state e country servem para guardar a cidade, estado e pas dos usurios, mantidos em
uma aplicao em PHP especfica para este caso escrita a parte.
USE postfix;
ALTER TABLE `mailbox` ADD `city` VARCHAR(255) DEFAULT NULL AFTER `name`;
ALTER TABLE `mailbox` ADD `state` VARCHAR(255) DEFAULT NULL AFTER `city`;
ALTER TABLE `mailbox` ADD `country` VARCHAR(255) DEFAULT NULL AFTER
`state`;
Permisses de acesso:
As permisses ficaro assim:
Sendo que:
Para criar as permisses no MySQL:
# mysql -p -u root
mysql> use mysql;
mysql> GRANT select,insert,update,delete ON postfix.* TO 'postfixadmin'@'nome.server.net' IDENTIFIED BY
'senha';
mysql> GRANT select,insert,update,delete ON postfix.* TO 'postfixadmin'@'localhost' IDENTIFIED BY 'senha';
MTA (postfix)
No make do /usr/ports/mail/postfix, compilar com suporte a:
SASL2, SPF, TLS, MySQL, VDA
Segue as principais alteraes feitas no main.conf do Postfix, usando o default como base:
# Basic Configuration
myhostname = nome.site.net
mydomain = site.net
myorigin = $myhostname
mydestination = $myhostname, localhost.$mydomain, localhost mail.$mydomain
inet_interfaces = all
# Proxy Settings
# Deixa em "cache" os endereos locais para "economizar" algumas queries
proxy_read_maps = $local_recipient_maps
local_recipient_maps = proxy:unix:passwd.byname $alias_maps $virtual_mailbox_maps
# Redes confiveis, MX secundrio
# Estes endereos podem enviar e-mail sem autenticao
mynetworks = 200.200.200.200/29, 222.222.222.222/32, 127.0.0.0/8
relay_domains = $mydestination
# 550 = rejeita e-mail
# 450 = tente novamente mais tarde
unknown_local_recipient_reject_code = 550
transport_maps = mysql:/mailcfg/mysql/mysql_transport_maps.cf
alias_maps = hash:/mailcfg/aliases
# Virtual Domains Settings
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_mailbox_base = /var/mail/vmail/
virtual_mailbox_domains = mysql:/mailcfg/mysql/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/mailcfg/mysql/mysql_virtual_mailbox_maps.cf
virtual_alias_maps = mysql:/mailcfg/mysql/mysql_virtual_alias_maps.cf
# Security Options
disable_vrfy_command = yes
smtpd_etrn_restrictions = permit_mynetworks, reject
# SASL Configuration
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_application_name = smtpd
smtpd_sasl_security_options = noanonymous
# TLS Configuration
smtp_use_tls = yes
smtpd_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtpd_tls_key_file = /mailcfg/ssl/smtpd.pem
smtpd_tls_cert_file = /mailcfg/ssl/smtpd.pem
smtpd_tls_CAfile = /mailcfg/ssl/smtpd.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
# SMTPd Restrictions
smtpd_delay_reject = yes
# Vide comentrio sobre anti-spam no final do artigo
spf_explanation = "%{h} [%{i}] is not allowed to send mail for %{s}"
smtpd_helo_required = yes
smtpd_client_restrictions =
permit_mynetworks
permit
smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_sender
reject_unknown_sender_domain
permit
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
reject_non_fqdn_sender
reject_non_fqdn_recipient
reject_unknown_sender_domain
reject_unknown_recipient_domain
reject_invalid_hostname
reject_non_fqdn_hostname
reject_spf_invalid_sender
reject_rbl_client bl.spamcop.net
reject_rbl_client sbl-xbl.spamhaus.org
reject_rbl_client relays.ordb.org
reject_rbl_client opm.blitzed.org
reject_rbl_client list.dsbl.org
reject_rbl_client sbl.spamhaus.org
reject_rbl_client cbl.abuseat.org
reject_rbl_client dul.dnsbl.sorbs.net
permit
smtpd_data_restrictions =
reject_unauth_pipelining
permit
# Importante para o IMAP
home_mailbox = Maildir/
sendmail_path = /usr/local/sbin/sendmail
# Content Filter interagindo com o Amavis via SMTP
content_filter = smtp-amavis:[127.0.0.1]:10024
Os arquivos de configurao das chamadas do MySQL, em /mailcfg/mysql/ (mailcfg um link para
/usr/local/etc/postfix):
# cat mysql_relay_domains_maps.cf
hosts = localhost
user = postfix
password = senha
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '1'
# cat mysql_transport_maps.cf
hosts=localhost
user=postfix
password=senha
dbname=postfix
table=domain
select_field=transport
where_field=domain
# cat mysql_virtual_alias_maps.cf
hosts = localhost
user = postfix
password = senha
dbname = postfix
table = alias
select_field = goto
where_field = address
# cat mysql_virtual_domains_maps.cf
hosts = localhost
user = postfix
password = senha
dbname = postfix
table = domain
select_field = description
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'
# cat mysql_virtual_mailbox_limit_maps.cf
hosts = localhost
user = postfix
password = senha
dbname = postfix
table = mailbox
select_field = quota
where_field = username
additional_conditions = and active = '1'
# cat mysql_virtual_mailbox_maps.cf
hosts = localhost
user = postfix
password = senha
dbname = postfix
table = mailbox
select_field = maildir
where_field = username
additional_conditions = and active = '1'
POP3/IMAP
O pacote o courier-imap, no make config dele marcar auth_mysql e openssl (ir instalar o courier-imap-authlib)
Em /usr/local/etc/courier-imap renomear os .dist
Em /usr/local/etc/authlib renomear os .dist e:
Arquivo authdaemonrc:
authmodulelist="authmysql"
Arquivo authmysqlrc:
MYSQL_SERVER localhost
MYSQL_USERNAME postfix
MYSQL_PASSWORD senha
MYSQL_SOCKET /tmp/mysql.sock
MYSQL_DATABASE postfix
MYSQL_USER_TABLE mailbox
MYSQL_CRYPT_PWFIELD password
MYSQL_UID_FIELD '5000'
MYSQL_GID_FIELD '5000'
MYSQL_LOGIN_FIELD username
MYSQL_HOME_FIELD '/var/mail/vmail'
MYSQL_MAILDIR_FIELD maildir
MYSQL_QUOTA_FIELD quota
MYSQL_WHERE_CLAUSE active='1'
IMAPD/ POP3D do rc.conf:
courier_authdaemond_enable="YES"
courier_imap_imapd_enable="YES"
courier_imap_pop3d_enable="YES"
courier_imap_imapd_ssl_enable="YES"
courier_imap_pop3d_ssl_enable="YES"
Anti-virus (ClamAV + McAfee)
Usamos dois anti-vrus como soluo reduntante, controlado pelo Amavisd-new:
ClamAV
O ClamAV um anti-vrus OpenSource que pode ser integrado, por exemplo, em um PDC ou em um MTA.
Depois da compilao, para inicia-lo durante o boot coloque no rc.conf:
## CLAMAV - Anti-Virus and SPAM protection
clamav_clamd_enable="YES"
clamav_clamd_flags=""
clamav_clamd_socket="/var/run/clamav/clamd"
#
## FRESHCLAM - Virus database update
clamav_freshclam_enable="YES"
clamav_freshclam_flags=""
O clamd o daemon do ClamAV que varre o binrio em busca de vrus, e o freshclam o daemon que cuida da
atualizao do mesmo vrias vezes ao dia.
Um pequeno hack o ClamAV funcionar com o ClamAV+Amavisd-new:
No /etc/group, colocar o usurio clamav no grupo do vscan:
vscan:*:GID_AMAVIS:clamav
McAfee
O McAfee uma soluo comercial e necessrio possuir uma licena de uso do mesmo, ou usar uma verso
trial.
Em nai.com -> download -> Product Upgrades
Escolha o produto: Command Line Scanner para FreeBSD
Baixe e descompacte com o gunzip e depois com o tar, e execute o install-uvscan
Tente executar o comando abaixo para ver a verso, e aproveite para fazer os links simbbicos necessrios que
o programa pedir...
# uvscan --version
Um script modificado pelo Luis Henrique Nardella que, agendado pelo crontab, faz a atualizao da base de dados
do McAFee:
# cat dat_update.sh
#!/bin/sh
# Kris Kennaway <kris at FreeBSD.org>
# Luis Nardella <luis.nardella at @gmail.com>
data=`date`
WGET='/usr/local/bin/wget --passive-ftp -o wget.log -c -v -t10'
LOGFILE='/var/log/dat_update.log'
cd /usr/local/uvscan/
rm -f -v update.ini > $LOGFILE
if ${WGET} ftp://ftp.nai.com/pub/datfiles/english/update.ini
then
echo "$data - Verificando se ha atualizacoes -> CHECKED" >> $LOGFILE
else
echo "$data - Nao foi possivel verificar -> BROKED" >> $LOGFILE
fi
# Variavel que recebe o valor da DAT mais atual.
#AVVER=`/usr/bin/head -1 readme.txt | /usr/bin/cut -d' ' -f7`
#AVVER=`/usr/bin/head -1 readme.txt | /usr/bin/sed -e 's/^.* (4[0-9]*) .*$/1/'`
#AVVER=`/usr/bin/head -6 update.ini | grep DATVersion= | cut -d '=' -f2`
AVVER=`grep DAT update.ini | head -5 | grep '[^0-9]4[0-9][0-9][0-9][^0-9]' | head -1 | sed -e
's/^.*[^0-9](4[0-9]*)[^0-9].*$/1/'`
echo "$data - DAT mais atual (update.ini) $AVVER" >> $LOGFILE
if [ ! -f dat-$AVVER.tar ]
then
for i in *.tar
do
echo "$data - valor de i no loop for = ${i}"
mv -f -v ${i} ${i}.old >> $LOGFILE
done
if ${WGET} ftp://ftp.nai.com/pub/datfiles/english/dat-$AVVER.tar
then
echo "$data - Dowloaded new datfile $AVVER" >> $LOGFILE
for i in *.dat
do
cp -p -v $i $i.bak >> $LOGFILE
done
if /usr/bin/tar -xvf dat-${AVVER}.tar >> $LOGFILE
then
rm -f *.old
echo "$data - Successfully updated AntiVirus DAT files to $AVVER" >>
$LOGFILE
fi
else
echo "$data - The download of new DAT file doesn't work, something is
wrong" >> $LOGFILE
fi
else
echo "$data - The DAT file $AVVER is already UPDATED" >> $LOGFILE
fi
AmavisD-New
Nota: Instalar primeiro o ClamAV para o Amavisd-new reconhecer, o SpamAssassin vir como dependncia do
Amavisd.
O 'make config' normal, no precisa de nada especfico.
Alterar o master.cf:
## Interface for amavisd virus scanner
smtp-amavis unix - - n - 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20
127.0.0.1:10025 inet n - n - - smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks_style=host
-o mynetworks=127.0.0.0/8
-o strict_rfc821_envelopes=yes
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
Dicas do arquivo de configurao /usr/local/etc/amavisd.conf
@local_domains_maps = ( read_hash("$MYHOME/local_domains_maps") );
um hash perl dos domnios que o amavis vai verificar:
[root@VADER:~]# cat /var/amavis/local_domains_maps
dominio1.com
dominio2.com.br
dominio3.net
dominio4.org
@mynetworks = qw( 127.0.0.0/8 192.168.0.0/16 200.152.202.8/29 );
Lista das suas redes confiveis
Outros ajustes:
$final_virus_destiny = D_DISCARD;
#$final_banned_destiny = D_BOUNCE;
$final_banned_destiny = D_PASS;
$final_spam_destiny = D_DISCARD;
$final_bad_header_destiny = D_PASS;
Sendo que:
Na parte de 'banned extension', ns descomentamos a 'long' e tiramos o '.exe'
Anti-spam (SpamAssassin)
Ele ser compilado como mdulo perl junto com o Amavisd-new.
Lembrando que a parte de SPF (Sender Policy Framework) do main.cf do postfix s ir funcionar se voc tiver as
respectivas entradas no seu servidor de DNS, como: