Hogar Indice Busqueda Enlaces Sobre Nosotros
  Noticias   Archivos   Compañias   Consejos y Trucos  

Procesamiento de Correo con procmail

por Angel Lopez


Instalación

Funciones Básicas

Configuraciones

Listas de Correo

Respondiendo Correo

Bucles Infinitos

Descifrando Mensajes

Conclusiones

Instalación

El primer paso es conseguir la última versión de procmail. Cuando se comenzó a escribir este artículo la última versión disponible era la 3.11pre7.

Una vez que hayas obtenido el fichero con las fuentes del programa, para instalarlo deberás descomprimirlo con el siguiente comando: tar -xzvf procmail.tar.gz

El siguiente paso sería editar los ficheros Makefile y config.h. Al ser este artículo de introducción y para no complicar en exceso este primer acercamiento a procmail, no trataremos las diferentes opciones de configuración de estos ficheros. El lector interesado en ello puede consultar las páginas de manual y la documentación suministrada con el paquete.

No obstante, es conveniente resaltar la presencia de la opción BASENAME en el fichero Makefile. Con esta opción indicaremos el directorio base donde se instalará procmail. Del directorio que indiquemos en esta opción colgarán otros como bin y man.

Finalmente, para compilar el paquete, deberemos ejecutar el comando make install.

Procmail puede instalarse para todo el sistema y ser llamado desde alguna regla del sendmail(8) o puede ser instalado por un usuario para su uso particular. En éste último caso, el usuario indicará el uso de procmail en su .forward, donde habrá una línea como la siguiente:

|IFS=' ' && exec /home/juan/procmail/bin/procmail -f- || exit 75 #juan

He indicado esta línea suponiendo que el usuario juan ha instalado procmail en su HOME. Para esta línea en particular deberiamos haber indicado como BASENAME el directorio /home/juan/procmail.

Funcionamiento Básico

Procmail lee de su entrada standard un mensaje. Consulta el fichero .procmailrc que es un fichero de configuración que el usuario deberá tener en su HOME. Este fichero define ciertas reglas que servirán para que el procmail sepa qué hacer con el mensaje que ha leido.

Se podrá indicar que compruebe la cabecera del mensaje y busque ciertas cadenas en ella, para decidir si queremos guardar el mensaje, descartarlo, contestarlo automáticamente, etc...

Procmail nos permitirá tratar el correo que nos llegue, o el almacenado en un fichero, de manera automática.

Configuración

El fichero de configuración usado es .procmailrc y deberemos tenerlo en nuestro HOME.

Toda línea que comience por # se considerará un comentario.

Las líneas que comiencen por :0 o :0: indicarán el comienzo de una regla que indicará a procmail qué debe hacer con un mensaje.

Las líneas que comienzan por * indican la condición de una regla. De esta manera procmail selecciona la regla que debe aplicar a un mensaje determinado.

Las restantes líneas, es decir, aquellas que no comienzan por un :, un # o un * se considerarán comandos, es decir, lo que tiene que hacer procmail al ver que cierto mensaje cumple la condición indicada en una regla. Se podrá borrar el mensaje, redirigirselo a otra persona, guardarlo en un fichero...

Lo primero que deberás indicar en tu .procmailrc son algunas variables de entorno, a continuación te muestro algunas que es recomendable establecer:

MAILDIR
Indica el directorio donde se almacenan los ficheros con los mensajes de correo. Generalmente apuntará a $HOME/mail o $HOME/Mail. El que sea uno u otro, o incluso otro nombre de directorio dependerá del lector de correo que usemos.

LOGFILE
Indica un fichero donde procmail dejará constancia de todo lo que vaya haciendo.

SENDMAIL
Indica dónde encontrar el sendmail, que se usará cuando se conteste automáticamente a los mensajes.

FORMAIL
Indica dónde encontrar el formail. Este programa se distribuye junto al procmail y sirve para modificar las cabeceras de los mensajes o reformatear un mensaje antes de enviarlos o almacenarlos.

DEFAULT
Fichero donde se almacenará un mensaje si no se le ha podido aplicar ninguna de las reglas definidas.

En cualquier parte de .procmailrc se puede redifinir una variable de entorno. Si se indicase sin el = y un valor, dicha variable se eliminaría.

Respecto a las reglas, apuntar que podemos clasificarlas en dos tipos: reglas que dan por entregado un mensaje y las que no lo dan por entregado.

Las primeras suponen que el mensaje ya ha sido entregado tras la ejecución de la regla, por lo que no se siguen buscando más reglas que pudieran aplicarse al mensaje.

En el segundo caso no se da por entregado el mensaje, así que al terminar la ejecución de la regla actual se continúa la búsqueda de otra regla que pudiera ser aplicada.

La sintaxis general de una regla es la siguiente:


           :0 [opciones] [ : [fichero de exclusión] ]

           * condicion 1

           * condicion 2

                 .

                 .

                 .

           * condición N

           comando

           

