Archive for category Software Livre

Slides da minha palestra sobre Arquitetura de serviços de diretório com OpenLDAP pela Locaweb na LinuxCon 2010

, , , , , , , , ,

No Comments

Efetuando Cache de suas consultas LDAP

Há bastante tempo tenho trabalhado com serviço de diretório, especificamente com o OpenLDAP. Quando criando um novo ambiente, no geral minhas preocupações são: redundância e performance das aplicações. Pensando nisso, sempre procurei manter meu backup em dia e diversos slaves como forma de redundância e para permitir que as aplicações não sofram com problemas de performance for falta de ajustes finos, latência de rede, inacessibilidade ou por questões relacionadas à escalabilidade.

De fato, essa fórmula sempre funcionou como esperado, mas o excesso de réplicas torna o ambiente praticamente inadministrável conforme o número de Slaves aumenta, e é óbvio que queremos que nossa aplicação seja escalável. Em um modelo deste tipo, escalar a aplicação também significa precisar de mais slaves.

A boa notícia é que o OpenLDAP possui um módulo chamado “pcache” que elimina esta necessidade absurda de milhões de réplicas dentro da sua estrutura.

O conceito é simples. Ao invés de replicar todo o diretório, o pcache armazena somente os resultados das pesquisas efetuadas e pelo tempo necessário. Uma consulta que não está em cache é respondida pelo Master (ou Slave, preferívelmente) e a que está em cache é respondida localmente.

Arquitetura com OpenLDAP Proxy Cache

A partir deste ponto, vou mostrar um exemplo de arquitetura física ignorando qualquer melhoria relacionada ao modelo utilizado dentro do diretório. Meu intuito é somente mostrar o funcionamento do “slapo-pcache”.

Exemplo simples de arquitetura :

text3215-7

Como é possível ver, existe a possibilidade de que a própria máquina de aplicação seja o cache. Desta forma a latência de rede já é eliminada pois a consulta é local. Digamos que é possível economizar alguns bons milisegundos (ou até segundos) para cada consulta efetuada. Obviamente, quando iniciar o serviço pela primeira vez, o seu diretório Slave vai receber uma carga maior, mas a curto prazo, essa carga deve diminuir. O Master por sua vez, será somente utilizado para gravações e algumas leituras.

A configuração do “slapo-pcache” é bastante simples, mas é necessário que você saiba exatamente todas os tipo de consultas que serão efetuadas no seu diretório. No geral, sempre sabemos quais queries serão efetuadas, salvo se seu diretório for aberto.

Instalação

A instalação é bem simples. Pode ser instalado através do gerenciador da sua distro, ou pelo conhecido trio “./configure”, “make”, “make install”.

Para o Red Hat, é necessário instalar o pacote openldap-servers-overlays e no caso de haver necessidade do compilação, são necessários os seguintes parâmetros “–backend-ldap” e “–overlay-pcache”.

Configuração

A configuração de um LDAP Cache é muito simples. A cada sessão, irei explicar qual é a função do ítem de configuração

slapd.conf

Primeiramente incluímos todos os “schemas” requeridos pelo diretório, pois caso não existirem, o OpenLDAP não consegue persistir o resultado das consultas, fazendo o cache ser ineficaz.

# Schema files
include      /etc/openldap/schema/core.schema
include      /etc/openldap/schema/corba.schema
include      /etc/openldap/schema/cosine.schema
include      /etc/openldap/schema/inetorgperson.schema
include      /etc/openldap/schema/misc.schema
include      /etc/openldap/schema/mail.schema
include      /etc/openldap/schema/nis.schema
include      /etc/openldap/schema/openldap.schema

É necessário carregar o módulo explicitamente. Em algumas distribuições é desnecessário fazer isso. Mas na dúvida, faça.

# modules
moduleload      pcache

Estes níveis de log, mostram sobre as consultas efetuadas no diretório. Para saber os outros níveis, verifique a documentação do OpenLDAP.

# log information
loglevel        stats stats2

Esta é a sessão relacionada aos backends necessários para efetuar o cache. Observe que o Backend primário utilizado aqui é o “ldap”, ou seja, a consulta feita no cache é repassada para as “uri” definidas. O “suffix” precisa ser o mesmo do seu diretório. O “rootdn” pode ser diferente.

database        ldap
suffix          "dc=mydomain,dc=com”
uri             “ldap://200.x.x.x ldap://200.x.x.y”
rootdn          "cn=manager,dc=mydomain,dc=com”

Aqui vemos a configuração do Cache. O Overlay pcache está sendo inicializado. Os valores do parâmetro proxycache são, respectivamente: tipo do backend; número de entradas no cache; número de attribute sets; número máximo de entradas; período de “consistency check”.

# slapo-pcache configuration
overlay         pcache
proxycache      bdb 100000 2 1000 100

Os “proxyAttrset”, são os attribute sets que serão retornados pelas consultas. No exemplo abaixo, minha consulta de número 0 retorna mailHost e rfc822MailAlias, enquanto minha consulta 1 retorna somente a existência de determinado attributo.
Estes “proxyAttrsets” serão utilizados pelas “proxyTemplates” a fim de consolidar o cache. Neles constam as templates das consultas que serão efetuadas, o id do attribute set e o TTL.

proxyAttrset    0 mailHost rfc822MailAlias
proxyAttrset    1 1.1
proxyTemplate   (&(uid=)(associatedDomain=)(mailHost=)) 0 3600
proxyTemplate   (&(uid=)(associatedDomain=)) 1 3600

E enfim, o tamanho total do cache (preferivelmente o mesmo do cache do overlay), o diretório onde será armazenado o cache e por último, os indexes.
Um ponto importante. Não abuse de indexes, eles são necessários, mas o excesso de índices inúteis podem gerar problemas de performance. Sempre olhe seus logs. Se faltar algum índice, constará em seus logs.

cachesize       100000
directory       /var/db/openldap-cache
index           uid,cn pres,eq
index           objectClass,associatedDomain,mailHost eq

A configuração do pcache é realmente simples. Uma vez que você sabe exatamente as queries que são feitas no seu diretório, seu cache será eficaz.
Outros tunings podem ser aplicados, mas não no slapd.conf, mas sim no DB_CONFIG no diretório de seu database.

Normalmente para um cache, costumo criar dois segmentos de memória para cache e um número maior de “lockers”, pois em ambientes de alto volume de consultas, um número baixo de “lockers” pode significar gargalo. Também deixo os transaction logs em auto-remove. Como trata-se de um cache, não existe utilidade nenhuma em preservá-los.

DB_CONFIG

set_flags DB_LOG_AUTOREMOVE
set_cachesize 0 2073741824 2
set_lk_max_locks 3000
set_lk_max_objects 1500
set_lk_max_lockers 1500

Basicamente, esta é uma configuração padrão para um cache. Como já dito, ele pode rodar diretamente e sua máquina de aplicação ou em separado mas fique atento para não confundir problemas de configuração nos “clients” com problemas de performance do cache. Um bom exemplo, é utilizar seu “base dn” diferente do que foi configurado no server. Todos os índices criados, só funcionarão corretamente se as consultas forem feitas na base correta, caso contrário, você terá problemas gigantes com deadlocks.

