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.
|