jul
15
2009

Postfix com Virtual Hosts e SMTP Autenticado

Instalando o Postfix com Virtual Host e SMTP Autenticado

Neste post será descrita a instalação passo-a-passo de um Postfix utilizando virtual hosts e smtp autenticado, todas as informações serão armazenadas em uma base de dados MySQL.

Neste procedimento será descrito desde o momento no qual realizamos uma instalação básica do Postfix, depois colocamos suporte a imap e pop3 seguros por TLS, depois configuramos o sasl que fará a autenticação das conexões SMTP através do PAM e por fim instalaremos o postfixadmin que gerenciará as contas de e-mail e o squirrelmail que servirá para acessá-las.

Este documento foi escrito devido a certa dificuldade de realizar uma configuração como esta e a falta de material em português e também a dificuldade de se encontrar um documento tão completo que realize passo-a-passo esses procedimentos ao seu final todos componentes funcionam de forma adequada, espero que sirva para você e comentários/críticas são sempre bem vindos.

Postfix

1. Instalando sistema base

Para configurar o postfix necessitaremos dos seguintes pacotes:

$ sudo apt-get install postfix postfix-mysql
Configuração Padrão: “No Configuration”

$ sudo /usr/share/postfix/main.cf.debian /etc/postfix/main.cf

2. Pacotes de Autenticação POP3/IMAP

Estes pacotes são para estabelecer conexão segura entre o cliente pop3/imap e o servidor de e-mails.
$ sudo apt-get install courier-authdaemon courier-authlib-mysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl

3. Pacotes de Autenticação SMTP

Já estes pacotes serão utilizados para autenticar usuários para envio de e-mails não tornando nosso servidor um open relay
$ sudo apt-get install libsasl2 libsasl2-modules libsasl2-modules-sql openssl sasl2-bin libpam-mysql

4. Cria o Banco de Dados para o Postfix

4.1. Cria o arquivo postfixadmin-mysql.sql que contém as tabelas usadas pelo mapeamento do postfix.

#
# Postfix / MySQL
#
CREATE DATABASE postfix;

GRANT SELECT ON postfix.* TO postfix@localhost IDENTIFIED BY 'postfixpassword';
GRANT SELECT, INSERT, DELETE, UPDATE, CREATE, ALTER ON postfix.* TO postfixadmin@localhost IDENTIFIED BY 'postfixadmin';

USE postfix;
#
# Table structure for table admin
#
CREATE TABLE admin (
username varchar(255) NOT NULL default '',
password varchar(255) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
modified datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(1) NOT NULL default '1',
PRIMARY KEY  (username),
KEY username (username)
) COMMENT='Postfix Admin - Virtual Admins';

#
# Table structure for table alias
#
CREATE TABLE alias (
address varchar(255) NOT NULL default '',
goto text NOT NULL,
domain varchar(255) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
modified datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(1) NOT NULL default '1',
PRIMARY KEY  (address),
KEY address (address)
) COMMENT='Postfix Admin - Virtual Aliases';

#
# Table structure for table domain
#
CREATE TABLE domain (
domain varchar(255) NOT NULL default '',
description varchar(255) NOT NULL default '',
aliases int(10) NOT NULL default '0',
mailboxes int(10) NOT NULL default '0',
maxquota int(10) NOT NULL default '0',
transport varchar(255) default NULL,
backupmx tinyint(1) NOT NULL default '0',
created datetime NOT NULL default '0000-00-00 00:00:00',
modified datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(1) NOT NULL default '1',
PRIMARY KEY  (domain),
KEY domain (domain)
) COMMENT='Postfix Admin - Virtual Domains';

#
# Table structure for table domain_admins
#
CREATE TABLE domain_admins (
username varchar(255) NOT NULL default '',
domain varchar(255) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(1) NOT NULL default '1',
KEY username (username)
) COMMENT='Postfix Admin - Domain Admins';

#
# Table structure for table log
#
CREATE TABLE log (
timestamp datetime NOT NULL default '0000-00-00 00:00:00',
username varchar(255) NOT NULL default '',
domain varchar(255) NOT NULL default '',
action varchar(255) NOT NULL default '',
data varchar(255) NOT NULL default '',
KEY timestamp (timestamp)
) COMMENT='Postfix Admin - Log';