Espero que este artigo possa ajudar quando for arquitetar sua próxima instalação. Claro que em ambientes maiores será necessário um número maior de caches e slaves, bem como a redundância de seu Master. Em meu próximo POST sobre LDAP, mostrarei como montar um ambiente com Hot Standby. Até!

, , , ,

3 Comments

Escrevendo um servidor HTTPS em Python

Dia desses precisei de um servidor HTTP para implementar algumas funcionalidades que eu precisava. Verificando os que já conhecia, percebi que seria bastente trabalhoso escrever módulos para WebServers como o Lighttpd, Apache ou o Nginx, mesmo apesar deste último ser um pouco mais fácil. Procurei então alguma linguagem interpretada para fazer o que eu precisava.

Pesquisei bastante em Ruby como o fazê-lo, mas não me senti “seduzido” pelas Libs de Ruby que construiam HTTP Servers, e também há aquela velha questão do Ruby ser mono thread. Pesquisei algo relacionado ao Perl mas infelizmente é uma linguagem que não me sinto à vontade para fazer alguma coisa, e sinceramente não gosto muito. No final, acabei escolhendo escrevê-lo em Python, pois devo confessar que existem muitas facilidades devido milhares de modulos embutidos na linguagem em sua instalação padrão.

Uma delas é o BaseHTTPServer, que constrói facilmente um servidor HTTP básico mas extermamente extensível.

O intuito deste POST é mostrar a facilidade com que se constrói um HTTPServer em Python e ainda por cima, adicionar a camada SSL por cima dele.

Escrevendo seu HTTP Server básico com SSL

user@host ~$ vim secureServer.py
 
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
import ssl
 
class classHandler(BaseHTTPRequestHandler): pass
 
server_addr = (127.0.0.1, 443)
httpd = HTTPServer(server_addr, classHandler)
httpd.socket = ssl.wrap_socket(httpd.socket,  \
    certfile='cert.pem', server_side=True, \
    ssl_version=ssl.PROTOCOL_SSLv23)
 
while True:
        httpd.handle_request()

Viram que simples? Mas para este pequeno protótipo funcionar corretamente, é preciso criar um certificado SSL. Como é somente teste, vou criar um “self signed”.

user@host ~$ openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
 
Generating a 1024 bit RSA private key
..........................................................++++++
.......................++++++
writing new private key to 'cert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:BR
State or Province Name (full name) [Some-State]:São Paulo
Locality Name (eg, city) []:SP
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Leandro LTDA
Organizational Unit Name (eg, section) []:Mail
Common Name (eg, YOUR name) []:localhost
Email Address []:leandro@localhost

Pronto, agora é só testar com o openssl client.

user@host ~$ openssl s_client -host localhost -port 443
CONNECTED(00000003)
depth=0 /C=BR/ST=S\xC3\xA3o Paulo/L=SP/O=Leandro LTDA/OU=Mail/CN=localhost/emailAddress=leandro@localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=BR/ST=S\xC3\xA3o Paulo/L=SP/O=Leandro LTDA/OU=Mail/CN=localhost/emailAddress=leandro@localhost
verify return:1
---
Certificate chain
 0 s:/C=BR/ST=S\xC3\xA3o Paulo/L=SP/O=Leandro LTDA/OU=Mail/CN=localhost/emailAddress=leandro@localhost
   i:/C=BR/ST=S\xC3\xA3o Paulo/L=SP/O=Leandro LTDA/OU=Mail/CN=localhost/emailAddress=leandro@localhost
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDijCCAvOgAwIBAgIJAKY1XzcnjUW3MA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
VQQGEwJCUjETMBEGA1UECBQKU8OjbyBQYXVsbzELMAkGA1UEBxMCU1AxFTATBgNV
BAoTDExlYW5kcm8gTFREQTENMAsGA1UECxMETWFpbDESMBAGA1UEAxMJbG9jYWxo
b3N0MSAwHgYJKoZIhvcNAQkBFhFsZWFuZHJvQGxvY2FsaG9zdDAeFw0xMDAxMjEw
MTQ0MThaFw0xMTAxMjEwMTQ0MThaMIGLMQswCQYDVQQGEwJCUjETMBEGA1UECBQK
U8OjbyBQYXVsbzELMAkGA1UEBxMCU1AxFTATBgNVBAoTDExlYW5kcm8gTFREQTEN
MAsGA1UECxMETWFpbDESMBAGA1UEAxMJbG9jYWxob3N0MSAwHgYJKoZIhvcNAQkB
FhFsZWFuZHJvQGxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
yCX09Doe3bfFwrmGjAA3cDOUC47vuOVUkWzlnkX2e7nWN7J13amFHtBFXG2YunEs
wPEm5VZMMtjq5fhmKdcw+y6U2Lf6iS1Q5vEutuY/L2XbHlzctMFbasqkuVO8H0oB
Lqg9zTuRfx/BJ7BmhrWZMKYMYbP/PbFGejMrhMUzcp0CAwEAAaOB8zCB8DAdBgNV
HQ4EFgQU6s23dwSaSIO2CRXnzSqRCfbJLyQwgcAGA1UdIwSBuDCBtYAU6s23dwSa
SIO2CRXnzSqRCfbJLyShgZGkgY4wgYsxCzAJBgNVBAYTAkJSMRMwEQYDVQQIFApT
w6NvIFBhdWxvMQswCQYDVQQHEwJTUDEVMBMGA1UEChMMTGVhbmRybyBMVERBMQ0w
CwYDVQQLEwRNYWlsMRIwEAYDVQQDEwlsb2NhbGhvc3QxIDAeBgkqhkiG9w0BCQEW
EWxlYW5kcm9AbG9jYWxob3N0ggkApjVfNyeNRbcwDAYDVR0TBAUwAwEB/zANBgkq
hkiG9w0BAQUFAAOBgQCl6+gzbq4gQfE/W5NYCX1S/bsNFaGaDoSr8nzibF++3NeI
CjgtDciimmSb330AJE1GSC9xqvLF86LV2wvIw3W6eR7+YYgGfoPv2eOnGO/djsKM
/0MvPoUjJPfP9k2RftyYQMaKPMXGtGGCWnlm6bUade9wq4BdBYkKRp42Rb83qQ==
-----END CERTIFICATE-----
subject=/C=BR/ST=S\xC3\xA3o Paulo/L=SP/O=Leandro LTDA/OU=Mail/CN=localhost/emailAddress=leandro@localhost
issuer=/C=BR/ST=S\xC3\xA3o Paulo/L=SP/O=Leandro LTDA/OU=Mail/CN=localhost/emailAddress=leandro@localhost
---
No client certificate CA names sent
---
SSL handshake has read 1072 bytes and written 316 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 1024 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: 0DF03B0D70244E8A4E357504AEB010FCCBF02977E1B530FC8E2F47057AB5D949
    Session-ID-ctx:
    Master-Key: 5E124A87C6BAE38AFF3CA2F78EBDB9A989E988B005AB596D7FCF7D93B48D7FD1C4F1FCAEA325DC48137D0EBC23DDBB4A
    Key-Arg   : None
    Start Time: 1264038343
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

