Instalado o Postfix, vamos cuidar da autenticação pelo banco de dados, imap e configuração dos usuários virtuais. Instale os pacotes:
# aptitude install courier-pop courier-pop-ssl courier-imap courier-imap-ssl courier-authdaemon courier-authlib-postgresql
Criação dos certificados:
Após a instalação temos que gerar certificados para serem utilizados com os pacotes courier-pop-ssl e courier-imap-ssl. Então vamos lá:
# cd /etc/courier
Crie o arquivo imapd.cnf:
# cp imapd.cnf.dpkg-new imapd.cnf
Edite agora o arquivo "imapd.cnf", adicionando as suas informações nos campos abaixo:
C=BR
ST=SP
L=Minha Cidade
emailAddress=postmaster@meudominio.com.br
Bem, se souber o que está fazendo, altere os outros campos, se quiser. Agora, gere o certificado:
# mkimapdcert
Se existir o certificado de pop, renomeie-o, e gere o novo:
# mv pop3d.pem pop3d.pem.old
Edite o arquivo "pop3d.cnf" do mesmo modo que o "imap.conf". Gere o novo certificado de pop:
# mkpop3dcert
No fim, os arquivos tem que ficar próximo disso:
imapd.cnf:
RANDFILE = /usr/lib/courier/imapd.rand
[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no
[ req_dn ]
C=BR
ST=SP
L=Minha Cidade
O=Courier Mail Server
OU=IMAP SSL key
CN=localhost
emailAddress=postmaster@meudominio.com.br
[ cert_type ]
nsCertType = server
pop3d.cnf:
RANDFILE = /usr/lib/courier/pop3d.rand
[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no
[ req_dn ]
C=BR
ST=SP
L=Minha Cidade
O=Courier Mail Server
OU=POP3 SSL key
CN=localhost
emailAddress=postmaster@meudominio.com.br
[ cert_type ]
nsCertType = server
Ok, até o momento não fizemos muito mais do que uma instalação básica. A criação de usuários virtuais exige um esquema de autenticação um pouco mais elaborado. É necessário configurar o daemon de autenticação para utilizar o módulo do postgre. Edite "/etc/courier/authdaemonrc" e inclua 'authpgsql', na lista de módulos a serem carregados. Nessa linha, o meu ficou assim:
authmodulelist="authpam authcram authpgsql"
# Lista de todos os módulos disponíveis:
authmodulelistorig="authuserdb authpam authpgsql authldap authmysql authcustom authpipe"
É interessante, na fase de testes, habilitar a exibição de informações de debug nos logs (/var/log/syslog):
DEBUG_LOGIN=1 # ativa o debug
DEBUG_LOGIN=2 # ativa o debug e exibe as senhas
courier-authdaemon courier-authlib-postgresql
#DEBUG AUTHDAEMON
ATENÇÃO: Não esqueça de desativar os debugs depois de finalizar o processo!
Agora vamos reconfigurar o Postfix a fim de criar usuários virtuais. Para isso vamos ter que criar um banco de dados para que o Postfix retire dele as informações. Além disso, temos que especificar como essas informações serão retiradas do nosso banco de dados, via comandos SQL. Vamos começar alterando as variáveis no
/etc/postfix/main.cf para (exemplo para um servidor 'urano'):
myhostname = urano.meudominio.com.br
mydomain = meudominio.com.br
Agora adicionaremos no final do arquivo as linhas:
# Domínios virtuais com o PostgreSQL:
virtual_gid_maps = static:107
virtual_uid_maps = static:108
virtual_transport = virtual
virtual_mailbox_limit = 51200000
virtual_mailbox_base = /var/vusers
virtual_alias_maps = pgsql:/etc/postfix/pgsql_virtual_aliases_maps.cf
virtual_mailbox_domains = pgsql:/etc/postfix/pgsql_virtual_domains_maps.cf
virtual_mailbox_maps = pgsql:/etc/postfix/pgsql_virtual_mailbox_maps.cf
ATENÇÃO: NO meu sistema, o id de usuário do Postfix é 107, e do grupo postfix é 108. Ajuste para os valores correspondentes no seu sistema. Incluindo os esquemas de autenticação TLS, o meu arquivo /etc/postfix/main.cf completo ficou:
OBS.: Não altere a ordem de precedência dos comandos do arquivo original, ela é importante.
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.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
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
myhostname = urano.meudominio.com.br
mydomain = meudominio.com.br
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination =
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
# Domínios virtuais com o PostgreSQL:
virtual_gid_maps = static:107
virtual_uid_maps = static:104
virtual_transport = virtual
virtual_mailbox_limit = 0
virtual_mailbox_base = /mail/vusers
virtual_alias_maps = pgsql:/etc/postfix/pgsql_virtual_aliases_maps.cf
virtual_mailbox_domains = pgsql:/etc/postfix/pgsql_virtual_domains_maps.cf
virtual_mailbox_maps = pgsql:/etc/postfix/pgsql_virtual_mailbox_maps.cf
Obs.: As linhas que contém 'pgsql:' indicam que o Postfix irá solicitar ao módulo correspondente (postgres) para que execute os comandos em banco de dados. Estes comandos se referem aos scripts que o Postfix irá executar para acessar o banco de dados. Obviamente, temos que criar os scripts.
Arquivo pgsql_virtual_aliases_maps.cf:
user = postfix
password = postpass
hosts = localhost
dbname = mail
query = SELECT address FROM aliases WHERE alias='%s'
Arquivo pgsql_virtual_domains_maps.cf:
user = postfix
password = postpass
hosts = localhost
dbname = mail
query = SELECT domain FROM domain WHERE domain='%s'
Arquivo pgsql_virtual_mailbox_maps.cf:
user = postfix
password = post1b2a
hosts = localhost
dbname = mail
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = 1
Ajuste o arquivo
/etc/courier/authpgsqlrc:
PGSQL_HOST localhost
PGSQL_PORT 5432
PGSQL_USERNAME postfix
PGSQL_PASSWORD postpass
PGSQL_DATABASE mail
PGSQL_USER_TABLE mailbox
PGSQL_CRYPT_PWFIELD password
PGSQL_UID_FIELD 107
PGSQL_GID_FIELD 108
PGSQL_LOGIN_FIELD username
PGSQL_HOME_FIELD '/var/vusers'
PGSQL_MAILDIR_FIELD maildir
ATENÇÃO: Novamente, no meu sistema, o id de usuário do postfix é 107, e do grupo postfix é 108. Ajuste para os valores correspondentes no seu sistema.
Obs.: O diretório '/var/vusers' será criado para se colocar as caixas dos usuários virtuais (nos passos a seguir).
Agora vamos criar o usuário postfix no postgre, com a mesma senha que colocamos no script:
# su - postgres
$ createuser -A -D -E -P postfix
Digite a senha para a nova role:
postpass
Digite-a novamente:
postpass
Crie um usuário admin com o mesmo login de um usuário do sistema para criar um banco de dados, tipo:
createuser -a -d -E -P useradmin
Agora vamos criar o banco de dados 'mail' e as tabelas que vamos utilizar:
# su useradmin
$ createdb mail
$ psql mail
Comandos SQL (pode copiar e colar no console):
ALTER DATABASE mail OWNER TO postgres;
\connect mail
SET client_encoding = 'UTF8';
SET standard_conforming_strings = off;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET escape_string_warning = off;
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
CREATE TABLE aliases (
alias character varying(255) DEFAULT ''::character varying NOT NULL,
address text NOT NULL,
domain character varying(255) DEFAULT ''::character varying NOT NULL,
created time with time zone DEFAULT now() NOT NULL,
modified time with time zone DEFAULT now() NOT NULL,
active integer DEFAULT 1 NOT NULL
);
ALTER TABLE public.aliases OWNER TO postfix;
CREATE TABLE domain (
domain character varying(255) DEFAULT ''::character varying NOT NULL,
description character varying(255) DEFAULT ''::character varying NOT NULL,
aliases integer DEFAULT 0 NOT NULL,
mailboxes integer DEFAULT 0 NOT NULL,
maxquota integer DEFAULT 0 NOT NULL,
transport character varying(255) DEFAULT NULL::character varying,
backupmx integer DEFAULT 0 NOT NULL,
created time with time zone DEFAULT now() NOT NULL,
modified time with time zone DEFAULT now() NOT NULL,
active integer DEFAULT 1 NOT NULL
);
ALTER TABLE public.domain OWNER TO postfix;
CREATE TABLE mailbox (
username character varying(255) DEFAULT ''::character varying NOT NULL,
password character varying(255) DEFAULT ''::character varying NOT NULL,
name character varying(255) DEFAULT ''::character varying NOT NULL,
maildir character varying(255) DEFAULT ''::character varying NOT NULL,
quota integer DEFAULT 0 NOT NULL,
domain character varying(255) DEFAULT ''::character varying NOT NULL,
created time with time zone DEFAULT now() NOT NULL,
modified time with time zone DEFAULT now() NOT NULL,
active integer DEFAULT 1 NOT NULL
);
ALTER TABLE public.mailbox OWNER TO postfix;
INSERT INTO domain (domain, description, aliases, mailboxes, maxquota, transport, backupmx, created, modified, active) VALUES ('meudominio.com.br', 'Domínio Oficial do meu site', 0, 0, 0, NULL, 0, '23:11:33.126422-03', '23:11:33.126422-03', 1);
INSERT INTO aliases (alias, address, domain, created, modified, active) VALUES ('isaias', 'isaias@outrodominio.com.br', '', '11:54:33.577091-03', '11:54:33.577091-03', 1);
INSERT INTO mailbox (username, password, name, maildir, quota, domain, created, modified, active) VALUES ('user@meudominio.com.br', '$1$Uf8bM$5gO/4Dokk34vYECv1.HGa1', '', 'user/', 0, '', '23:51:53.816966-03', '23:51:53.816966-03', 1);
INSERT INTO mailbox (username, password, name, maildir, quota, domain, created, modified, active) VALUES ('admin@meudominio.com.br', '$1$Uf8bM$5gO/4Dokk34vYECv1.HGa1', 'Mailbox User', 'admin/', 0, '', '23:11:33.126422-03', '23:11:33.126422-03', 1);
INSERT INTO mailbox (username, password, name, maildir, quota, domain, created, modified, active) VALUES ('outrouser@meudominio.com.br', '', 'Mailbox User', 'roundcube/', 0, '$1$Uf8bM$5gO/4Dokk34vYECv1.HGa1', '23:11:33.126422-03', '23:11:33.126422-03', 1);
ALTER TABLE ONLY aliases
ADD CONSTRAINT aliases_pkey PRIMARY KEY (address);
ALTER TABLE ONLY domain
ADD CONSTRAINT domain_pkey PRIMARY KEY (domain);
ALTER TABLE ONLY mailbox
ADD CONSTRAINT mailbox_pkey PRIMARY KEY (username);
REVOKE ALL ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON SCHEMA public FROM postgres;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO PUBLIC;
REVOKE ALL ON TABLE aliases FROM PUBLIC;
REVOKE ALL ON TABLE aliases FROM postfix;
GRANT ALL ON TABLE aliases TO postfix;
REVOKE ALL ON TABLE domain FROM PUBLIC;
REVOKE ALL ON TABLE domain FROM postfix;
GRANT ALL ON TABLE domain TO postfix;
REVOKE ALL ON TABLE mailbox FROM PUBLIC;
REVOKE ALL ON TABLE mailbox FROM postfix;
GRANT ALL ON TABLE mailbox TO postfix;
ATENÇÃO:
- O Postfix trabalha com dois tipos de 'caixas' de e-mail: mbox e Maildir. No primeiro tipo, mbox, ele cria um arquivo único, no spool de emails do postfix (geralmente em '/var/mail' ou '/var/spool/mail'), com o nome do usuário. No segundo tipo, ele cria uma estrutura num diretório, no qual ficarão os e-mails. A distinção que define o uso de um estilo ou de outro é o caractere '/' no final da string que inserimos no banco de dados acima (tabela mailbox). Se o endereço do diretório estiver sem essa barra final, os mails vão para o arquivo '/var/mail/nome_do_usuario'. Do contrário, vão para a árvore de diretórios: <raiz do diretório virtual>/nome_especificado/. Em nosso caso, será o '/var/vusers' como diretório raiz para os nossos usuários.
- Não coloque um domínio virtual listado na variável mydestination.
- No arquivo de alias, temos um mapeamento de um alias (virtual) para um usuário/endereço (real). Não misture, para não obter resultados inesperados.
- Neste artigo, as senhas inseridas para os usuários correspondem ao código encriptado da senha 'teste'. Você pode usar o comando 'authpasswd' para gerar outras chave e armazená-las na tabela mailbox de usuários no postgres:
# authpasswd
Password:
Reenter password:
$1$skrcM$z1Ql3ycdJv.ZieQ8ywYUS0
Ok, ajustados nossos registros no PostgreSQL e configurado o postfix para acessar os dados no bd, vamos criar os diretórios de email.
Crie o diretório /var/vusers (usuário:grupo = postfix:postfix).
# mkdir /var/vusers
Agora, crie as mailboxes dos dois usuários-exemplo do script sql:
# maildirmake /home/postfix/Maildir/user
# maildirmake /home/postfix/Maildir/admin
# chown -R postfix:postfix /home/postfix
Ok, agora vamos reiniciar os serviços:
# /etc/init.d/postfix reload
# /etc/init.d/courier-imap restart
Se o imap subir, ótimo, é hora de testar. Se você encontrar o seguinte erro:
Starting Courier IMAP-SSL server:/etc/init.d/courier-imap-ssl:
xmalloc: ../bash/variables.c:3095: cannot allocate 1065 bytes (0 bytes allocated)
Bem, é um erro novo, creio, o qual encontrei na versão Debian 64 bits. Como eu já tinha instalado em 32 bits, resolvi reinstalar o sistema (que era uma versão básica, somente para servidor), e usar 32 mesmo. Salvei os arquivos de configuração e mandei bala. Nessa versão, funcionou tudo, e o imap subiu redondo.
Bem, uma vez que o courier-imap estiver ativo, vamos testar a autenticação do imap:
# telnet 0 143
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=CRAM-MD5 AUTH=CRAM-SHA1 AUTH=CRAM-SHA256 IDLE ACL ACL2=UNION STARTTLS] Courier-IMAP ready. Copyright 1998-2008 Double Precision, Inc. See COPYING for distribution information.
0
login user@meudominio.com.br teste
0 OK LOGIN Ok.
0
logout
* BYE Courier-IMAP server shutting down
0 OK LOGOUT completed
Nesse caso o login foi bem sucedido. Vamos dar um exemplo de falha:
# telnet 0 143
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=CRAM-MD5 AUTH=CRAM-SHA1 AUTH=CRAM-SHA256 IDLE ACL ACL2=UNION STARTTLS] Courier-IMAP ready. Copyright 1998-2008 Double Precision, Inc. See COPYING for distribution information.
0
login user
0 NO Error in IMAP command received by server. <- Falha
0
logout
* BYE Courier-IMAP server shutting down
0 OK LOGOUT completed
IMPORTANTE:
1) Digitar o '0' no início das linhas para os comandos telnet para o imap (143).
2) Colocar no campo 'username' da tabela 'mailbox' do banco de dados 'mail' o nome completo, com @ e nome de domínio, como na tabela do postgre, a menos que você saiba configurar diferente.
3) Em caso de falhas de autenticação (penei muito com isso, até entender o esquema), use os arquivos de log (/var/log/syslog) como geradores de pistas. Habilite o modo debug (DEBUG_LOGIN=2 no arquivo '/etc/courier/authdaemonrc'). Pode usar também os arquivos '/var/log/mail.err', '/var/log/auth.log'.
Agora vamos testar a autenticação pop:
# telnet meudominio.com.br 110
Trying 45.246.678.123...
Connected to urano.
Escape character is '^]'.
+OK Hello there.
user user@meudominio.com.br
+OK Password required.
pass teste
+OK logged in.
quit
+OK Bye-bye.
Connection closed by foreign host.
Novamente, se houverem erros, dê uma olhada nos logs.
Faça vários testes, envie e-mails do seu servidor para fora (yahoo, gmail) e vice-versa e verifique se os e-mails estão sendo gravados nos respectivos maildirs. Utilize um 'ls -laR maildir' para checar se está tudo certo. Isso é importante porque o conteúdo desses diretórios é utilizado pelo imap para permitir ao roudcube gerenciar as mensagens. No final, não se esqueça de definir:
DEBUG_LOGIN=0
em /etc/courier/authdaemonrc. É importante o sistema de e-mail estar funcionando integralmente nessa fase, para uma instalação rápida e fácil do roundcube.