#
# Table structure for table mailbox
#
CREATE TABLE mailbox (
username varchar(255) NOT NULL default '',
password varchar(255) NOT NULL default '',
name varchar(255) NOT NULL default '',
maildir varchar(255) NOT NULL default '',
quota int(10) NOT NULL default '0',
domain varchar(255) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
modified datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(1) NOT NULL default '1',
PRIMARY KEY  (username),
KEY username (username)
) COMMENT='Postfix Admin - Virtual Mailboxes';

#
# Table structure for table vacation
#
CREATE TABLE vacation (
email varchar(255) NOT NULL default '',
subject varchar(255) NOT NULL default '',
body text NOT NULL,
cache text NOT NULL,
domain varchar(255) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(1) NOT NULL default '1',
PRIMARY KEY  (email),
KEY email (email)
) COMMENT='Postfix Admin - Virtual Vacation';

4.2. Editar a senha para os usuários postfix e postfixadmin no postfixadmin-mysql.sql

4.3. Executa o sql no banco de dados

$ mysql -uroot -psenhaderoot < postfixadmin-mysql.sql

4.4 Remove o arquivo sql

$ rm postfixadmin-mysql.sql

5. Configurando os mapas do Postfix

Uma vez que as tabelas foram criadas, configura o postfix para realizar o mapeamento editando cada um dos arquivos, e não esquecendo de alterar as credenciais de acesso ao banco de dados.

$ sudo vi /etc/postfix/mysql_virtual_alias_maps.cf

user = postfix
password = postfixpassword
hosts = 127.0.0.1
dbname = postfix
table = alias
select_field = goto
where_field = address

$ sudo vi /etc/postfix/mysql_virtual_domains_maps.cf

user = postfix
password = postfixpassword
hosts = 127.0.0.1
dbname = postfix
table = domain
select_field = domain
where_field = domain
#additional_conditions = and backupmx = '0' and active = '1'

$ sudo vi /etc/postfix/mysql_virtual_mailbox_maps.cf

user = postfix
password = postfixpassword
hosts = 127.0.0.1
dbname = postfix
table = mailbox
select_field = maildir
where_field = username
#additional_conditions = and active = '1'

$ sudo vi /etc/postfix/mysql_virtual_mailbox_limit_maps.cf

user = postfix
password = postfixpassword
hosts = 127.0.0.1
dbname = postfix
table = mailbox
select_field = quota
where_field = username
#additional_conditions = and active = '1'

$ sudo vi /etc/postfix/mysql_relay_domains_maps.cf

user = postfix
password = postfixpassword
hosts = 127.0.0.1
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '1'

Alterar permissão dos mapas para somente root alterar e o postfix poder ler, visto que temos credenciais de acesso ao banco nos arquivos.
$ sudo chgrp postfix /etc/postfix/mysql_*.cf
$ sudo chmod 640 /etc/postfix/mysql_*.cf

Criar usuário vmail para armazenar os e-mails de todos os vhosts, não necessitando assim uma conta no sistema para cada usuário
$ sudo groupadd -g 5000 vmail
$ sudo useradd -m -g vmail -u 5000 -d /home/vmail -s /bin/bash vmail

6. Configura o Postfix para Utilizar os Mapas

Uma vez que temos o banco de dados criados, os arquivos que fazem o mapeamento, temos que configurar no Postfix para o mesmo utilizar cada um dos mapeamentos para determinada tarefa, como segue:

$ sudo vi /etc/postfix/main.cf

# Virtual Mailbox Domain Settings

virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_mailbox_limit = 51200000
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_mailbox_base = /home/vmail
virtual_transport = virtual

# Additional for quota support

virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, the your maildir has overdrawn your diskspace quota, please free up some of spaces of your mailbox try again.
virtual_overquota_bounce = yes

7. Configuração do Postfix

Termina de realizar a configuração do Postfix para usar nossos certificados para o TLS e configurações básicas do mesmo.

$ sudo vi /etc/postfix/main.cf

# TLS parameters
smtpd_tls_cert_file = /etc/postfix/smtpd.cert
smtpd_tls_key_file = /etc/postfix/smtpd.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