Pronto, seu HTTPServer com SSL está funcionando. Obviamente, nenhum dos métodos está sendo implementado, mas isto é facilmente de se fazer. O BaseHTTPServer, por padrão não implementa nenhum método, sendo assim, para facilitar você pode extender o SimpleHTTPServer que já implementa os métodos do_GET e do_HEAD, a única coisa que é necessário fazer é implementar os outros método desejado, como do_POST, do_PUT, do_DELETE, etc. Verifique a documentação!

É isso aí galera!!

Referencias

http://docs.python.org/library/ssl.html
http://docs.python.org/library/basehttpserver.html

, , ,

No Comments

Replicação Multi-Master no OpenLDAP 2.4

As versões mais antigas, era possível efetuar a replicação somente via slurpd e na configuração Master para N Slaves. Com o lançamento da versão 2.4, o OpenLDAP passou a proporcionar diversas formas de replicação, como Mirror Mode, N-Way Multimaster e ainda Master-Slave.

Este pequeno tutorial, explica de forma rápida a configuração para Alta-disponibilidade (N-Way Multimaster) para OpenLDAP 2.4, que sempre foi uma das principais solicitações da comunidade.

Configurando do Slapd

Fazer o setup manual do slapd.conf, ex:

# schemas
include "/usr/loca/etc/openldap/schema/core.schema"
include "/usr/loca/etc/openldap/schema/corba.schema"
include "/usr/loca/etc/openldap/schema/cosine.schema"
include "/usr/loca/etc/openldap/schema/inetorgperson.schema"
include "/usr/loca/etc/openldap/schema/misc.schema"
include "/usr/loca/etc/openldap/schema/nis.schema"
include "/usr/loca/etc/openldap/schema/openldap.schema"
 
moduleload back_bdb
 
database bdb
suffix   "ou=Mail, o=Teste"
rootdn   "cn=root, ou=Mail, o=Teste"
rootpw
directory /var/db/openldap-data
 
# Indexes
index objectClass eq
index cn,uid,associatedDomain eq

Feita a configuração básica, é necessário converter o arquivo de configuração para o novo “estilo” de configuração para o OpenLDAP 2.4. Isto pode ser feito com o commando slaptest.

root# mkdir /usr/local/etc/openldap/slapd.d/
root# slaptest -f /usr/local/etc/openldap/slapd.conf -F /usr/local/etc/openldap/slapd.d/

Serão gerados os arquivos de configuração da versão 2.4 do OpenLDAP.

É necessário também alterar os seguintes arquivos adicionando os seguintes atributos (em todos os nós):

Em /usr/local/etc/openldap/slapd.d/cn=config.ldif:

# alterar o número para cada nó
olcServerID: 1

e

Em /usr/local/etc/openldap/slapd.d/cn=config/olcDatabase={0}config.ldif:

olcRootPW: <senha>

A partir daí, o serviço deve ser iniciado.

Configurando a replicação

Com o novo tipo de configuração, tudo deve ser feito via arquivos LDIF e alterados na database cn=config do OpenLDAP, via ldapmodify.

Crie o um arquivo setup.ldif com o seguinte conteúdo:

dn: cn=config
changetype: modify
replace: olcServerID
olcServerID: 1 ldap://<server1>
olcServerID: 2 ldap://<server2>
dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
 
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=ldap://<server1> binddn="cn=config" bindmethod=simple
credentials=secret searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
olcSyncRepl: rid=002 provider=ldap://<server2> binddn="cn=config" bindmethod=simple
credentials=secret searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
-
add: olcMirrorMode
olcMirrorMode: TRUE

Adicionar ao diretório

root# ldapmodify -x -D"cn=config" -w  -f setup.ldif

Isto fará a replicação da database “cn=config”. Fazer o mesmo processo no LDAP SLAVE.
Replicando a base de dados “ou=Mail,o=Teste”.

A base de dados cn=config, é importante pois desta forma, todos os nós serão configurados automaticamente, quando for feito o setup para a replicação da base “ou=Mail,o=Teste”, que possui os dados importantes.

Criar um arquivos data.ldif:

dn: olcDatabase={1}bdb,cn=config
changetype: modify
add: olcMirrorMode:
olcMirrorMode: TURE
add: olcLimits
olcLimits: dn.exact="cn=root,ou=Mail,o=Teste" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
#replica 1
add: olcSyncRepl
olcSyncRepl: rid=003 provider=ldap://<server1> binddn="cn=root,ou=Mail,o=Teste"
bindmethod=sinple credentials=secret searchbase="ou=Mail,o=Teste"
type=refreshOnly interval=00:00:00:10 retry="5 5 300 5" timeout=1
#replica 2
add: olcSyncRepl
olcSyncRepl: rid=004 provider=ldap://<server2> binddn="cn=root,ou=Mail,o=Teste"
bindmethod=sinple credentials=secret searchbase="ou=Mail,o=Teste"
type=refreshOnly interval=00:00:00:10 retry="5 5 300 5" timeout=1
 
# Habilita o syncprov
dn: olcOverlay=syncprov, olcDatabase={1}bdb,cn=config
changetype: add
objectClass: olcOverLayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov

Feito isso, adicionar os dados no Diretório:

root# ldapmodify -x -D"cn=config" -w  -f data.ldif

Pronto! Está funcionando!

No Comments

IMAP Proxy

IMAP Proxy

Parece óbvio, mas poucos se lembram da possibilidade, de “cachear” as conexões IMAP em uma única, a fim de diminuir as requisições IMAP vindas por HTTP (webmails, em específico), pois como o HTTP é um protocolo “stateless”, ou seja, não mantém uma conexão persistente e automaticamente cada REQUEST é uma nova conexão IMAP em seu servidor.

Para resolver isto, existe a solução de Proxy IMAP. Existem alguns software para isto, mas no momento estou usando o “imapproxy” que pode ser baixado no site do projeto, www.imapproxy.org.

O software é extremamente simples e intuitivo, não precisando de mais de 10 minutos pra entender e colocar no ar.

A característica principal do software é manter uma conexão única por usuário. Ele mantém as credenciais enviadas pelo client cacheadas e uma conexão persistente com o servidor IMAP.

Instalação

Baixe o software no site do projeto:

1
user ~/ $ wget http://www.imapproxy.org/downloads/up-imapproxy-1.2.6.tar.gz

O imapproxy depende de ncurses para compilar, então, baixe-o e instale-o!

Compile-o e instale-o, ou então busque o pacote da sua distro.

Para os Slackers de plantão:

1
2
3
4
5
user :~$ tar xvzf up-imapproxy-1.2.6.tar.gz
user :~$ cd up-imapproxy-1.2.6/
user :~/up-imapproxy-1.2.6$ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
user :~/up-imapproxy-1.2.6$ make
user :~/up-imapproxy-1.2.6$ sudo make install

Instalado, a configuração é extremamente simples, mas vou explicar algumas delas.
O arquivo de configuração de acordo com nossa instalação estará em /etc/imapproxy.conf.

1
2
3
4
5
6
7
server_hostname 200.x.x.x  # Este será o servidor de destino
cache_size 100 # Número de conexões máximas que poderão ser "proxyadas"
listen_port 143 # Onde o imapproxy escutará as conexões
# listen_address 127.0.0.1 # Neste caso se indefinido (comentado), irá escutar todas os endereços.
server_port 1143 # Porta do servidor de destino, neste caso, estou usando o IMAP em uma porta diferente.
cache_expiration_time 300 # Tempo do cache em segundos
proc_username mail # Usuário que irá rodar o processo do imapproxy