Vayamos por partes analizando esta construcción. En primer lugar cada regla comienza por un :0, a continuación podemos indicar las siguientes opciones:

H La condición se aplica a la cabecera del mensaje.
B La condición se busca en el cuerpo del mensaje.
D Al analizar la condición se distingue entre mayúsculas y minúsculas.
A Esta regla se ejecutará únicamente si su antecesora lo hizo.
a Igual que la anterior, con la salvedad de que la ejecución de la regla anterior debió realizarse sin errores.
E Esta regla se ejecutará si la anterior no lo hizo.
e Esta regla se ejecutará si se intento ejecutar la regla anterior pero hubo algún error.
h La cabecera se pasa al comando.
b El cuerpo del mensaje se pasa al comando.
f El comando se considerará como un filtro.
c Genera un carbon copy del mensaje. Al ejecutar una regla que da el mensaje por entregado con este flag, se consigue que el mensaje no se de por entregado y se puedan ejecutar otras reglas a continuación de esta.
w Espera a que el comando se ejecute para recibir su código de salida.
W Igual que el anterior pero en caso de error no emite ningún mensaje.
i Ignora los posibles errores de escritura.
r Escribe el mensaje tal y como esté. No comprueba que termine en una línea en blanco que sería lo correcto.

Por defecto, de no indicarse nada, se comparará la condición de la regla con la cabecera del mensaje (opción H). Al comando se le pasará a su entrada estándard tanto la cabecera del mensaje como su cuerpo (opciones h y b). No se hará distinción entre mayúsculas y minúsculas.

Tras el :0 y las posibles opciones puede aparecer opcionalmente un segundo :, de hacerlo se estará indicando que el fichero destino donde se escriba el mensaje debe bloquearse para que dos procesos no escriban a la vez sobre el fichero. Opcionalmente se puede indicar el fichero de exclusión que se usará para realizar el bloqueo.

A continuación vienen las condiciones, una por línea y precedidas por un *. En las condiciones generalmente se usan expresiones regulares para intentar encontrar cadenas de texto dentro de la cabecera o del cuerpo del mensaje. Las expresiones regulares usan los siguientes símbolos entre otros:

^ Comienzo de la línea.
$ Final de la línea.
. Cualquier caracter excepto un salto de línea.
* Cero o más veces.
+ Una o más veces.
? Cero o una vez.
[a-z] Rango de caracteres, en este caso de la 'a' a la 'z'.
[^a-z] Cualquier caracter que no esté en el rango de la 'a' a la 'z'.
a|b La 'a' o la 'b'

Tras las condiciones viene un único comando. Si el primer carácter del comando es alguno de los siguientes se sigue un comportamiento especial:

! Se redirige el mensaje a todas las direcciones de correo que se indiquen.
| Si después del símbolo se pone el nombre de un programa, éste se ejecutará. Si no se indica nada tras el símbolo, el mensaje se sacará por la salida estándard. Si se indica el nombre de una variable de entorno antes del |, entonces el resultado del comando indicado se guarda en esta variable.

Mailing Lists

Una situación en la que procmail puede sernos útil es en la organización del correo. Supongamos que estamos apuntados a 3 listas de distribución de Linux. Cada lista se identifica por la dirección desde la cual nos llegan sus respectivos mensajes, así pues podríamos tener las siguientes direcciones:


           l-linux@calvo.teleco.ulpgc.es

           linux@nuclecu.unam.mx

           linux-security@redhat.com

           

En condiciones normales los mensajes de estas listas nos llegarían juntos, y de no separarlos los tendríamos todos mezclados en nuestro fichero de correo. Sería mucho más cómodo si al llegar se fuesen clasificando y guardando en diferentes ficheros.

Procmail nos puede solucionar este caso de manera sencilla. Podríamos usar un fichero .procmailrc que tuviese las siguientes reglas para solucionar nuestro ejemplo de las mailing lists de Linux:


:0

* ^From.*l-linux@calvo.teleco.ulpgc.es

l-linux



:0

* ^From.*linux@nuclecu.unam.mx

linux-mx



:0

* ^From.*linux-security@redhat.com

linux-security

Veamos detenidamente una de las reglas. Si comprendes el funcionamiento de ésta, comprenderás el resto ya que la idea es la misma siempre.

En primer lugar nos encontramos un :0 que nos indica el comienzo de una regla. No aparece ninguna opción adicional así que se toman las opciones por defecto: no se diferencian mayúsculas y minúsculas, la condición se aplica sobre la cabecera del mensaje, al comando se le pasará tanto la cabecera del mensaje como su cuerpo.

En la siguiente línea encontramos la condición, que como ya hemos visto siempre se identifica porque el primer carácter de la línea es un *. La condición es la siguiente expresión regular:

^From.*linux@nuclecu.unam.mx

El ^From indica que se buscarán aquellas líneas que comiencen por From

El .* que sigue, quiere decir cualquier número de caracteres. Ya hemos visto que en expresiones regulares . equivale a cualquier carácter y * hace referencia a 0 o más caracteres. Por tanto con .* indicamos que tras el From inicial pueden venir 0 o más caracteres.