#The host name where your MX for virtual domains will point to
myhostname = mail.domain.com
mydestination = #Remains blank since we are going to host virtual domains
relayhost = #Remains blank unless you are going to use your ISP's SMTP server mail sending out mails. In which case it would be set to the host name of the ISP's SMTP server

Deixe esses parâmetros com seus valores padrão

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mynetworks = <seuip>/32 127.0.0.1/32
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

8. Autenticação de IMAP

Configuramos este arquivo para o IMAP realizar a conexão ao banco de dados para validar cada tentativa de conexão dos usuários.

Alteração para usar o módulo mysql no courier authdaemon

$ sudo vi /etc/courier/authdaemonrc

authmodulelist="authmysql authpam"

$ sudo vi /etc/courier/authmysqlrc

MYSQL_SERVER        127.0.0.1
MYSQL_USERNAME        postfixadmin
MYSQL_PASSWORD        <senha postfixadmin>
MYSQL_PORT            0
MYSQL_OPT            0
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    '/home/vmail'
MYSQL_NAME_FIELD    name
MYSQL_MAILDIR_FIELD    maildir
MYSQL_QUOTA_FIELD    concat(quota,'S')

Reinicie os serviços e cheque os logs:

$ sudo /etc/init.d/courier-authdaemon restart
$ sudo /etc/init.d/courier-imap restart
$ sudo /etc/init.d/courier-imap-ssl restart
$ sudo /etc/init.d/courier-pop restart
$ sudo /etc/init.d/courier-pop-ssl restart
$ sudo tail -f /var/log/mail.info

9. Autenticação de SMTP

Antes de mais nada para habilitar o saslauthd fazemos:
$ sudo vi /etc/default/saslauthd

START=yes

e verifique neste arquivo se os mecanismos estão configurados como:

MECHANISMS="pam"

e altere a opção OPTIONS:

OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"

e então habilite o servico:
$ sudo /etc/init.d/saslauthd start

Configuramos o Postfix para o mesmo somente aceitar envio de e-mails de usuários autenticados via sasl

$ sudo vi /etc/postfix/main.cf

smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, permit
# modify the existing smtpd_sender_restrictions
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_pipelining, permit
# then add these
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_path = smtpd
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =

Cria o arquivo que diz para o Postfix como será a checagem da senha, no caso, via saslauthd
$ sudo vi /etc/postfix/sasl/smtpd.conf

pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
log_level: 5

Configura o módulo ’smtp’ no pam para que o sasl use este método para autenticar através do mesmo.
$ sudo vi /etc/pam.d/smtp

auth    required   pam_mysql.so user=<user do banco> passwd=<passwd do mysql> host=127.0.0.1 db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1
account sufficient pam_mysql.so user=<user do banco> passwd=<passwd do mysql> host=127.0.0.1 db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1

Como estamos utilizando nosso smtp em uma jail, temos que realizar as seguintes alterações:
Crie o grupo sasl e adicione o usuário postfix ao mesmo adicionando esta linha no arquivo /etc/group
$ sudo vi /etc/group

sasl:x:45:postfix

Crie os arquivos/diretórios que ficarão dentro da jail para o postfix autenticar no sasl

$ sudo mkdir -p /var/spool/postfix/var/run/
$ sudo mv /var/run/saslauthd /var/spool/postfix/var/run/saslauthd
$ sudo ln -ns /var/spool/postfix/var/run/saslauthd /var/run/saslauthd
$ sudo cp /etc/sasldb2 /var/spool/postfix/etc/
$ sudo chgrp sasl /var/spool/postfix/etc/sasldb2
$ sudo chmod g+w /var/spool/postfix/etc/sasldb2

Reinicie os serviço e cheque o log
$ sudo /etc/init.d/courier-authdaemon restart
$ sudo /etc/init.d/saslauthd restart
$ sudo /etc/init.d/postfix restart
$ sudo tail -f /var/log/mail.info

Uma vez que tenha adicionado um usuário no postfix (via inserção manual no banco ou usando o postfixadmin) pode testar a autenticação por sasl utilizando o seguinte comando:
Testando usuário através do sasl
$ sudo testsaslauthd -s smtp -f /var/spool/postfix/var/run/saslauthd/mux -u ‘user@vhost.com’ -p senha

Postfixadmin