Para configuração básica (provavelmente a maioria dos casos), estes parâmetros serão os utilizados, mas existem alguns poucos a mais que poderão ser alterados de acordo com a necessidade.

Para iniciar o serviço é somente executar o daemon:

1
user ~$ sudo imapproxy

Pronto, seu IMAP Proxy está no ar!

1 Comment

Os atuais MDAs e as linguagens de filtragem de e-mail (parte 3)

sieve375x375Continuando minha série de Posts sobre linguagens de filtragem de e-mail, escrevo enfim, sobre o Sieve, que é de longe, a mais importante das linguagens de filtragem, devido sua simplicidade, facilidade de aprendizado, e por ser um padrão de linguagem para filtragem de correio.


Assim como nos outros Posts sobre linguagens de filtragem de correio, este último também não tem intenção nenhuma de ensinar como configurá-los em seus servidores, mas sim, falar sobre a linguagem e mostrar alguns exemplos de scripts.


Sieve: Uma linguagem para filtragem de correio

Sieve é uma linguagem de scripts para filtragem de correio eletrônico que, dentre todas conhecidas, é a única que segue um padrão de implementação. Este padrão foi inicialmente definido na RFC3028 e atualizado pelas RFCs 5228, 5229 e 5429, ou seja, qualquer software de correio, pode criar sua própria implementação, e o mesmo script DEVE funcionar em qualquer um destes servidores.


Existem diversas implementações do padrão, mas as mais conhecidas pela comunidade Open-Source são sem dúvida, as implementações feitas pelo Cyrus IMAP Server e pelo Dovecot. Este segundo, usa o mesmo interpretador Sieve do Cyrus IMAP. A partir da versão 1.2 (ainda em Release Candidate) do Dovecot, o interpretador Sieve foi totalmente re-escrito.


A linguagem Sieve suporta a maioria das features que as outras linguagens já mostradas aqui, com uma exceção, que é a execução de comandos de sistema (vide Courier maildropfilter). O fato de não existir esta feature não deixa a linguagem mais fraca, mas sim mais segura, pois uma das razões que contribuiram para criação do padrão, é definir uma forma segura da manipulação de scripts pelo próprio usuário.


Sieve Scripts

Agora que já sabemos um pouco sobre a linguagem Sieve, vamos conhecer o que é possível fazer, e como podemos usar a linguagem Sieve para nos auxiliar.

A maioria das features do Sieve, podem ser incluídas em seu script através do comando “require”, assim, é possível que você carregue somente as funções que vai utilizar, agilizando o parsing do script.

Outro ponto importante é que a linguagem suporta internacionalização, ou seja, você pode escrever seus scripts em UTF-8. Nota que também existem extensões para o Sieve que também possuem RFCs relacionadas. Aqui, falaremos sobre algumas extensões, como “fileinto”, “vacation” e “regex”.


Exemplos de scripts:

Consideremos nossa mensagem de correio:


From: "Spammer"<spammer@viagra.com>
Date: Sun, Apr 19 2009  18:36:49 -0300
X-Spam-Flag: Yes
Subject: [ SPAM ] Testando um script Sieve
 
Que tal testarmos alguns Sieve Scripts?


Vamos testar as seguintes simples condições, que são plausíveis no dia-a-dia:


  1. Verificar se a mensagem tem a tag [ SPAM ] e escolher uma ação a tomar;
  2. Auto-resposta;
  3. Verificar tamanho da mensagem e escolher uma ação a tomar;
  4. Verificar o remetente da mensagem e escolher uma ação a tomar;


1. Verificar se a mensagem tem a tag [ SPAM ] e escolher uma ação a tomar (descartar ou movê-la para uma outra pasta);

O primeiro passo é carregar os plugins a serem usados:


require [“fileinto”, “regex”];

Logo após, verificamos se a mensagem pussui tag SPAM ou o header “X-Spam-Flag: Yes”. Exemplificarei os dois casos:


Pelo header:


if header :contains “X-Spam-Flag” “Yes” {
    # move para a pasta SPAM
    fileinto “SPAM”;
    discard;
}


Pelo Assunto via regex:


if header :regex “subject” “\[(.)?SPAM(.)?\]{
    # neste exemplo, quero descartar a mensagem.
    discard;
}


2. Auto-resposta de Férias

Novamente, o primeiro passo é carregar os plugins:


require [“fileinto”, “vacation”, “regex”];


Caso a mensagem for da lista “Postfix-BR”, não enviaremos a auto-resposta, mas armazenaremos em uma pasta específica.


if header :regex “list-id” “Grupo.*Postfix.*Brasil” {
    fileinto "Listas";
    stop;
}
else {
    # não enviará novamente para o mesmo remetente mais de uma vez
    # até que se cumpra o período de 30 dias de férias.
    # Seu script tem que estar em UTF-8, por causa da acentuação
         vacation :days 30
                 “Estou de férias. Envie novamente para fulano@ciclano.com”;
}


Auto-resposta sempre que receber um e-mail:

vacation :subject “Recebido” “Sua mensagem foi recebida com sucesso”;


3. Verificar tamanho da mensagem e escolher uma ação a tomar


require “fileinto”;
 
if size :over 5M {
    # salva na pasta BigMessages
    fileinto “BigMessages”;
}


4. Verificar o remetente da mensagem e escolher uma ação a tomar

Neste exemplo, todas as mensagens vindas de “spammer@viagra.com” ou “Spammer” recebam a flag “Junk” e também a flag \\Deleted:


require "imapflags";
 
if addres :matches “from” “spammer@viagra.com” {
    setflag "\\Deleted";
    addflag “Junk”;
}


ou


require "imapflags";
 
if header :matches “from” “Spammer” {
    setflag "\\Deleted";
    addflag “Junk”;
}


Enfim, estes foram alguns simplíssimos exemplos de uso do Sieve. Espero que este pequeno Post te abra o “apetite” por esta pequena, mas eficiente linguagem de filtragem, que cresce a cada dia mais, e em breve, prevalecerá na maioria dos MTAs conhecidos do mercado.


Em breve, farei outro Post falando sobre o Dovecot ManageSieve, que é uma ótima ferramenta para gerenciar scripts Sieve e também detalharei como implementá-lo.


Até lá!


Referências

http://wiki.dovecot.org/LDA/Sieve: http://wiki.dovecot.org/LDA/Sieve

RFCs 3028, 5228, 5229 e 5429: http://ietfreport.isoc.org/rfc/rfc3028.txt, http://ietfreport.isoc.org/rfc/rfc5228.txt, http://ietfreport.isoc.org/rfc/rfc5229.txt, http://ietfreport.isoc.org/rfc/rfc5429.txt

No Comments

Postfix + SASL2 + Courier-IMAP + QUOTA + PostgreSQL HOW-TO (deprecated)

Calma lá! Eu concordo que colocar que algo é depreciado já no título é um tanto quanto bizarro, mas acreditem, este artigo é.

Escrevi este artigo em 2004 e após um crash no servidor onde estava hospedado, este artigo ficou perdido  por um bom tempo. Poisé, e hoje, buscando por este artigo, o encontrei na íntegra no site Extmail.org. Fiquei bastante feliz, mas ao reler, vi que uma série de coisas não se compatibilizam com o que penso hoje.

