você está aqui: Home  → Arquivo de Mensagens

Servidor de e-mail completo com Postfix e MySQL

Colaboração: Tiago Cruz

Data de Publicação: 16 de Outubro de 2005

Este documento sugere a instalação de servidor de e-mail rodando postifix com os usuários virtuais guardados em um banco de dados, e com uma interface administrativa bem simples e eficiente via web. Ha também dois anti-vírus rodando em paralelo, junto com um anti-spam para complementar a privacidade e segurança do usuário final.

Este documento não tem por objetivo ser um guia completo e detalhado sobre o assunto, e estamos levando em consideração que você conheça o ambiente e tenha boas noções de administração de servidores baseados em unix.

As instruções estão 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 distribuição que distribui pacotes em binários possui suporte as opções aqui descritas;
  2. A configuração do rc.conf deve ser adaptada para que os daemons sejam iniciados juntos com sua distribução;
  3. O caminho dos binários e arquivos de configuração devem ser copiados com sua devida modificação.

E, por fim, este documento fala apenas sobre o Mail Server, imaginando que o Web Server e o DNS Server está rodando em outra máquina.

Banco de Dados (MySQL)

Instalação

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 básica do PostfixAdmin deverá ser criada a partir do arquivo disponível no mesmo:

      # mysql -u root < DATABASE_MYSQL.TXT
    

  • O campo plain é usado pelo SASL e também para guardar a senha do usuário (quando este esquece a mesma). Esta é uma modificação não-oficial feita diretamente no código fonte do PostfixAdmin para a criação do usuário e também no plugin change_mysqlpass do Squirelmail, no caso do usuário alterar a mesma.

  • Os campos city, state e country servem para guardar a cidade, estado e país dos usuários, mantidos em uma aplicação em PHP específica 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`;
    

Permissões de acesso:

As permissões ficarão assim:

  mysql> USE mysql;
  
  mysql> SELECT host,db,user,select_priv,insert_priv,update_priv,delete_priv from db;
  +-----------------+---------+--------------+-------------+-------------+-------------+-------------+
  | host            | db      | user         | select_priv | insert_priv | update_priv | delete_priv |
  +-----------------+---------+--------------+-------------+-------------+-------------+-------------+
  | %               | test    |              | Y           | Y           | Y           | Y           |
  | %               | test\_% |              | Y           | Y           | Y           | Y           |
  | localhost       | postfix | postfix      | Y           | N           | N           | N           |
  | localhost       | postfix | postfixadmin | Y           | Y           | Y           | Y           |
  | nome.server.net | postfix | postfixadmin | Y           | Y           | Y           | Y           |
  | nome.server.net | postfix | postfix      | Y           | N           | N           | N           |
  | localhost       | postfix | webmail      | Y           | Y           | Y           | N           |
  | nome.server.net | postfix | webmail      | Y           | Y           | Y           | N           |
  +-----------------+---------+--------------+-------------+-------------+-------------+-------------+

Sendo que:

Usuário Função
postfix Usado localmente pelo Postfix buscar as informações no banco
postfixadmin Usado localmente pelo vacation e pelo Webserver para adicionar, remover e editar os usuários via PostfixAdmin
webmail Usado pelo Webserver (em outro servidor) para ler os e-mails e atualizar a senha pelo plugin do squirrelmail

Para criar as permissões 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

Alterações no main.conf do Postfix:

  
  # Basic Configuration
  myhostname = nome.site.net
  mydomain = site.net
  myorigin = $myhostname
  mydestination = $myhostname, localhost.$mydomain, localhost mail.$mydomain
  inet_interfaces = all
  
  # Proxy Settings
  proxy_read_maps = $local_recipient_maps
  local_recipient_maps = proxy:unix:passwd.byname $alias_maps $virtual_mailbox_maps
  
  # Redes confiáveis, MX secundário
  mynetworks = 200.200.200.200/29, 222.222.222.222/32, 127.0.0.0/8
  
  relay_domains = $mydestination
  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
  
  spf_explanation = "%{h} [%{i}] is not allowed to send mail for %{s}"
  
  smtpd_helo_required = yes
  
  smtpd_client_restrictions =
  permit_mynetworks
  check_client_access hash:/mailcfg/client_access
  permit
  
  smtpd_helo_restrictions =
  #      reject_invalid_hostname # Dah pau com o maldito outlook que nao implementa porra de RFC nenhum.
  check_helo_access hash:/mailcfg/helo_access
  permit
  
  smtpd_sender_restrictions =
  permit_mynetworks
  permit_sasl_authenticated
  reject_non_fqdn_sender
  reject_unknown_sender_domain
  check_sender_access hash:/mailcfg/sender_access
  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
  check_recipient_access hash:/mailcfg/recipient_access
  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 configuração 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-vírus como solução reduntante, controlado pelo Amavisd-new:

ClamAV

O ClamAV é um anti-vírus OpenSource que pode ser integrado, por exemplo, em um PDC ou em um MTA.

Depois da compilação, 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 binário em busca de vírus, e o freshclam é o daemon que cuida da atualização do mesmo várias vezes ao dia.

Um pequeno hack o ClamAV funcionar com o ClamAV+Amavisd-new:

No /etc/group, colocar o usuário clamav no grupo do vscan:

  vscan:*:GID_AMAVIS:clamav

McAfee

O McAfee é uma solução comercial e é necessário possuir uma licença de uso do mesmo, ou usar uma versão 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 versão, e aproveite para fazer os links simbóbicos necessários que o programa pedir...

  # uvscan --version

Um script modificado pelo Luis Henrique Nardella que, agendado pelo crontab, faz a atualização 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 dependência do Amavisd.

O 'make config'é normal, não precisa de nada específico.

Ação Comando
Para iniciar manualmente /etc/rc.d/amavisd start
Para parar manualmente /etc/rc.d/amavisd stop
Para iniciar durante o boot (no rc.conf) amavisd_enable = "YES"

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 configuração /usr/local/etc/amavisd.conf

  • @local_domains_maps = ( read_hash("$MYHOME/local_domains_maps") );

É um hash perl dos domínios 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 confiáveis

  • 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:

Comando Ação
Bouce Devolver
Discard Descartar
Pass Passar

Na parte de 'banned extension', nós descomentamos a 'long' e tiramos o '.exe'

Anti-spam (SpamAssassin)

Ele será compilado como módulo 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:

  ; MX Record
  @               IN MX   5      mail.site.com
  @               IN MX   20      mx2.site.com.
  
  ; SPF Record
  site.com.   IN TXT  "v=spf1 ip4:200.200.200.200/8 ip4:222.222.222.222/32 include:dominio.net ~all"
  
  ; Machine Names
  ns1             IN A    200.200.200.200
  ns2             IN A    222.222.222.222

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Brazil License



Veja a relação completa dos artigos de Tiago Cruz

 

 

Opinião dos Leitores

Gilmar
03 Fev 2011, 15:45
Sofri igual um cavalo fazendo postfix + mysql e nao tive sucesso, consegui achar esse site que salvou meu emprego http://store.jbpserver.com.br.

Em 5 minutos ja estava tudo pronto, estou utilizando em todos meus clientes agora. e meu patrao nao sabe como consigo fazer tao rapido os servidores rsrs.


Gilmar
*Nome:
Email:
Me notifique sobre novos comentários nessa página
Oculte meu email
*Texto:
 
  Para publicar seu comentário, digite o código contido na imagem acima
 


Powered by Scriptsmill Comments Script