Las reglas de procmail se refieren al contenido del mensaje en sí (tanto la cabecera como el cuerpo del mismo), y nos permitirán eliminar correo propaganda o spam (si no todo, al menos sí gran parte de él), repartir los mensajes entre los diferentes usuarios de correo, pudiendo tener una sóla dirección email para todos los usuarios, pero utilizando algún campo especial para identificar a cada uno. También podremos separar el correo de las listas de correo, o por categorías, preparar autorespuestas (por ejemplo un autoenviador de nuestra clave PGP cuando nos sea pedida, o un aviso de que nos hemos ausentado y no podemos leer el correo) y, como veremos, muchas cosas más sólo limitadas a nuestra imaginación.
[sromero] [~]$ cat /etc/sendmail.cf | grep "^Mlocal" Mlocal, P=/usr/bin/procmail, F=(...etc...)Si en dicha línea nos aparece la llamada a procmail, éste ya estará integrado en sendmail y podemos pasar directamente a su configuración propiamente dicha.
El fichero .forward sólo será necesario si procmail no es llamado por nuestro MTA (agente de correo), en cuyo caso se necesitará este fichero para llamar a procmail ante cada entrada de mensajes. Dicho fichero se creará en el home del usuario que desea utilizar procmail y contendrá una línea que llame a procmail y que defina el usuario al que debe ir a parar el correo:
|IFS=' '&&exec /usr/bin/procmail -f || exit 75 #sromeroEste fichero debe tener permiso de lectura:
[sromero@compiler ~]$ chmod ugoa+r .forwardCuando es llamado (de cualquiera de las 2 formas), procmail lee el mensaje de correo desde la entrada estándar. A continuación abre y lee el fichero .procmailrc de nuestro directorio home (si existe), examina las reglas contenidas en dicho fichero y decide el destino del mensaje (que puede ser devuelto, enviado a un usuario en concreto, autorespondido, borrado, etc.). Si el fichero .procmailrc no existe el mensaje es depositado en el Inbox habitual del usuario.
El conjunto de reglas de .procmailrc suelen ser de comprobación y búsqueda de cadenas de texto en el FROM (dirección de origen), SUBJECT (tema del mensaje), BODY (cuerpo del mensaje), etc. Como sencillo ejemplo, es posible especificarle a sendmail que si en el cuerpo del mensaje se encuentran las palabras "gane" y "dinero", o similares, elimine el correo (probablemente se trate de un correo spam o correo basura), o que si en el subject encuentra las palabras "clave" y "PGP", debe enviar al remitente de ese mensaje un texto con nuestra clave PGP.
Más concretamente, el fichero .procmailrc contiene un conjunto de reglas formados por instrucciones condicionales, variables y otras instrucciones. Cuando el mensaje es recibido, éste pasa a ser procesado (procmail = procesador de mail), es decir: se leen todas las reglas del fichero y se comprueba si el mensaje cumple alguna de ellas, en cuyo caso se ejecutará el subcódigo pertinente a dicha regla. En caso de no cumplirse ninguna el mensaje es añadido al final del fichero de mensajes por defecto (especificado como veremos por la variable $DEFAULT).
# ejemplo de .procmailrc MAILDIR=$/var/spool/mail DEFAULT=$MAILDIR/juan LOGFILE=$MAILDIR/log :0: * ^From.*romario /home/juan/Mail/mensajes_romario :0: * ^From.*Josema !jefe@de.josema :0 * ^Subject:.*prueba /dev/nullEn en el ejemplo anterior, las 3 primeras líneas especifican los directorios de correo (MAILDIR), el fichero de entrada de emails por defecto (DEFAULT), y un fichero donde procmail indicará paso por paso todo lo que ha hecho en cada sesión (LOGFILE). A continuación se definen 3 reglas (comenzando todas ellas por :0), que son las siguientes:
:0: * ^From.*romario mensajes_romarioTodos los mensajes que contengan en la cabecera From (el remitente) la cadena "romario" serán dejados en el fichero "mensajes_romario". De esta manera, cuando llegue un email cuyo campo From sea From: romario@futbol.com, o From:admiradores@romario.com, éste será dejado en el fichero mensajes_romario. Si esta regla no se cumple (es decir, no aparece la cadena "romario" en el campo From), se pasa a comprobar si se cumple la siguiente regla, que en nuestro caso especifica que todos los mensajes provenientes de josema sean enviados a jefe@de.josema, acción realizada mediante el comando ! (cierre de admiración). La última regla especifica que todos los mensajes que contengan la cadena prueba en el asunto (Subject) deben ir a para a /dev/null (also así como la papelera de Linux). En caso de no cumplirse ninguna de las 3 reglas el mensaje irá a parar al fichero apuntado por $DEFAULT, usualmente /var/spool/mail/<nombre_usuario>, de forma que luego puedan ser recogidos por cualquier cliente de correo, como Kmail o Netscape.
Pero veamos más concretamente la sintaxis de procmail. Lo primero que veremos serán las diferentes variables de entorno que podemos modificar:
La asignación de estas variables puede realizarse en cualquier parte del fichero .procmailrc (no tiene porqué ser al principio del mismo), de la misma forma que pueden eliminarse si procmail se encuentra una línea con el nombre de una variable y sin asignarle ningún valor (ej: DEFAULT (intro)).
En principio, a partir de cada carácter '#' el texto hasta fin de línea es considerado como comentario (ignorado por procmail), con la excepción de las líneas en las que se definen condiciones, donde no es posible situar comentarios (sólo antes o tras ellas, pero nunca en la misma línea).
Dentro de cada regla, las líneas que comienzan por un carácter '*' indican la condición de la regla, mientras que todo lo que siga a las condiciones (pues puede haber más de una condición) se considerarán comandos a ejecutar (excepto las líneas de comentario), tales como en el ejemplo anterior el nombre de fichero (que indicaría a procmail que debe guardar el mensaje ahi), una dirección de correo precedida por ! (que le indica reenvío), o una referencia a /dev/null (borrado), así como la ejecución de cualquier otro comando Linux que deseemos. Pueden distiguirse 2 tipos de reglas: las que al cumplirse se finaliza el procesado del mensaje (terminales) y las que tras su ejecución se siguen realizando comprobaciones con otras reglas (no terminales).
Una regla tiene un aspecto similar al siguiente esquema:
:0 [opciones] [ : ] * condicion A * condicion B * condicion C etc... * condición N comando a ejecutarTras cada :0 podemos utilizar las siguientes opciones:
Como se ha comentado, si no se indica ninguna opción las condiciones de la regla se aplican a la cabecera del mensaje (H), y pasando como entrada al comando tanto la cabecera (h) como el cuerpo del mensaje (b).
Símbolo '^' -> Indica el comienzo de una línea. Símbolo '$' -> Indica el final de una línea. Símbolo '*' -> Indica cero o más veces. Símbolo '?' -> Indica cero o una vez. Símbolo '+' -> Indica una o más veces. Símbolo '+' -> Cualquier carácter excepto un \n (salto de línea). Símbolo [a-z] -> Que quede en un rango de carácteres (primero-último). Símbolo [^a-z] -> Que no quede en un rango de carácteres (primero-último). Símbolo '|' -> Permite especificar operación O ( a | b = 'a' o 'b' )Al comienzo de la línea de condición tambien pueden existir opciones sobre esa condición:
Símbolo '<' -> Permite comprobar si el fichero tiene un tamaño menor al especificado. Símbolo '>' -> Permite comprobar si el fichero tiene un tamaño mayor al especificado. Símbolo '!' -> Invierte la condición (se cumplirá cuando la condición sea falsa). Símbolo '$' -> Realiza susticiones de variables en las expresiones regulares. Símbolo '?' -> Necesita el resultado que devuelve el programa especificado.
1. Fichero: Hace que procmail añada el mensaje al final del fichero, con otros posibles mensajes.
2. Directorio: Hace que procmail guarde el mensaje en el directorio con un nombre propio no repetido.
3.!direccion@email.es: Mediante el carácter '!' podemos enviar el mensaje a la dirección de correo especificada.
4.|programa: El carácter '|' permite ejecutar un programa/comando de linux. La salida del programa saldrá por la salida estándar, aunque se puede redirigir a cualquier lado con el redireccionamiento estandar de linux (>/dev/null, >fichero, etc). También es posible asignar la salida del programa a una variable de entorno.
Tomemos para ello la lista l-linux, de dirección l-linux@calvo.teleco.ulpgc.es. Cualquier mensaje que provenga de esa dirección será un mensaje de la lista, de modo que esos mensajes deberán ir a un fichero aparte del Inbox estándar. A continuación se muestra un .procmailrc que se podría utilizar para dicha separación:
# procmailrc para separar los mensajes # de la lista l-linux :0: * ^From.*l-linux@calvo.teleco.ulpgc.es l-linux.msgs #si no es un l-linux, entrega normal.La regla utilizada es muy sencilla:
* ^From.*l-linux@calvo.teleco.ulpgc.es l-linux.msgsRecordemos que * indica el comienzo de la regla, y que a continuación de * viene la condición de la misma. Esta contiene la cadena From.*l-linux@calvo.teleco.ulpgc.es con el símbolo^ delante. Esto quiere decir que cualquier línea que comience (^) por From, con cualquier número de carácteres (.*) y que contenga la cadena From.*l-linux@calvo.teleco.ulpgc.es cumplirá la regla y que por tanto ese mensaje debe ser grabado en el fichero l-linux.msgs (en el directorio apuntado por la variable $MAILDIR). En caso contrario, se entrega normalmente. El uso de .* es que tras el campo from pueden venir 0 o más carácteres (ver definiciones de condiciones), con lo que cadenas como "From", "From:", "FROM:" y "From, " antes de la direccion de correo serán reconocidas como cumplidoras de la regla.
:0 * ^Sender: linux@calvo.teleco.ulpgc.es { :0 * ^From: juanjo@direccion.es /dev/null :0 B * (juanjo wrote)|(juanjo escribi) /dev/null :0 l-linux.msgs }Como puede observarse en este ejemplo, mucho más elaborado, y basado en otro de una de las muchas páginas web dedicadas a procmail,en este caso hemos creado una regla compuesta de 3 condiciones mediante los operadores { y }. Cuando se detecta si el mensaje es de una lista de correo, se puede hacer distinción entre los mensajes enviados por juanjo@direccion.es (regla 1, comprobándolo en la cabecera, y son enviados a /dev/null, es decir, son eliminados), entre mensajes escritos por dicho usuario (comprobando la condición en el cuerpo del mensaje con la opción B), o (el resto de casos) dejando en el fichero deseado.
Otro ejemplo de este tipo (y muy sencillo) es la autorespuesta de nuestro sistema de correo a determinados emails, como envio de la clave PGP (cuando el Subject del mensaje contiene la cadena PGP es usual que nos la estén pidiendo), o autorespuestas para cuando nos vamos de vacaciones:
:0: * ^Subject.*PGP | (formail -r ; cat /home/juan/clavepgp.txt) | sendmail -tEn este caso clavepgp.txt es un texto con nuestra clave PGP lista para enviar, que pasamos a formail para que componga un mensaje que enviamos con sendmail. De la misma forma podemos autoresponder en vacaciones a todos los mensajes que sean recibidos, simplemente eliminando la condición. El único problema que puede presentarse es que un email nos sea devuelto, con lo que lo contestaríamos de nuevo (a nuestra dirección), nos llegaría, lo volveríamos a contestar, etc. Para evitar esto se utiliza una campo del mensaje llamado X-Loop que detectaremos antes de contestar, pues si está presente quiere decir que ese mensaje lo enviamos nosotros (lo activaremos en cada autorespuesta), y si no, que es un mensaje del exterior. El añadir un campo a la cabecerade un mensaje se realiza con formail (ver man formail), y lo debemos hacer en cada autocontestación:
formail -r -A"X-Loop: nosotros@direccion.es"A la hora de auto responder también deberemos detectar si ya existe dicho campo y no contestar en ese caso:
:0 * !^X-Loop: nosotros@direccion.es | (formail -r -A"X-Loop: nosotros@direccion.es" ; cat /home/juan/estoy_de_vacaciones.txt) | sendmail -t
Santiago Romero
Volver a la tabla de contenidos.