Apesar disso, acho importante que esteja no ar pois muitas coisas deste artigo ainda se aplicam na prática, lógico que com algumas atualizações de software.

Acho importante também que eu esclareça as coisas que não acredito mais em relação a implementação que descrevi no artigo, e caberá a você pensar se vale a pena utilizá-lo.

1. Não acredito no uso de banco de dados relacionais como consulta para o Postfix. Bancos de dados relacionais são mais lentos, criam uma dependência perigosa e desnecessária externa e de forma mais clara, foram concebidos com outro propósito, não este. Use LDAP no lugar. É simples, rápido e existe para justamente este fim.

2. Apesar de ainda  considerar o Courier-IMAP uma boa solução, hoje prefiro utilizar o Dovecot como servidor de POP3 e IMAP. É extremamente mais rápido, muito mais flexível e trabalha tanto com MBOX quanto com MAILDIR, fora a questão dos plugins disponíveis (LDA e Sieve, por exemplo) e sua implementação de autenticação SASL que é facilmente integrada com o Postfix, sem necessidades de Patches.

3. SASL. Expliquei em poucas palavras no tópico 2. Creio que a explicação seja suficiente.

4. Sobre a questão da Quota, não sou a favor de adicionar Patches de terceiros no Postfix. Hoje já existem diversas opções para implementar este comportamento. Novamente, o dovecot LDA te fornece esta funcionalidade.

Por ora, acredito que estes ítens já são claro o suficiente e mostram exatamente minha opinião hoje, mas muitos por algum motivo precisam utilizar o conjunto que entitula este Post. Sendo assim, boa leitura!

— Artigo publicado em 26/04/2004, linkado em http://www.postfix.org/non-english.html (quebrado) —

Postfix + SASL2 + Courier-IMAP + QUOTA + PostgreSQL HOW-TO

Este HOW-TO Foi escrito para auxiliar os Administradores que necessitam instalar um mailserver com suporte a domínios virtuais. Decidi usar o PostgreSQL como Banco de dados, pois este agrega uma série de funções mais complexas, e pensando que a instalação do servidor não é a única parte do processo. Talvez o administrador não queira usar  somente um gerenciador de  Domínios virtuais, e sim, fazer o controle do seu provedor inteiro dentro do PostgreSQL, via seu próprio “ISP Manager”. Lógicamente, é necessário uma máquina bem parruda para faze-lo, mas acredito que seja uma boa solução no que diz respeito à domínios virtuais.

Infelizmente, ainda não pude adicionar ao HOW-TO, nada relacionado à filtragem de mensagens, pois o maildrop não dá suporte ao PostgreSQL.
Consta também neste HOW-TO a implementação de soft quota para controle das caixas postais. O controle é feito pelo próprio postfix, mas necessita a aplicação de um patch.

Para Administração simples dos domínios, iniciei o desenvolvimento do Post-MailAdmin, que é baseado no ótimo PostfixAdmin, que gerencia os domínios virtuais no MySQL.

Iniciando o Processo

Instale o PostgreSQL (Faça download da ultima versão, ou baixe para sua distribuição)
Mais informações sobre o PostgreSQL aqui:
Baixe o cyrus-sasl e o patch para Crypt passwords.

O programa:

ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/

O patch

http://frost.ath.cx/software/cyrus-sasl-patches/

Descompacte o software, aplique o Patch, compile e instale o programa:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[ root@server/~] # tar xvzf cyrus-sasl-2.*.*.tar.gz
[ root@server/~] # cd cyrus-sasl-2.*.*/
[ root@server/~] # patch -p0 &lt;../cyrus-sasl-2.1.17-checkpw.c.patch
[ root@server/~] # ./configure --enable-login --enable-plain --enable-sql --with-pgsql=PATH-PARA-O-PGSQL
[ root@server/~] # make
[ root@server/~] # make install
[ root@server/~] # ln -s /usr/local/lib/sasl2 /usr/lib/sasl2
 
# *** Não deixe de fazer isto, pois o cyrus-sasl não dá suporte à passwords crypt . Se está usando o sasl da sua distribuição, remova-o e instale a partir dos fontes***
 
# Crie o arquivo /usr/lib/sasl2/smtpd.conf com o seguinte conteúdo:
 
pwcheck_method: auxprop
auxprop_plugin: sql
allowanonymouslogin: no
allowplaintext: yes
mech_list: PLAIN LOGIN
srp_mda: md5
 
srvtab: /dev/null
opiekeys: /dev/null
 
password_format: crypt
 
sql_engine: pgsql
sql_user: postfix
sql_passwd: postfix
sql_hostnames: localhost
sql_database: postfix
sql_select: SELECT password FROM mailbox WHERE username = '%u@%r' AND domain = '%r';
 
# Baixe a ultima versão estável do Postfix:
 
[ root@server/~ ]# wget ftp://ftp.matrix.com.br/pub/postfix/official/postfix-*.tar.gz
[ root@server/~ ]# tar xvjf postfix-*.tar.gz

Baixe o patch para controle de quotas referente a versão que você baixou do postfix:
http://web.onda.com.br/nadal/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
[ root@server/~ ]# gunzip postfix-*-trash.patch.gz
[ root@server/~ ]# patch -p0 &lt;postfix-*-trash.patch
[ root@server/~ ]# cd postfix-*/
[ root@server/~ ]# make tidy
[ root@server/~ ]# make -f Makefile.init makefiles 'CCARGS=-DHAS_PGSQL -I/usr/local/pgsql/include -DUSE_SASL_AUTH -I/usr/local/include' 'AUXLIBS=-L/usr/local/pgsql/lib -lpq -L/usr/local/lib/sasl2 -lsasl2'
 
# (Altere o caminho dos headers e das libs conforme a sua instalação do postgre e sasl2)
 
[ root@server/~ ]# make
[ root@server/~ ]# make install  #Se houver algum erro relacionado à sasl2, coloque o path "/usr/lib" em /etc/ld.so.conf
 
# Inicie o PostgreSQL:
# Se for baseado no Red Hat:
 
[ root@server/~ ]# service postgresql start
[ root@server/~ ]# su - postgres
 
# Caso contrário:
 
[ root@server/~ ]# su - postgres
[ postgres@server/~ ]$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
[ postgres@server/~ ]$ postmaster -D /usr/local/pgsql/data &gt;postgresql.log 2&gt;&amp;1 &amp;
 
# Crie o usuário a database e o user postfix:
 
[ postgres@server/~ ]$ createdb postfix
[ postgres@server/~ ]$ createuser postfix
 
#Tabelas no PostgreSQL
 
[ postgres@server/~ ] $ psql postfix -U postfix
 
# Caso não logar, descomente no /usr/local/pgsql/data/pg_hba.conf a linha abaixo (use isto, somente se o BD postfix, for para uso exclusivo do usuário postfix, e só para localhost), pois assim localmente, o usuário postfix do PostgreSQL não precisa de senha:
 
# TYPE  DATABASE  IP_ADDRESS  MASK  AUTH_TYPE  AUTH_ARGUMENT
# local postfix seu_ip sua_mascara trust
 