Baixe o postfixadmin na sua última versão, tenho usado em ambientes de produção e não tive nenhum problema com a mesma.

$ wget http://sourceforge.net/projects/postfixadmin/files/postfixadmin/postfixadmin_2.3rc5.tar.gz
Descompacte o arquivo e copie para dentro do seu webroot

$ tar xvzf postfixadmin_2.3rc5.tar.gz
$ sudo mv postfixadmin-2.3rc5/ /var/www/postfixadmin/

Altere o arquivo de configuração para configurar o sistema de deixá-lo pronto para o setup

$ sudo vi /var/www/postfixadmin/config.inc.php

$CONF['configured'] = true;
 
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = '&lt;senha do postfixadmin&gt;';
$CONF['database_name'] = 'postfix';
 
$CONF['postfix_admin_url'] = '';
$CONF['admin_email'] = 'postmaster@change-this-to-your.domain.tld';
 
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
 
# Customizações
$CONF['user_footer_link'] = "http://seudominio.com.br/postfixadmin";
$CONF['footer_text'] = 'Return to postfixmyadmin home';
$CONF['footer_link'] = 'http://seudominio.com.br/postfixadmin';
 
$CONF['welcome_text'] = &lt;&lt;&lt;EOM
Hi,
 
Welcome to your new account.
EOM;
 
$CONF['theme_logo'] = 'images/logo-default.png';
$CONF['theme_css'] = 'css/default.css';

Acesse o setup.php em http://seudominio.com.br/postfixadmin/setup.php
Coloque a senha da instalação e ao gerar o hash, copie-o para:

$CONF['setup_password'] = 'changeme'

Novamente acesse o setup.php em http://seudominio.com.br/postfixadmin/setup.php e crie as credenciais do seu usuário administrador e agora seu postfixadmin já está pronto para ser acessado e já podem ser criadas as contas.

SquirrelMail

Instalação do squirrelmail via apt
$ sudo apt-get install squirrelmail

Configure o squirrelmail utilizando seu configurador (customizações devem ser feitas nesse passo) nenhum configuração adicional é necessária para o nosso sitema.
$ sudo squirrelmail-configure

Copie o arquivo de configuração para usar o squirrelmail no apache, se quiser mudar a localização de /squirrelmail para /webmail por exemplo, altere na linha que contem o Alias
$ sudo cp /etc/squirrelmail/apache.conf /etc/apache2/sites-available/squirrelmail

Habilite o vhost do squirrelmail
$ sudo a2ensite squirrelmail

Reinicie o Apache
$ sudo /etc/init.d/apache2 force-reload

tags: , , , , ,
posted in sysadmin by Celso Fernandes

Follow comments via the RSS Feed | Deixe um comentário | Trackback URL

