Inicio > Linux > Montar un Servidor Correo con : Postfix + Mysql + Teapop HOWTO

Montar un Servidor Correo con : Postfix + Mysql + Teapop HOWTO

Visitado: 18 veces.
Viernes, 2 de noviembre de 2007 Dejar un comentario Ir a comentarios

Postfix + Mysql + Teapop HOWTO

1. Introducción

Cuando comence a trabajar como administrador de redes en una pequeña red, me di cuenta que la manera de administrar correos vía Sendmail y usuarios reales era un martirio. No sabía configurar Sendmail ni tampoco tenía tiempo de aprender.

Probando con los distintos MTAs disponibles en Internet, el que finalmente use (y actualmente uso) es Postfix. No es por desmerecer a Sendmail, ni Qmail ni ningún otro. Todos tienen su fortaleza y sus deficiencias. Pero hasta el momento no soy un usuario experto, sino un aprendiz de sysadmin, y algunas veces, la simplicidad da paso al poder, y no al revés.

Cuando comencé a trabajar, aún seguía estudiando. Dentro de los ramos que tenía, uno de ellos era Bases de Datos. Así que empecé a pensar de que forma los servicios gratuitos como Yahoo o Hotmail podían agregar usuarios en tiempo real, casi sin haber intervención humana. Es de allí que comence a pensar que usaban bases de datos para la administración.

Así que me puse manos a la obra en el peor momento de todos, y la solución salió mas por perseverancia que por propia suerte.

1.1 Aclaraciones # comando

Comando que debe ejecutarse como root

$ comando

Comando que debe ejecutarse como un usuario normal

mysql>

Linea de comando de mysql

1.2 Pasos previos

Primero, hay que conseguir el software necesario. Segundo, asumo que se instala desde la consola. Prioritario.

  • Un compilador (preferentemente gcc)
  • El paquete Make
  • Software RPM:
    Mysql (mysql, mysqlclient, mysql-server, mysql-devel) : Estos paquetes estan incluidos en la distribucion minima de Red Hat. Para instalarlo, se necesitan las dependencias de estos paquetes. Fuera del contexto de este HOWTO esta la forma de compilar, configurar y hacer funcionar MySQL, pero igualmente se incluye una pequeña guia de supervivencia practica.

    Disponible en http://www.mysql.org

    Postfix (postfix-XXX-src.rpm) : Paquete incluido dentro de las herramientas de RedHat (PowerTools). Recalco esto ya que el ultimo snapshot no contenia el soporte para entregas virtuales. Preferible instalar los fuentes, parchar, compilar e instalar.

    En todo caso, Postfix esta disponible en http://www.postfix.org

  • Fuentes:
    Teapop : Como dije, cuando comence a buscar servidores de POP/IMAP me encontre con este juguete. Soporta los RFCXXXX y RFCXXXX, dominios y usuarios virtuales, autentifica sobre htpasswd, pam, mysql, postgresql, etc.

    Disponible desde http://www.toontown.org/teapop

2.0 Configuraciones previas antes de instalar

Lo primero es crear el usuario y el grupo Postfix, necesarios para la entrega de correos. Desde la consola ejecutar:

# groupadd postfix # adduser -g postfix postfix

Esto creara el directorio /home/postfix que precisamente se volvera la raiz del "spool" de correo, alla "/var/mail".

Instalar los paquetes relacionados con mysql:

# rpm -ihv mysqlXXXXXX.rpm

En caso de necesitar dependencias (Perl), instalarlas. Se debe tener mysql configurado e instalado antes de seguir.

No olvidar el paquete mysql-devel, necesario para compilar Teapop y Postfix.

2.1 Postfix

Instalar los fuentes de Postfix. Esto NO hara que el paquete .src.rpm aparezca en la base de datos RPM, solo descomprime los archivos (parches, scripts y el snapshot)

# rpm -ihv postfix-XXXX.src.rpm

En caso que Linux reclame, verificar que /usr/src/redhat este previamente creado.

Si estuviese creado, "por el amor de dios", sacar cualquier archivo presente alli, para evitar confusiones con otros paquetes. Es super entretenido no saber que parche aplicar, sobre todo por la falta de sueño y el exceso de cafeina…=)

