Postfix com Virtual Hosts e SMTP Autenticado

July 15, 2009

[Warning: This post is a backup recovery from my previous Wordpress blog. All content was automatically converted accessing a MySQL database using a Python script (details). Mostly are in Portuguese but if you are interest I can translate to English. If you found any problem dont’t hesitate to contact me in comments.]

Instalando o Postfix com Virtual Host e SMTP Autenticado

Neste post ser descrita a instalao passo-a-passo de um Postfix utilizando virtual hosts e smtp autenticado, todas as informaes sero armazenadas em uma base de dados MySQL.

Neste procedimento ser descrito desde o momento no qual realizamos uma instalao bsica do Postfix, depois colocamos suporte a imap e pop3 seguros por TLS, depois configuramos o sasl que far a autenticao das conexes SMTP atravs 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 configurao como esta e a falta de material em portugus e tambm a dificuldade de se encontrar um documento to completo que realize passo-a-passo esses procedimentos ao seu final todos componentes funcionam de forma adequada, espero que sirva para voc e comentrios/crticas so sempre bem vindos.

Postfix

1. Instalando sistema base

Para configurar o postfix necessitaremos dos seguintes pacotes:

$ sudo apt-get install postfix postfix-mysql
Configurao Padro: "No Configuration"

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

2. Pacotes de Autenticao POP3/IMAP

Estes pacotes so para estabelecer conexo 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 Autenticao SMTP

J estes pacotes sero utilizados para autenticar usurios para envio de e-mails no 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 contm 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 usurios 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 no 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 permisso 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 usurio vmail para armazenar os e-mails de todos os vhosts, no necessitando assim uma conta no sistema para cada usurio
$ 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. Configurao do Postfix

Termina de realizar a configurao do Postfix para usar nossos certificados para o TLS e configuraes bsicas 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 parmetros com seus valores padro

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. Autenticao de IMAP

Configuramos este arquivo para o IMAP realizar a conexo ao banco de dados para validar cada tentativa de conexo dos usurios.

Alterao para usar o mdulo 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 servios 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. Autenticao 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 esto configurados como:

MECHANISMS="pam"

e altere a opo OPTIONS:

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

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

Configuramos o Postfix para o mesmo somente aceitar envio de e-mails de usurios 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 mdulo 'smtp' no pam para que o sasl use este mtodo para autenticar atravs 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 alteraes:
Crie o grupo sasl e adicione o usurio postfix ao mesmo adicionando esta linha no arquivo /etc/group
$ sudo vi /etc/group

sasl:x:45:postfix

Crie os arquivos/diretrios que ficaro 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 servio 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 usurio no postfix (via insero manual no banco ou usando o postfixadmin) pode testar a autenticao por sasl utilizando o seguinte comando:
Testando usurio atravs 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 verso, tenho usado em ambientes de produo e no 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 configurao 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'] = '<senha do postfixadmin>';
$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';

# Customizaes
$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'] = <<<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 instalao 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 usurio administrador e agora seu postfixadmin j est pronto para ser acessado e j podem ser criadas as contas.

SquirrelMail

Instalao do squirrelmail via apt
$ sudo apt-get install squirrelmail

Configure o squirrelmail utilizando seu configurador (customizaes devem ser feitas nesse passo) nenhum configurao adicional necessria para o nosso sitema.
$ sudo squirrelmail-configure

Copie o arquivo de configurao para usar o squirrelmail no apache, se quiser mudar a localizao 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