# Outro detalhe, é habilitar o PostgreSQL a escutar os pedidos de conexão.
# Edite o postgresql.conf e habilite as linhas:
 
tcpip_socket = true
port = 5432
 
# Logue no Postgre, crie as tabelas e dê permissão.
 
[ postgres@server/~ ] $ psql postfix -U postfix
 
CREATE TABLE "admin" (
"username" character varying(255) NOT NULL,
"password" character varying(255) NOT NULL,
"created" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"modified" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"active" boolean default true,
Constraint "admin_key" Primary Key ("username")
);
 
GRANT ALL ON admin TO postfix;
 
CREATE TABLE "alias" (
"address" character varying(255) NOT NULL,
"goto" text NOT NULL,
"domain" character varying(255) NOT NULL,
"created" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"modified" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"active" boolean default true,
Constraint "alias_key" Primary Key ("address")
);
 
GRANT ALL ON alias TO postfix;
CREATE TABLE "domain" (
"domain" character varying(255) NOT NULL,
"description" character varying(255) NOT NULL,
"aliases" numeric(10,0) DEFAULT '0' NOT NULL,
"mailboxes" numeric(10,0) DEFAULT '0' NOT NULL,
"maxquota" numeric(10,0) DEFAULT '0' NOT NULL,
"created" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"modified" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"active" boolean default true,
Constraint "domain_key" Primary Key ("domain")
);
 
GRANT ALL ON domain TO postfix;
 
CREATE TABLE "domain_admins" (
"username" character varying(255) NOT NULL,
"domains" character varying(255) NOT NULL,
"created" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"active" boolean default true,
Constraint "domain_admins_key" Primary Key ("username")
);
 
GRANT ALL ON domain_admins TO postfix;
 
CREATE TABLE "mailbox" (
"username" character varying(255) NOT NULL,
"password" character varying(255) NOT NULL,
"name" character varying(255) NOT NULL,
"maildir" character varying(255) NOT NULL,
"quota" numeric(10,0) DEFAULT '0' NOT NULL,
"domain" character varying(255) NOT NULL,
"created" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"modified" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"active" boolean DEFAULT 't'::bool,
"home" character varying(255) DEFAULT '/var/spool/virtual/',
"uid" numeric(3,0) DEFAULT 200,
"gid" numeric(3,0) DEFAULT 200,
Constraint "mailbox_key" Primary Key ("username")
);
 
GRANT ALL ON mailbox TO postfix;
 
CREATE TABLE "vacation" (
"email" character varying(255) NOT NULL,
"subject" character varying(255) NOT NULL,
"body" text,
"cache" text NOT NULL,
"domain" character varying(255) NOT NULL,
"created" timestamp(13) with time zone DEFAULT '1999-04-23 01:05:06',
"active" boolean default true,
Constraint "vacation_key" Primary Key ("email")
);
 
GRANT ALL ON vacation TO postfix;
 
# De "q" para sair do psql
 
# Configuração do Postfix para utilizar usuários Virtuais.
# Lembre-se que esta configuração é para os usuários virtuais, seu postfix já tem que possuir as configurações default!
 
# Adicione ao /etc/passwd:
 
vuser:x:200:200::/var/spool/virtual:/bin/false
 
# Adicione ao /etc/group:
 
vgroup:x:200:
 
# Crie o diretório e dê permissão:
 
[ root@server/~ ]# mkdir /var/spool/virtual
[ root@server/~ ]# chown 200:200 /var/spool/virtual
 
# Crie os seguintes arquivos com os seguintes conteúdos:
 
# /etc/postfix/pgsql_virtual_domains_maps.cf
 
user = postfix
password = postfix
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and active = true
 
# ==========================
 
# /etc/postfix/pgsql_virtual_mailbox_maps.cf
 
user = postfix
password = postfix
dbname = postfix
table = mailbox
select_field = maildir
where_field = username
additional_conditions = and active = true
 
# ==========================
 
# /etc/postfix/pgsql_virtual_mailbox_size.cf
 
user = postfix
password = postfix
dbname = postfix
table = mailbox
select_field = quota
where_field = username
additional_conditions = and active = true
 
# ==========================
 
# /etc/postfix/pgsql_virtual_alias_maps.cf
 
user = postfix
password = postfix
dbname = postfix
table = alias
select_field = goto
where_field = address
additional_conditions = and active = true
 
# Edite o arquivo /etc/postfix/main.cf e adicione as seguintes configurações:
# Lembrando novamente que estou supondo que você já fez a configuração básica do mesmo.
 
# PGSQL
virtual_uid_maps = static:200
virtual_gid_maps = static:200
virtual_mailbox_base = /var/spool/virtual
virtual_mailbox_domains = pgsql:/etc/postfix/pgsql_virtual_domains_maps.cf
virtual_mailbox_maps = pgsql:/etc/postfix/pgsql_virtual_mailbox_maps.cf
virtual_alias_maps = pgsql:/etc/postfix/pgsql_virtual_alias_maps.cf
virtual_mailbox_limit = 51200000
virtual_transport = virtual
 
# SASL2
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated
reject_unauth_destination, permit_mynetworks
smtpd_sasl_application_name = smtpd
broken_sasl_auth_clients = yes
 
# QUOTA
virtual_mailbox_limit_inbox = no
virtual_mailbox_limit_maps = pgsql:/etc/postfix/pgsql_virtual_mailbox_size.cf
virtual_mailbox_limit_override = yes
virtual_maildir_extended = yes
virtual_create_maildirsize = yes
virtual_mailbox_limit = 100000000

Simples teste:

Primeiro insira alguma coisa nas tabelas

1
INSERT INTO mailbox (username,password,name,maildir,quota,domain) values ('teste@dominio.com.br','$1$Fi8IP53B$3yeGqD1Cnax.f.yAkLiAd1','name','teste@dominio.com.br/',1048576,'dominio.com.br');

Insira a senha criptografada!

A SENHA NESTE CASO É a palavra teste e quota é de 1MB

1
INSERT INTO domain (domain,description,aliases,mailboxes,maxquota) values ('dominio.com.br','Domínio Virtual',1,1,1);

Reinicie o Postfix:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[ root@server/~ ]# postfix stop; postfix start
# Dê um telnet no host:
 
[root@server~/]# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 server.domain.com.br ESMTP Postfix (2.1.0)
MAIL FROM: teste@dominio.com.br
250 Ok
RCPT TO: teste@dominio.com.br
250 Ok
DATA
354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;
teste
.
250 Ok: queued as 7B41F4665A
quit
221 Bye
Connection closed by foreign host.
[root@server~/]# cd /var/spool/virtual;ls -la
drwxr-xr-x   3   vuser  vgroup   4096 Abr 26 11:18 .
drwxr-xr-x   11  root  root    4096 Abr 26 10:44 ..
drwx------   5   vuser  vgroup   4096 Abr 26 11:18 teste@dominio.com.br
[root@server~/]#

Quando a mensagem chegar, será criado um arquivo chamado maildirsize dentro do diretório do usuário, que controlará a cota deste usuário virtual.

Courier-IMAP

Baixe o Courier-IMAP em http://www.courier-mta.org/download.php

Descompacte-o como usuário normal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
[ tanga_frouxa@server/~ ]$ tar xfjv courier-imap-3.0.3.20040424.tar.bz2
 