A continuación deberá venir linux@nuclecu.unam.mx que es la dirección desde la cual provienen los mensajes.

Si piensas un poco en la expresión regular, verás que lineas como las siguientes serían reconocidas:


From: linux@nuclecu.unam.mx

From:linux@nuclecu.unam.mx

FROM linux@nuclecu.unam.mx

Ya podemos distinguir los mensajes que provengan de esta dirección del resto. Y ahora que ya tenemos un mensaje, ¿qué hacemos con él?

La siguiente línea es el comando, y nos indicará qué hacer con el mensaje reconocido. En nuestro caso indicamos un nombre de fichero linux-mx donde queremos que se guarde el mensaje. El nombre de fichero, de no indicarse un camino absoluto, se tomará como relativo al directorio indicado en la variable de entorno $MAILDIR.

Como ves, de esta manera podemos guardar en diferentes ficheros los mensajes que nos lleguen de diferentes listas de distribución, diferenciándolos por su dirección de origen (From).

Contestación Automática

Otra situación en la que procmail puede ser de ayuda es en las contestaciones automáticas. Puede serte útil, por ejemplo, si quieres mandar automáticamente tu llave pública de PGP a todas aquellas personas que te lo soliciten por E-Mail.

Para ello, tomamos como regla que cualquier mensaje que tenga la cadena "PGP" en el campo de Subject será una petición de envío de nuestra llave pública de PGP. La regla podría definirse de la siguiente manera:


0:

* ^Subject.*PGP

| (formail -r ; cat $HOME/llave.asc) | sendmail -t

Esta misma idea se puede aplicar para hacer el típico programa que avisa a la gente de que nos hemos ido de vacaciones y que por tanto contestaremos su E-Mail a la vuelta:


0:

| (formail -r; cat $HOME/vacaciones.txt) | sendmail -t

En este caso no hay condición, ya que se quiere aplicar a todos los mensajes que nos lleguen.

Evitando Bucles en Contestaciones Automáticas

En los ejemplos expuestos no nos hemos preocupado de manejar los posibles bucles que se puedan producir con el correo cuando se realizan contestaciones automáticas.

Si nos llegase un mensaje cuyo origen fuese nuestra propia dirección de E-Mail, el programa contestaría a esa dirección, llegándonos dicha contestación a nosotros mismos. Este mensaje volvería a ser contestado, y así sucesivamente entrando en un bucle infinito. Para evitarlo, cuando contestamos al mensaje añadimos una nueva línea a la cabecera para indicar que ya lo hemos contestado. Esto lo hacemos con la opción -A de formail:

formail -r -A"X-Loop: dir@email.es"

Donde dir@email.es sería tu propia dirección de E-Mail. De esta manera al crear la cabecera para responder a un mensaje se le añade la línea X-Loop que comprobaremos luego en nuestras reglas de la siguiente manera:


:0

* !^X-Loop: dir@email.es

| (formail -r -A"X-Loop: dir@email.es" ; 

    cat $HOME/vacaciones.txt) | sendmail -t

Con esta regla evitamos entrar en un bucle, ya que los mensajes que contengan en la cabecera la línea X-Loop no cumplirían la condición y no serían contestados.

Decodificando Ficheros

Otra regla interesante para nuestro .procmailrc podría ser aquella que decodificase automáticamente aquellos mensajes que contengan un fichero codificado con uuencode(1). La regla podría ser la siguiente:


:0 B

* ^begin 644 .*

{

	MAILDIR=$HOME/ficheros

	

	:0

	| uudecode

}

En esta regla indicamos explícitamente con la opción B que únicamente deseamos comprobar la condición en el cuerpo del mensaje.

Si encontramos una línea que comience con la cadena "begin 644" significa que hemos encontrado el comienzo de un fichero codificado con uuencode(1) así que establecemos la variable de entorno MAILDIR, que sería equivalente a cambiar al directorio indicado en dicha variable, ya que todas las escrituras se realizarán tomando como directorio base el indicado. En nuestro caso nos interesa guardar los ficheros recibidos por E-Mail en $HOME/ficheros.

A continuación tenemos una regla, sin condición, que únicamente pasa el mensaje al uudecode(1) para que lo decodifique. El fichero original lo obtendremos en $HOME/ficheros.

Conclusión

Como se puede apreciar de la breve introducción que se ha realizado a procmail, este programa puede ser realmente versátil y ayudarnos en la gestión del correo de una manera fácil y cómoda. Recomiendo experimentar con las expresiones regulares y las reglas, para adaptar el programa a tus necesidades, ya que sus posibilidades van mucho más allá de lo que se ha expuesto en esta pequeña introducción.


Para más información:
  • Consulte la página de manual del procmail
  • Lea otros artículos por el mismo autor:PGP en Linux.


© 1998 Angel Lopez
This website is mantained by Miguel A Sepulveda.