En /usr/src/redhat/SOURCES estara el archivo snapshot-XXXXX.tar.bz2. Este archivo, primero descomprimirlo con bunzip2. Luego, ojala moverlo a un directorio con permisos de lectura para cualquier usuario para configurar y compilar. En este caso, al /tmp

# bunzip2 snapshot-XXXXXX.tar.bz2 # mv snapshot-XXXXXX.tar /tmp

Ahora, como un usuario normal (no root) descomprimimos el snapshot. Por conveniencia use el mismo usuario Postfix.

# su postfix $ cd /tmp $ tar xfv snapshot-XXXXX.tar

(paso opcional) Parchar Postfix. No se cubre aqui, aunque la misma distribucion del postfix-XXXX.src.rpm viene con algunos parches incluidos.

Sigue configurar (dentro del directorio extraido) Postfix para compilar. Para eso usamos:

$ cd snapshot-XXXXXX $ make -f Makefile.init makefiles ' CCARGS=-DHAS_MYSQL -I/usr/include/mysql' ' AUXLIBS=-L/usr/lib -lmysqlclient -lm'

Si se desea incluir soporte SSL, incluir

…. -DHAS_SSL -I/usr/include/openssl -lssl -lcrypto

(Hay mas opciones, como soporte para Pcre, que no voy a cubrir aqui)

Luego,

$ make

De haber compilado, como root,

# make install

Postfix va a a preguntar ciertas cosas. Estas son las respuestas (en mi caso):

[install_root] / [tempdir] /tmp [config_directory] /etc/postfix [daemon_directory] /usr/libexec/postfix [command_directory] /usr/sbin [sendmail_path] /usr/sbin/sendmail [new_aliases_path] /usr/bin/newaliases [mailq_path] /usr/bin/mailq [mail_owner] postfix [setgid] no [manpages] /usr/local/man

Dentro de /usr/src/redhat/SOURCES hay un archivo llamado postfix-init_script.sh. Hay que copiarlo a /etc/rc.d/init.d

# cp postfix-init_script.sh /etc/rc.d/init.d/postfix

Luego, permitirle a Postfix iniciar en momento de reiniciar la maquina con

# chkconfig postfix on

Postfix esta instalado!

3. Mysql

Mysql es un potente pero humilde RDBMS. No aguanta el 100% de la sintaxis de otros RDBMS, pero para nuestro caso, es suficiente.

Antes de comenzar, verificar que la database mysql esta creada. No esta demas ejecutar

# mysql_install_db

para crearla.

OJO!
La distribucion de RPM de mysql viene con una pequeña 'rana': los archivos de mysql no le pertenecen a mysql. Para ello no esta demas devolverles la pertenencia respectiva.

# chown mysql.mysql /var/lib/mysql -R

Hay que arrancar y configurar para partir a mysql.

# /etc/rc.d/init.d/mysql start # chkconfig mysql on

Ahora, ejecutar

# mysql mysql>

Ahora se debe crear el usuario Postfix (u otro, es para hacer mas facil el ejemplo). Hay dos maneras. Una es a traves de mysqladmin, la otra es agregarlo 'a mano' a user.mysql. Prefiero la segunda.

mysql> use mysql; mysql> insert into user (host, user, password) values mysql> ('localhost', 'postfix', password('postfix'));

Se ingresa en la tabla el usuario Postfix con la password "postfix" o con cualquier password que se quiera. Para eso solamente cambiar password('postfix') por password('la_password_que_yo_quiera').

Ahora se debe crear la database 'mail'. Como dije, hay dos maneras. La manera facil, permitiendole al usuario Postfix acceder a ella es :

mysql> insert into db (host, db, user, select_priv) values mysql> ('localhost', 'mail', 'postfix', 'Y'); mysql> create database mail;

Salir de mysql.

mysql> quit;

Verificar que el usuario Postfix pueda ejecutar mysql y acceder a la db 'mail':

# mysql -u postfix -p mail Enter Password:

Ingresar la contraseña de Postfix. Deberia devolver la linea de comando mysql:

mysql>