# Antes de iniciar o processo, certifique-se que existem os diretórios ou links /usr/include/pgsql e /usr/lib/pgsql, pois, se não existirem, pode acontecer de o courier-imap não ser compilado com suporte à PostgreSQL.
 
[ tanga_frouxa@server/~ ]$ ./configure --with-redhat --enable-workarounds-for-imap-client-bugs # O --with-redhat somente se vc está usando Red Hat linux.
[ tanga_frouxa@server/~ ]$ make
 
# E como root:
 
[ root@server/~ ]# make install
[ root@server/~ ]# make install-configure
 
#Configuração:
 
# /usr/lib/courier-imap/etc/authdaemonrc
 
authmodulelist="authpgsql authpam"
authmodulelistorig="authpgsql authpam"
daemons=5  # Aumente este valor caso tiver muitos "clientes IMAP"
version=""
authdaemonvar=/usr/lib/courier-imap/var/authdaemon
 
# /usr/lib/courier-imap/etc/authpgsqlrc
# É provável que ele exista com o nome de authpgsqlrc.dist.
 
PGSQL_HOST localhost
PGSQL_PORT 5432
PGSQL_USERNAME postfix
PGSQL_PASSWORD postfix
PGSQL_DATABASE postfix
PGSQL_USER_TABLE mailbox
PGSQL_CRYPT_PWFIELD password
PGSQL_UID_FIELD uid
PGSQL_GID_FIELD gid
PGSQL_LOGIN_FIELD username
PGSQL_HOME_FIELD home
PGSQL_NAME_FIELD name
PGSQL_MAILDIR_FIELD maildir
 
# Inicie o Courier-IMAP:
 
/usr/lib/courier-imap/libexec/imapd.rc start
 
# Dê um telnet no host:
 
[root@server~/]# telnet localhost 110
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK Hello there.
user teste@dominio.com.br
+OK Password required.
pass teste
+OK logged in.
list
+OK POP3 clients that break here, they violate STD53.
1 1051
2 442
3 505
4 13516
5 27389
.
quit
+OK Bye-bye.
Connection closed by foreign host.
[root@server~/]#

Pronto agora é só Instalar o Post-MailAdmin para adicionar e remover os usuários. Assim que possível, coloco a parte de anti-vírus no Postfix.

——————————————————————————–

Bibliografia

Postfix Website: http://www.postfix.org
Pelas quotas, agradeço à Marco Máximo pelo seu HOW-TO no Link http://www.linuxit.com.br/section-viewarticle-78.html
SASL2: http://www.gfxcafe.com/Mail%20Howto.htm / http://frost.ath.cx/software/cyrus-sasl-patches/

Autor Leandro Mendes - 26/04/2004
Atualizado em: 12/07/2004

No Comments

Dica rápida - Submission port no Postfix

<dica>

Como abrir a porta 587 para envio?

Bom, se a dúvida for só essa é simples. Edite o master.cf e adicione ao final do arquivo:

master.cf

1
2
# habilitando submission port respeitando RFC5068
submission    inet    n    -    n    -    -    smtpd

Se for só para habilitar a porta, está prontinho. É necessário reiniciar o Postfix.
Desta forma, as mesmas restrições existentes para a porta 25 serão “herdadas” por este novo serviço, mas isso não significa que não seja possível alterá-las.

Para fazer isto basta utilizar o parâmetro -o na configuração do serviço:

1
2
3
4
5
submission    inet    n    -    n    -    -    smtpd
    -o smtp_client_restrictions=permit_sasl_authenticated,check_policy_service=unix:privacy/policy,reject
    -o smtp_helo_restrictions=permit_sasl_authenticated,reject
    -o smtp_sender_restrictions=permit_sasl_authenticated,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining

(Este exemplo é hipotético, pode não funcionar no seu caso. Leia o README e o man necessário para configurar corretamente).

</dica>

Valeu!

No Comments

ifconfig, você ainda usa?

tapeUltimamente venho percebendo que algumas coisas que deveriam ser extintas, não são. Não tenho nada contra se manter coisas depreciadas por compatibilidade, mas definitivamente, as distribuições modernas deveriam abolir ferramentas como o ifconfig. Ok, pode me bater se quizer, mas o por que utilizar uma ferramenta depreciada e limitada, se você pode utilizar algo extremamente mais moderno?

Normalmente as pessoas insistem em se manter na tal da “zona de conforto”. Eu confesso que certamente sou um dos que por comodidade muitas vezes prefiro manter as coisas como estão, só que definitivamente, já há algum tempo aboli duas ferramentas do meu repertório… ifconfig e route. Obviamente, me refiro ao ifconfig do Linux, pois em sistemas BSD, o ifconfig não te obriga a criar uma interface alias, ao invés de somente adicionar um IP alias em sua placa de rede…

Desde 1999 (ainda no kernel 2.2) foi liberado publicamente o iproute2, que nada mais é que uma série de utilitários escritos a fim de modernizar e compatibilizar os sistemas GNU/Linux com os outros sistemas operacionais de rede, como o IOS e outros que habitam diversos ativos de rede por aí. Além disso, o iproute2 traz uma ferramenta específica para controle de tráfego, coisa que (pasmem) muita gente ainda acredita que não exista no Linux.

Talvez você ache inútil trocar de ferramenta, mas fica extremamente claro que você precisa usar algo mais moderno quando vc tiver mais de 2 ips alias na mesma interface de rede. Eu realmente acho idiota, e totalmente ridículo existir os aliases eth0:1, eth0:2, eth0:3 e assim sucessivamente se na realidade, você só está colocando um ip alias na eth0. Não concorda que o comportamento dos BSDs são mais inteligentes, que simplesmente listam os aliases na mesma interface com o nome de alias? Então, já está aí uma boa justificativa para começar a usar o iproute2 pois agrega os endereços em uma mesma interface.

Se você achou que esta justificativa é insuficiente para largar o seu velho e conhecido ifconfig, tudo bem, mas e se eu te disse que a mesma ferramenta que você configura seu IP também configura o roteamento do seu sistema? Ohhhh! incrível! Poisé, o mesmo comando configura sua interface e ainda configura a tabela de roteamento do seu sistema!

Ainda não acha que é uma boa justificativa? Tudo bem, eu compreendo. Mas essa ferramenta apesar de tão simples e intuitiva ainda é capaz de gerenciar o tráfego de sua rede! Complicado de entender? Não acho. Imagine, seu sistema é responsável por gerenciar diversos links diferentes e você precisa priorizar o tráfego de determinado serviço. Sim, você pode criar uma rota e mandar tudo que vem da origem X sair pelo link Y, mas normalmente, depois de alguns dias, ao verificar a tabela de roteamento você não vai entender o que significa aquele amontoado de rotas que parecem não dizer nada. O iproute2 te auxilia bastante nesse sentido. Se você tem conjuntos de servidores por determinados serviços, você pode agrupá-los em rules e definir o tráfego através dessas rules. Depois, quando precisar listá-las, o que você poderá ver é uma lista nomeada de “o quê é o quê” e “pra onde vai o quê”.