11 Comments to "Postfix com Virtual Hosts e SMTP Autenticado"

  1. Carlos Miranda wrote:

    Olá. Desde já os meus parabéns pelo tutorial, esta muito completo. Tenho uma dúvida: Eu criei o servidor e consigo aceder via postfixadmin e criar os utilizadores virtuais mas preciso de ligar via telnet as contas por causa de umas experiencias que ando a realizar e cada vez que tento aceder a elas via telnet, depois de colocar a password do user é devolvido o seguinte erro e é automaticamente terminada a sessão de telnet: “[postfix] telnet localhost 110 – ERR Maildir invalid ” ja tentei resolver isto mas sem exito. Ha alguma coisa que me tenha fugido no meio do tutorial? utlizo o ubuntu 8.04 server para o que estou a fazer. desde ja, obrigado pela resposta.

  2. Celso Fernandes wrote:

    Olá Carlos,

    Primeiramente obrigado pelos parabéns, desculpe se não entendi algo do seu comentário, mas por que esta acessando o servidor via telnet? Utilize o ssh que é melhor e mais seguro!

    Quanto a sua dúvida, como está tentando acessar as contas via telnet? ja tentou acessá-las via squirrelmail ou algum cliente de mail de sua preferência?

    Até mais.

  3. Carlos Miranda wrote:

    Ola e obrigado pela resposta. É o seguinte: isto faz parte de uma simulação de uma rede fechada e estou a aceder via telnet porque tenho um script criado que vai aceder as contas via pop3 em diferentes pontos da rede para verificar os e-mails de modo a gerar tráfego de pacotes smtp dentro da rede fechada para realizar capturas e medições para o trabalho que estou a realizar. Visto o script utilizado é por linha de comandos, optei pela opção de telnet porque não posso ter clientes de e-mail’s gráficos visto que preciso de utilizar a opção de bind address para que o tráfego seja enviado pelos interfaces que eu quero.

    Ate mais e obrigado.

  4. Celso Fernandes wrote:

    Olá Carlos,

    Tive um pouco de dificuldade em responder sua pergunta, mas creio que para gerar um relatório do tráfego do seu servidor de smtp, poderia gerá-lo a partir do log que o mesmo gera, não seria uma solução mais adequada?

    Até mais,
    Celso.

  5. Carlos Miranda wrote:

    Ola. Não é um relatório de tráfego que eu quero, eu quero mesmo gerar tráfego aleatório smtp dentro da rede, imitar utilizadores através de um distribuição exponencial. Tive a tentar entrar pelo imap e o erro obtido é parecido: “fatal error: Maildir: no such file or directory” e dps fiz o seguinte comando “/usr/bin/imapd .maildir” ao que obtive o seguinte: “chdir .maildir no such or directory” ou seja, parece que não existe a directoria Maildir e o courier precisa desta. Esta directoria não tem que ser criada através do comando maildirmake? mais uma vez, obrigado e desculpa o incomodo.

  6. Celso Fernandes wrote:

    Olá Carlos,

    Agora sim entendi o quer fazer, procure sobre como usar o mailx, você conseguirá enviar e-mails com ele através da linha de comando, desta forma irá conseguir gerar este tráfego dentro da sua rede.
    De acordo com o texto que fiz, devido ao suporte a virtual host todos e-mails ficam guardados em /home/vmail crie uma conta no postfixadmin, coloque para enviar o e-mail de boas vindas e assim o diretório será criado automaticamente.

    ps: A criação do usuário vmail e do seu home, podem ser conferidas no item (5).

    Espero que agora dê tudo certo heheh

    Até mais,
    Celso.

  7. Carlos Miranda wrote:

    Ola. Obrigado pela resposta. Esta a referir-te a instalar o pacote ssmtp? e com respeito ao maildir, se executar o maildirmake tenho que criar uma pasta maildir dentro do vmail para depois serem criadas as sub-pastas? é que o postfixadmin cria o e-mail de boas vindas e eu vejo no servidor essas pastas criadas, mas o telnet não consegue abrir pq diz que não encontra a pasta maildir.

    ate mais.
    Carlos

  8. Carlos Miranda wrote:

    Ola. Penso ter encontrado uma resposta a este problema no seguinte link: https://help.ubuntu.com/community/PostfixVirtualMailBoxClamSmtpHowto na secção “Postfix virtual Mailboxes for Separate Domains and Non-Linux Accounts” como o dominio e as contas não apresentam o formato do maildir (Maildir/) elas não conseguem ser vistas, mas pelo que me parece este exemplo não utiliza a base de dados criada no teu tutorial, o que achas?

    ate mais.
    Carlos.

  9. Carlos Miranda wrote:

    Desculpa mandar mais esta mensagem. Seria possível postares o teu main.cf para comparar com o meu? é que pelo que estou a ver, podem existir o problema de ele não esta a ver o maildir da base de dados porque o meu home_mailbox esta configurado para ser Maildir/ e pelo que vi na base de dados as mailboxes encontram-se nesse formato, mas parece que ele não consegue ir a base de dados por algum motivo.

    Desde ja obrigado e desculpa o incomodo.
    Ate mais.
    Carlos

  10. Carlos Miranda wrote:

    Ola. só para avisar que finalmente consegui resolver o problema :) olhei com mais calma para as minhas configurações e tinha uma linha comentada que não devia estar, a MYSQL_MAILDIR_FIELD maildir no ponto 8 do tutorial. mais uma vez parabéns pelo tutorial e obrigado pela ajuda :)

    Ate mais.
    Carlos.

  11. Celso Fernandes wrote:

    Olá Carlos,

    Fico feliz que tenha conseguido resolver seu problema, realmente esses ‘detalhes’ na configuração fazem a diferença.

    Um abraço e até a próxima,
    Celso.

Leave Your Comment