ðH geocities.com /bertogg/linux/exim-como.html geocities.com/bertogg/linux/exim-como.html delayed x m^ÔJ ÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ 01K 1O OK text/html €#{ 1O ÿÿÿÿ b‰.H Tue, 18 Sep 2001 18:40:40 GMT €/ Mozilla/4.5 (compatible; HTTrack 3.0x; Windows 98) en, * l^ÔJ 1O
bertogg@yahoo.com
,
Fidonet: 2:348/105.108
Exim
para
los casos típicos de PCs con conexión a internet via módem, usando la
característica de reescritura de cabeceras
Antes de nada, aclarar que no soy ningún experto en Exim, y todo esto está basado en la experiencia: es el método que uso yo y algunas personas más actualmente, y está funcionando bien. Sin embargo, no puedo garantizar que esté libre de errores. Espero que os sirva de ayuda. Cualquier duda, consulta, comentario o sugerencia será agradecido.
Este documento no prentende en ningún caso ser exhaustivo. Se trata de una pequeña guía para poner a punto una configuración básica de Exim, un servidor de SMTP más sencillo de configurar que otros equivalentes como el conocido Sendmail. No por ello Exim es un programa menos serio, sino que puede satisfacer perfectamente las necesidades de un servidor SMTP normal.
Este texto está orientado a un perfil típico de un usuario de PC, con un ordenador o una pequeña red local conectada a Internet via modem, por ejemplo. El objetivo de esta configuración es la reescritura del campo From: de los mensajes de correo salientes, de forma que aparezca la dirección de internet en lugar de la dirección local.
NOTA: Este documento está basado en Exim 3.12 (de Debian potato), pero probablemente es también aplicable a otras versiones de Exim, ya que los cambios en los ficheros de configuración son mínimos.
Este documento se puede encontrar en mi página web, cuya dirección es http://www.oocities.org/bertogg/linux
El fichero de configuración se divide en 6 bloques. Cada bloque está separado del siguiente por la palabra ``end'', excepto el último que no lleva ``end''. Todos los bloques deben aparecer, si alguno se encuentra vacío tiene que aparecer el ``end'' de todos modos. Los bloques son los siguientes:
Cómo funciona exim (a grandes rasgos):
Cuando exim recibe un email, lo primero que hace es aplicar las reglas de reescritura de cabeceras. Una vez reescrito, se comprueba si el destinatario es local o está en otra máquina. Si es local, se pasa por la lista de directors, hasta que alguno sepa qué hacer con él y lo reparta.
Si no es local, se pasa por la lista de routers, también hasta que alguno sepa qué hacer con él.
Para saber si un email es local, se compara el dominio del detinatario con la lista definida en el campo ``local_domains'' en el fichero de configuración.
El primer ejemplo que vamos a ver es una reescritura simple: suponemos que tenemos una red con dos ordenadores ``pc1.mired'' y ``pc2.mired'', y estamos en pc1.
Queremos que todo el correo que salga con ``From: usuario1@pc1.mired''
se chequee en una base de datos, por si hay que reescribir la dirección de
``usuario1'' por otra: usuario1@pc1.mired -> usuario@cuenta.inet
Vamos a partir de una configuración básica cualquiera. En Debian, el script eximconfig genera un fichero de configuración que nos puede servir de maravilla, si seleccionamos ``Internet system using smarthost''. En este documento, en la sección Configuración de ejemplo, hay una basada en esa.
Estas son algunas directivas importantes a considerar en la parte 1 de la configuración. Una vez que todo esté funcionando, se recomienda echarle un vistazo al manual para dejar esto a gusto de cada uno:
---------------------------------------------- # Este es el nombre completo de la máquina. primary_hostname = pc1.mired # Nombres a los que podemos dirigir correo refiriéndonos a nuestra máquina. # Cualquier mail que vaya a uno de estos dominios se considera local # La '@' equivale al valor de primary_hostname local_domains = @:pc1:localhost # Las IPs de nuestra máquina también se consideran locales local_domains_include_host_literals = true # No permitimos relay a ninguna parte relay_domains = "" # A nuestras máquinas sí permitimos hacer relay a cualquier parte host_accept_relay = localhost:*.mired ----------------------------------------------
En la parte 2 (transports) la cosa se puede dejar igual, no es necesario tocar nada. En la parte 3 (directors), pues lo mismo.
Ahora viene la parte 4 (routers). Esto es todo lo necesario:
---------------------------------------------- # Todo el correo que vaya a alguna de las máquinas de la red local se envía # directamente. A continuación explico cada flag: # driver = lookuphost -> Se resuelve el nombre de la máquina para saber su IP # domains -> Para usar este router, el dominio tiene que ser uno de estos. # Pon aquí todos los nombres válidos para una máquina de la LAN # widen_domains -> Si el nombre no se encuentra en la lista anterior, se # le añade el valor de `widen_domains' y se prueba de nuevo. # Nos permite poner usuario1@pc1 además de usuario1@pc1.mired # self = local -> Si al resolver el nombre se obtiene nuestra IP, se envía # el mensaje como si fuese local. Si todos los posibles # nombres de nuestra máquina ya están en 'local_domains', # esto no es necesario # gethostbyname -> Así se mira el /etc/hosts # transport -> Uno de los que aparecen en la sección de transports, # que se encarga de enviar el correo via SMTP red_local: driver = lookuphost domains = "*.mired" widen_domains = "mired" self = local gethostbyname = true transport = remote_smtp # Si en el dominio ponemos una dirección IP, se viene por este router literal: driver = ipliteral transport = remote_smtp # Todo lo que no pasó por el anterior se viene por aquí. Todo el correo se # envía al smarthost 'smtp.proveedor.es' smarthost: driver = domainlist transport = remote_smtp route_list = "* smtp.proveedor.es bydns_a" end ----------------------------------------------
La parte 5 es la de ``retry configuration''. La puedes dejar como está o poner a tu gusto.
Finalmente, la parte 6 es la de reescritura. Esta irá así:
---------------------------------------------- *@* ${lookup{$1@$2}lsearch{/etc/exim/email-addresses}{$value}fail} frF ----------------------------------------------
Creamos el fichero /etc/exim/email-addresses
, de la forma:
usuario1@pc1.mired: cuenta1@dom1.sub1 usuario2@pc1.mired: cuenta2@dom2.sub2
De esta manera, cualquier mail que enviemos, si el remitente está en ese fichero, llegará reescrito. Si nos enviamos un email a nosotros mismos en la propia máquina, podremos comprobar que llega con el From: reescrito. Nótese que en este fichero las direcciones del remitente se escriben completas. De esta forma, podemos reescribir direcciones que no sean locales, aunque normalmente eso no será interesante (ni aconsejable). Por supuesto, si no existe el directorio /etc/exim, no hay más que crearlo.
Si sólo nos interesa que se reescriba el From: de los mensajes que
salen de la red local, el método es bastante similar. Originalmente había
ideado un método con dos configuraciones, que se describe en la sección
Método de las dos configuraciones. Este método es
más sencillo y -en mi opinión- mejor que el otro en cualquier caso. De todos
modos, es importante dejar claro que para este método es imprescindible tener
el intérprete de perl instalado (lo podemos comprobar escribiendo
perl -v
en la línea de comandos).
A partir del exim.conf original, hacemos las siguientes modificaciones:
remote_smtp
''
por ``rewritten_smtp
''
------------------- rewritten_smtp: driver = smtp transport_filter = "/etc/exim/from-rewrite.pl" return_path = "${lookup{$sender_address}lsearch\ {/etc/exim/email-addresses}{$value}fail}" -------------------
/etc/exim/from-rewrite.pl
:
------------------- #!/usr/bin/perl -w use strict; my $email = ""; my $linea = ""; while ($linea = <STDIN>) { if (!$email) { if ($linea =~ /^From:.*\<(.*)\>.*/) { $email = $1; } elsif ($linea =~ /^From: *([^ ]*) */) { $email = $1; } if ($email) { my $rewr = ""; $email =~ s/[ \t\n]//g; open(BASE,"/etc/exim/email-addresses"); while (!eof(BASE)) { $rewr = <BASE>; if ($rewr =~ s/$email:[ \t]*([^ \t])/$1/) { $rewr =~ s/[ \t\n]//g; $linea =~ s/$email/$rewr/; close(BASE); } } print $linea; print <STDIN>; exit(0); } } print $linea; } -------------------
De esta forma, todo el correo que llegue al router ``smarthost'', será
enviado al exterior, pero pasado a través del filtro que acabamos de definir,
que reescribirá el From: si lo encuentra en el fichero
email-addresses
.
Atención: Este es el método original que se mostró en este documento; ha sido sustituído por el método del filtro, más adecuado y sencillo, que se describe en la sección Método del filtro. Si decides utilizar este, ignora por completo todo lo descrito sobre el método del filtro.
Si sólo nos interesa que se reescriba el From: de los mensajes que salen de la red local (algo bastante usual), el método es bastante similar. Este es un método que se me ocurrió hace algún tiempo, pero pensaba que tenía que haber otra manera de hacerlo. Consultando el FAQ del Exim, comprobé que allí se explicaba una manera muy similar a esta, por lo que decidí que mi método era correcto.
A partir del exim.conf original, hacemos las siguientes modificaciones:
------------------- correo_exterior: driver = domainlist transport = smtp_externo route_list = "*" -------------------
------------------- smtp_externo: driver = pipe command = "/usr/sbin/exim -C /etc/exim.conf.external $local_part@$domain" user = mail -------------------
De esta forma, todo el correo que llegue al router ``correo_exterior'', será pasado nuevamente al exim, pero esta vez con otra configuración diferente.
Esta es la otra configuración, el fichero /etc/exim.conf.external
:
------------------- ########### General local_domains = relay_domains = * spool_directory = /var/spool/exim/external end ########### Transports remote_smtp: driver = smtp end ########### Directors end ########### Routers smarthost: driver = domainlist transport = remote_smtp route_list = "* smtp.proveedor.es bydns_a" end ########### Retry * * F,2h,15m; G,16h,2h,1.5; F,4d,8h end ########### Reescritura *@* ${lookup{$1@$2}lsearch{/etc/exim/email-addresses}{$value}fail} frF -------------------
Esto ya no tiene mucho misterio. Esta vez no hay ``local_domains'', así que ningún mensaje es local. Todo se envía al router ``smarthost'' que lo envía a internet. Y como vemos, esta configuración sí reescribe la cabecera.
Lo que sí hay que notar es que el directorio de spool es diferente. Esto es
así para evitar problemas. Por eso, los que vacíen la cola del exim al
conectar a internet deben añadir la opción ``-C /etc/exim.conf.external
'', para vaciar sólo la cola del correo que va a internet, que es la
que tiene sentido ahí. El comando debería quedar más o menos de la forma
``exim -qf -C /etc/exim.conf.external
''
Enviar el correo a internet usando el SMTP de nuestro proveedor no es la única opción disponible. Normalmente, estos smarthosts hacen control de relay, por lo que si conectamos en un momento dado con un proveedor distinto, es muy posible que no podamos enviar correo a internet. Una posible solución es enviar el correo directamente a su destino en lugar de usar un smarthost. Así tendremos la ventaja adicional de que el correo llegará antes. Para hacer eso, tan sólo hay que sustituir el router ``smarthost'' que tenemos en los ejemplos por este otro:
-------------------------------- correo_saliente: driver = lookuphost transport = remote_smtp --------------------------------
Si usamos el método del filtro, el transport es ``rewritten_smtp'' en lugar de ``remote_smtp''.
Y esto es todo lo que hay. Espero que lo disfruteis. Se aceptan comentarios, críticas, sugerencias, agradecimientos, etc. :))
En las últimas versiones de Exim, es posible hacer reescritura de cabeceras de los mensajes que salen al exterior usando unas nuevas opciones de configuración de los transports, que eliminan la necesidad de usar filtros externos y segundas configuraciones. Este es sin duda el método más adecuado para hacer esta tarea, y en cuanto migre a esa versión de Exim explicaré en este documento cómo se hace.
Este es un ejemplo de configuración que puede valer perfectamente. Sólo hay que modificarla un poco para adaptarla a cada caso. Está basado en el fichero de ejemplo que genera el programa de configuración de Debian.
El nombre del fichero es /etc/exim.conf
####### EJEMPLO DE CONFIGURACION DE EXIM primary_hostname = pc1.mired local_domains = @:pc1:localhost local_domains_include_host_literals = true relay_domains = "" host_accept_relay = localhost:*.mired host_lookup = 0.0.0.0/0 trusted_users = mail smtp_verify = false gecos_pattern = ^([^,:]*) gecos_name = $1 received_header_text = "Received: \ ${if def:sender_fullhost {from ${sender_fullhost} \ ${if def:sender_ident {(${sender_ident})}}\n\t}\ {${if def:sender_ident {from ${sender_ident} }}}}\ by ${primary_hostname} \ ${if def:received_protocol {with ${received_protocol}}} \ (Exim ${version_number} #${compile_number})\n\t\ id ${message_id}" end ###### TRANSPORTS local_delivery: driver = appendfile group = mail mode = 0660 mode_fail_narrower = false file = /var/spool/mail/${local_part} address_pipe: driver = pipe return_output address_file: driver = appendfile address_directory: driver = appendfile no_from_hack prefix = "" suffix = "" address_reply: driver = autoreply remote_smtp: driver = smtp end ####### DIRECTORS real_local: prefix = real- driver = localuser transport = local_delivery system_aliases: driver = aliasfile file_transport = address_file pipe_transport = address_pipe file = /etc/aliases search_type = lsearch userforward: driver = forwardfile file_transport = address_file pipe_transport = address_pipe reply_transport = address_reply no_verify check_ancestor file = .forward modemask = 002 filter localuser: driver = localuser transport = local_delivery end ###### ROUTERS red_local: driver = lookuphost domains = "*.mired" widen_domains = "mired" gethostbyname = true self = local transport = remote_smtp literal: driver = ipliteral transport = remote_smtp smarthost: driver = domainlist transport = remote_smtp route_list = "* smtp.proveedor.es bydns_a" end ###### RETRY # Domain Error Retries # ------ ----- ------- * * F,2h,15m; G,16h,2h,1.5; F,4d,8h end ###### REESCRITURA # Fin de la configuración de Exim