Si no lo hace, verificar :

  1. la contraseña del usuario postfix

    Si se olvido la contraseña del usuario postfix, es facil cambiarla. Entrar a mysql como root.

    # mysql mysql> use mysql; mysql> update user set password=password('nueva_password') where user='postfix'; mysql> quit; # mysqladmin reload

  2. verificar que mysql este corriendo (pero no en modo seguro!)
  3. verificar que los archivos en /var/lib/mysql pertenezcan a mysql.mysql.

Si todo funciona bien hasta aqui, hay que crear las siguientes tablas (como root):

transport: Transporte, el mismo transporte de Postfix.

aliases : los 'alias' locales de la maquina. Necesario para entrega en dominios virtuales y donde van a caer los mensajes (en un spool truculento en /home/postfix). remote_aliases : 'alias' remotos, que pertenezcan a la maquina o a otra externa.

# mysql mysql> use mail; mysql> create table transport(domain varchar(255) Primary Key, transport char(8)); mysql> create table aliases (id int(6), alias varchar(255) Primary key, mysql> maildir varchar(255) not null); mysql> create table remote_aliases (alias varchar(255) Primary key, mysql> rcpt varchar(255) not null);

Estas tablas son necesarias para Postfix. Ahora agreguemos la tabla necesaria para autentificar a nuestros usuarios:

mysql> create table midominio (user varchar(255) primary key, mysql> pass varchar(255) not null, maildir varchar(255) not null, mysql> active int(8) default 1); mysql> quit;

Luego

# mysqladmin reload

OJO!
Ahora hay que cambiar la contraseña de acceso de root para mysql. Esto es para evitar intrusiones desde la consola (o desde la misma maquina)

# mysql mysql> update user set password=password('nueva_pass_root') where user='root'; mysql> delete from user where user=''; mysql> quit; # mysqladmin reload

Mysql esta corriendo perfecto!

4. Postfix+Mysql

Aqui comienza la configuracion y los pasos mas faciles.

En /etc/postfix se encuentran (un monton!) los archivos de configuracion de postfix. Solo se necesita el principal, main.cf

Necesitamos configurar un par de cosas a este archivo:

myhostname = mydomain = inet_interfaces = all (o las que se quiera escuchar correo)

Ahora, agregar las tablas de 'diccionario' (como las llama Postfix) con soporte de mysql. Todo esto en /etc/postfix/main.cf

transport_maps=mysql:/etc/postfix/transport.cf virtual_mailbox_base=mysql:/home/postfix virtual_uid_maps=mysql:/etc/postfix/ids.cf virtual_gid_maps=mysql:/etc/postfix/ids.cf virtual_mailbox_maps=mysql:/etc/postfix/aliases.cf virtual_maps=mysql:/etc/postfix/remote_aliases.cf

Ahora hay que crear los siguientes archivos en /etc/postfix:

———–transport.cf user=postfix password= dbname=mail table=transport select_field=transport where_field=domain hosts=localhost ———–aliases.cf user=postfix password= dbname=mail table=aliases select_field=maildir where_field=alias hosts=localhost ———–ids.cf user=postfix password= dbname=mail table=aliases select_field=id where_field=alias hosts=localhost

Todavía NO iniciar postfix (si está esta corriendo, echarlo abajo).

Con este sistema, se puede hacer la entrega de varios dominios virtuales sin sudar mucho. Todo es gracias a la tabla transport. Se explica esto mas tarde.

Iniciar mysql:

# mysql -u root -p Enter Password: <—esto solo sale si le cambiamos la password de mysql a root mysql> use mail; mysql> insert into transport values ('midominio', 'virtual:'); mysql> quit;

Con el usuario Postfix, hagamos el "spool":

# su postfix $ cd /home/postfix $ mkdir midominio $ exit

Ahora agreguemos un usuario "virtual":

OJO!OJO!OJO!
Para hacer que funcione bien el truco, hay que indicar en el campo id de la tabla aliases…

EL MISMO USERID DE POSTFIX!

De lo contrario, el maillog se va a llenar de "enforcing file restriction"!

# cat /etc/passwd | grep postfix postfix:x:500:500::/home/postfix:/bin/bash

En este caso, el userid es 500. Tratar que el UID/GID sea el mismo.