Apesar de tudo isso, o maior mérito do iproute2 ainda é a ferramenta tc, que gerencia o controle de banda do Linux. Incrível é o fato de muitos SysAdmins não sabem sobre esta ferramenta. Ouvem muito falar sobre HTB e CBQ, e acreditam que HTB e CBQ sejam comandos ou programas, quando na verdade são qdiscs (Queue Disciplines) gerenciadas através do tc.

Tudo isso é realmente trivial, reconheço, só que acredito que seja importante nos renovarmos e nos compatibilizarmos com as outras ferramentas, que afinal, seguem o mesmo padrão. Talvez muitos SysAdmins não acreditem tanto na necessidade de mudança, pois normalmente a preocupação de um SysAdmin é acima da camada de rede, mas para um profissional de rede, essa mudança é de extrema importância. Apesar de eu ser um SysAdmin, tenho formação específica na área de rede, e talvez por isso seja tendêncioso e acredito na necessidade desta mudança, não só de ferramenta, mas de pensamento.

Se você se concorda com isso, o primeiro passo é ler bastante sobre o que o iproute2 pode fazer. Como esse artigo não tem a finalidade de ensinar nada, eu aconselho a leitura de dois documentos; Linux Advanced Routing & Traffic Control HOWTO e o HTB Manual - Ambos são ótimas fontes de informação sobre em que o iproute2 pode te ajudar.

No Comments

Os atuais MDAs e as linguagens de filtragem de e-mail (parte 2)

email.pngNesta segunda parte, venho mostrar aquele que é na minha opinião, o mais completo MDA para uso geral, O Courier-Maildrop.

À primeira vista, sei que este comentário parece tendencioso, mas independente de minha opinião pessoal, acho importante que se saiba as capacidades deste MDA antes de fazer sua escolha.

Novamente contarei um pouco de história, falando sobre o seu crescimento e amadurecimento. Trago também novos exemplos para mostrar aquilo que é o mínimo que a maildropfilter pode fazer.

Courier-Maildrop, o canivete suiço

Este MDA Surgiu em 1998, inicialmente como parte do Courier Mail Server, mas logo teve seu release standalone. Com o passar dos anos, foi se tornando um dos MDAs mais flexíveis e logo tornou-se também um dos mais usados, tendo como concorrente direto o vdeliver (parte do software vmailmgr, o qual não vou abordar) em servidores com Qmail. Com o advento do Postfix, teve um significante aumento em sua difusão, pois trata-se de uma alternativa eficaz para usuários virtuais. Durante uns bons anos foi considerada o melhor para este fim, devido sua flexibilidade. Em relação à sua linguagem para filtros, a maildropfilter é uma linguagem extremamente flexível e poderosa. Possui uma sintaxe muito parecida com Perl ou PHP e também características do POSIX Shell Script, e por isso podemos considerá-la extremamente intuitiva e com uma suave curva de aprendizado.

A maildropfilter não é somente uma linguagem que possibilita criar regras para filtragem de mensagens, mas sim, além dessa que é sua funcionalidade básica, é um processador de regras de negócio. Diferentemente do procmail e o Dovecot LDA (que veremos no próximo artigo), o maildrop é o único que por possuir realmente uma linguagem de programação embutida, pode proporcionar algo assim.

Da mesma forma que os outros MDAs, o maildrop inicia seu trabalho a partir de expressões regulares (PCRE) e finaliza seu trabalho quando encontra a declaração “to”. Inicia com diversas variáveis pré-definidas, e entre elas algumas importantes são: DEFAULT (Mailbox padrão para entrega. Para utilizar maildir, “Maildir/”), FROM, LOGNAME e SENDMAIL. Muitas outras estão disponíveis vide “man maildropfilter”.

Uma feature extremamente útil na minha opinião, é a capacidade de executar comandos de sistema. A maildropfilter o faz de duas formas: Através do comando xfilter ou da forma Unix like de receber saída de comandos, com as aspas invertidas. Ex. DIR=`ls`.

Podemos considerar a maildropfilter é uma linguagem completa, pois ela conta com os condicionais if e else, os laços while, for e foreach, operadores lógicos e bitwise e operadores de comparação, semelhantes ao POSIX Shell e Perl. Além disso, conta com comandos específicos para ajudar na filtragem. Veremos estes comandos nos exemplos à seguir.

Exemplos:

1. Filtrar todas as mensagens com Assunto ***SPAM*** para a pasta Mala Direta:

1
2
3
4
5
6
if ( /^Subject:.*SPAM.*/ )
{
    # Ao processar com sucesso o to o maildrop sai com EX_OK.
    # Em caso de erro EX_TEMPFAIL.
    to “$MAILDIR/.Mala Direta/}

2. Se a mensagem vier de “Grupo Email” verificar o assunto e se caso for “Teste do Maildrop” mover para a pasta “Grupo Email”:

1
2
3
4
5
6
7
if(/^From:.*GruposEmail.*/)
{
    if(/^Subject:.*Teste.do.Maildrop.*/)
    {
        to “$MAILDIR/Grupo Email/”
    }
}

3. Verificar no arquivo .config se o usuário possui o serviço de filtro de mensagens, e caso positivo, executar os filtros deste usuário e logar que será executado o filtro:

1
2
3
4
5
6
7
8
9
10
11
# seta local do logfile. Usuário rodando maildrop
# precisa de permissão de escrita no arquivo.
logfile “/var/log/maildrop.log”
 
# o comando lookup procura por patterns dentro de arquivos.
if(lookup(/^filterpref/, $HOME/.config))
{
    # grava no logfile.
    log “Este login possui filtros, executando”
    include $HOME/.myfilters
}

4. Verifica se o remetente está na blacklist

1
2
3
4
5
6
7
8
9
# a maildropfilter possui pattern matching, sendo assim você
# pode usar o resultado da expressão regular no seu script.
if(/^From:s*(.*)/ && lookup( $MATCH1, “blacklist.txt”) )
{
    # extrai o endereço RFC2822 do resultado da expressão.
    ADDR=getaddr($MATCH1)
    log “maildrop: $ADDR is on blacklist (dropped)”
    exit
}

Muitos outros exemplos e a documentação completa do maildrop e da maildropfilter podem ser conseguidas via o comando “man maildrop” e “man maildropex”, ou na página do Courier-Maildrop.

Como visto nos exemplos, o maildrop é um filtro avançado e o mais indicado quando é necessário colocar regras de negócio no procedimento de entrega dos e-mails. Lógicamente, se a sua única intenção é efetuar filtragens simples, você pode optar por outro MDA menos robusto. Isto também não significa que nestes casos você não deva o usar, pois a escolha também depende da combinação usada na instalação de seu servidor. Normalmente, se você utiliza Courier-IMAP, a melhor escolha é sempre o maildrop.

Espero que este artigo também tenha sido esclarecedor e como é de praxe, se você quiser conhecer mais sobre este MDA, acesse o site do Courier-Maildrop e também leia suas páginas de manual. Te garanto que é a melhor leitura pra quem quer aprender sobre este cara.

No próximo artigo, falarei sobre o Dovecot LDA, esse que é a coqueluxe do momento, e também sobre a história do Sieve. Até lá!

Bibliografia

maildrop documentation: http://www.courier-mta.org/maildrop/documentation.html
Páginas do manual: man maildropfilter, man maildropex

1 Comment