# mysql -u root -p mail Enter Password: mysql> insert into aliases values (500, 'yo@midominio', 'midominio/yo'); mysql> quit;

Reiniciar mysql

# mysqladmin reload

Y…

# /etc/rc.d/init.d/postfix start

Ahora viene verificar el log de mail y el de mensajes, en caso de encontrar mensajes raros.

En otra consola (alt-F(algo)), iniciar un simple rastreo del maillog:

# tail -f /var/log/maillog

Y en otra iniciar una sesion smtp:

# telnet localhost 25

Si todo fue bien, mensajes de este tipo NO se veran en el maillog:

postfix/smtpd [3435]: fatal: unsupported dictionary type: mysql

(no se compilo Postfix con soporte mysql)

Si todo salio bien…

# telnet localhost 25 Trying 127.0.0.1… Connected to localhost.localdomain. Escape character is '^]' 220 midominio ESMTP Postfix

Lo cual indica que todo salio bien!

Ahora probemos una entrega local, usando comandos SMTP minimos. Voy a colocar los mensajes del servidor y los mios:

svr>220 midominio ESMTP Postfix yo >mail from: yo@midominio svr>250 ok yo >rcpt to: yo@midominio svr>250 ok yo >data svr>354 End data with . yo >Subject: Estoy probando yo >Hola mundo! este es mi primer mensaje yo >. svr>250 Ok: queued as 06DD618415 yo >quit

Ahora revisar el log:

postfix/smtpd[4147]: connect from localhost.localdomain[127.0.0.1] postfix/smtpd[4147]: 06DD618415: client=localhost.localdomain[127.0.0.1] postfix/cleanup[4148]: 06DD618415: message-id=<20011106031630.06DD618415@fugees> postfix/qmgr[4145]: 06DD618415: from= , size=356, nrcpt=1 (queue active) postfix/smtp[4150]: 06DD618415: to= , relay=none, delay=85, status=bounced (Name service error for midominio (Host not found) while looking up the A record.)

No hay de que preocuparse, solamente no encuentra al servidor para midominio. Por tanto, queda configurar a midominio en un servidor DNS.

Si todo salio bien:

postfix/qmgr[2372]: 6D56718029: from= , size=341, nrcpt=1 (queue active) postfix/virtual[2442]: 6D56718029: to= , relay=virtual, delay=12, status=sent (mailbox)

Todo esta OK! Ahora verificar que haya llegado a nuestro 'spool':

# ls /home/postfix/midominio/ 4 -rw——- 1 postfix postfix 341 Nov 5 02:03 yo

Todo Ok! Creado con los permisos de postfix.postfix! Ahora solo queda crear mas usuarios! Mas dominios! Mas spools truculentos!


Para crear mas dominios 'virtuales': (* mas adelante, dominios y usuarios virtuales)

# mysql -u root -p mail Enter Password: <–como dije, solo si se cambio la password de mysql a root mysql> insert into transport values ('otro', 'virtual:');

(No olvidar que los dominios que se crean tambien deben estar configurados en un servidor de nombre)

Para agregar mas usuarios virtuales:

# mysql -u root -p mail Enter Password: mysql> insert into aliases values (500, 'yo@otro', 'otro/yo'); mysql> quit; # su postfix $ cd /home/postfix $ mkdir otro

Asi creamos un spool distinto para el dominio 'otro'

Todo termino con Postfix aqui.

5. Teapop

Deje esto para el final porque este paso toma 10 minutos en todo. Aparte de ser mecanico.

Primero, desempacar los fuentes de teapop en algun directorio COMO UN USUARIO NORMAL. En mi caso, el fiel usuario Postfix

# su postfix $ cd /tmp $ tar xfv teapop-latest.tar

Configurar

$ cd teapop-XXXXX $ ./configure –prefix=/usr –with-mysql=/usr –sysconfdir=/etc/teapop $ make

Como root, instalar

# make install

El único problema es que el ejecutable 'teapop' lo instala en /usr/libexec. Asi que movamoslo a /usr/sbin

# mv /usr/libexec/teapop /usr/sbin

Verificar que en /etc/services la linea que diga pop3 no este comentada:

# cat /etc/services | grep pop3 pop3 110/tcp pop-3 # POP version 3 pop3 110/udp pop-3

Si esta comentada, descomentarla.


Agregar el siguiente archivo (pop3) en /etc/xinetd.d/ (si todavia tienes inetd, lo siento).

service teapop_xinetd { disable = no type = UNLISTED socket_type = stream protocol = tcp wait = no user = postfix # si se quiere : user = root server = /usr/sbin/teapop log_on_success += USERID log_on_failure += USERID port = 110 }

Y crear el archivo teapop en /etc/rc.d/init.d (tambien se encuentra en la carpeta contrib/rpm en los fuentes de teapop). Gracias, Ivan F. Martinez !

—————-cut here——————– #!/bin/sh . /etc/init.d/functions RETVAL=0 start() { echo -n "Iniciando servicio Teapop: " daemon teapop -s RETVAL=$? echo [ $RETVAL = 0 ] && touch /var/lock/subsys/teapop return $RETVAL } stop() { echo -n "Cerrando Teapop: " killproc teapop echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/teapop return $RETVAL } case "$1" in start) start ;; stop) stop ;; status) status teapop ;; restart|reload) stop start ;; *) echo "Uso: teapop {start|stop|status|restart}" exit 1 esac exit $? —————–cut here——————-

Ahora viene el cuento de agregar un usuario para autentificar. Las passwords se guardan en texto plano, de ahi que es necesario que nadie externo pueda acceder a nuestra base de datos. Ademas, el usuario Postfix en mysql solo puede leer y seleccionar.

Usemos el usuario "yo" que creamos hace poco, en la tabla 'midominio' (como root, de nuevo):

mysql> insert into midominio(user, pass, maild) values mysql> ('yo', 'mipassword', 'midominio/yo');

(El mismo lugar donde esta el spool truculento de Postfix).

Ahora, comentar las ultimas lineas de /etc/teapop/teapop.passwd y colocar lo siguiente:

empty: :mysql:/home/postfix:0:postfix:postfix:localhost:3306:mail:postfix : :midominio:user:pass:maild:

Que significa?

El primer campo indica el dominio contra el que se va a autentificar via pop3.
(* explicacion usuarios virtuales y dominios virtuales mas adelante). La palabra 'empty' indica nada despues del @.
El segundo campo es el numero IP del dominio.
El tercero, el tipo de autentificacion, mysql =)
El cuarto, la raiz donde esta el spool. (ven que facil?)
El quinto es el numero hash. Debe ser distinto por dominio.
El sexto y el septimo, es el UID/GID del usuario que lea el spool. (mas facil)
El octavo, el noveno y el decimo indica el host con mysql (y las tablas), el puerto donde conectarse a mysql y la database.
El undecimo y duodecimo indica el usuario/contraseña para leer/seleccionar la db/tabla
El 13avo indica la tabla donde se encuentran las combinaciones usuarios/contraseñas
Los siguientes valores indican los campos de usuario(user), pass(contraseña) y maildir (maild).

Siempre se debe terminar con un dos puntos final.

Ahora, la prueba final.

# mysqladmin reload # postfix reload # /etc/rc.d/init.d/xinetd restart # chkconfig teapop on # /etc/rc.d/init.d/teapop start

Y listo! Probemos: ( y en otra consola, tail -f /var/log/messages)

# telnet localhost 110 Trying 127.0.0.1 blablablabla…. srv–>+OK Teapop [v0.3.3] – Teaspoon stirs around again <1005018897.CFE43C1@Llywellyn> yo—>user yo srv–>+OK Welcome, do you have any type of ID? yo—>pass mipassword srv–>+OK I'm ready to serve you, Master.

Ok!
Todo funciona bien!

Si no funciono, lo mas seguro es que en /etc/teapop/teapop.passwd hayas colocado :

… midominio: :mysql:….

Si es asi, prueba autentificar el usuario como:

usuario@midominio

Todo esto y más es gracias a la siguiente explicacion:

6. Usuarios y Dominios Virtuales: Un pequeño digest (jci)

Paquetes como IMAP de la Universidad de Washington autentifican contra PAM. O sea, revisan la tabla de passwords en /etc/passwd o cualquier metodo PAM como pam_mysql. El mas conocido es /etc/passwd.

Para IMAP y POP3, autentificar contra PAM solamente permite usuarios que hayan sido definidos como "reales". Es decir, que tengan su propio uid/gid en la maquina. Si no se quiere usar el PAM tipico, es un via crucis adaptar (p.ej. pam_mysql) para que tome la tabla de passwords. Y eso sin contar el infame /var/mail.

Para los sistemas Unix, todas las maquinas pertenecen a un dominio 'real' (gracias, oh TCP-IP). El problema comienza cuando maquinas con el mismo numero IP responden ante distintos nombres. Es decir, si midominio y miotrodominio poseen el mismo IP, prima el numero IP reverso (TCP-IP ve numeros, no nombres).

IMAP de la UdeWasington (el que viene con RedHat), el infame IMAP y su infame compañero, POP3, no permiten tener mas de un dominio por maquina. El truco se logro despues cuando aparecio vpop3d (con linuxconf), pero aun asi, autentificaba via PAM! Con una truculenta tabla de passwords pirateada /etc/vmail/passwd.algo. Aj!

Esto significaba que cada dominio, virtual o no, debia tener su propio numero IP. De ahi que NO recomiendo para nada IMAP de UdeWashington. Y no todo el mundo que sirve 40000 dominios tiene 40000 numeros IP para gastar en 3 usuarios por dominio.

Ahora, lo que permite Qmail+Vmailmgr+CourierImap (otro juguete mas) y este sistema es tener mas de un "dominio" inserto dentro del mismo numero IP. Pero la autentificacion no la hace contra PAM, sino con un metodo propio, haciendolo mas flexible para agregar 40000 dominios contra un solo IP.

Pero como diferenciar los usuarios de un dominio y otro? Gracias, oh, arroba. @.

Usando teapop permite el cuento. Usar el mismo numero IP para autentificar usuarios de varios dominios. Lo unico que los separa es la arroba (@).

Por eso, en la configuracion de teapop (teapop.passwd), el primer campo debe quedar en 'empty' si los usuarios se autentifican con

USER usuario

Y agregar un dominio cuando se quiera que el usuario se autentifique con

USER usuario@dominio

Asi evitamos archivos de texto plano innecesarios y configuraciones adicionales. Este cuento resulto gracias a que todo el movimiento con Postfix se hacia con un solo usuario (no root como ocurre con IMAP) y no con una ensalada, como en Sendmail e IMAP.

7. Dato Anecdótico y ¿Que siguie después?

Compilar todo desde cero, Postfix, Mysql, Teapop, configuraciones y demases toma como tiempo record 1 hora y 30 minutos.

¿Que sigue despues?
Bueno, la pregunta del millon. Queda:

  • configurar Postfix para que no sea un open-relay y así evitar SPAM
  • agregar header_checks y body_checks a Postfix para rechazar contenidos y direcciones. Gracias Ricardo por los body_checks!
  • una interfaz web para agregar/modificar/borrar usuarios via PHP.
  • no se, quizas un servicio de mail gratuito…=)

8. Agradecimientos

- Ricardo Muñoz por revisar la version preliminar del HOWTO y tener la pacienciapara leerlo, revisarlo, corregirlo y quizas probarlo.
– a los listeros de linux@inf.utfsm.cl por la paciencia. esta es la retribucion. Grax a todos!
– a Christoph Kowalczyk por su Postfix+Cyrus HOWTO.
– a DMZ (www.dmzs.com) por su HOWTO de Postfix+MySQL+Cyrus+Apache+WebMail
– A ??? (kummefryser.dk) por su Postfix+Mysql HOWTO, que fue el comienzo del proyecto.
– A Teaspoon (ToonTown) por un juguete tan inocente, liviano y simple como Teapop.
– A Nick Phillips por su Exim+Teapop MiniHOWTO
– A Ivan

Juan C. Inostroza O. jci@infoser.cl
Probando en Red Hat 7.x

Revisado por
Ricardo Muñoz rmunoz@tux.cl


Categories: Linux Tags:
  1. Sin comentarios aún.
  1. Sin trackbacks aún.
Debes estar registrado para dejar un comentario.