{"id":1846,"date":"2016-09-28T07:47:50","date_gmt":"2016-09-28T07:47:50","guid":{"rendered":"http:\/\/esferas.org\/msqlu\/?p=1846"},"modified":"2016-09-28T07:47:53","modified_gmt":"2016-09-28T07:47:53","slug":"usando-ldap-en-exim4","status":"publish","type":"post","link":"https:\/\/esferas.org\/msqlu\/2016\/09\/28\/usando-ldap-en-exim4\/","title":{"rendered":"Usando LDAP en exim4 &#8230;"},"content":{"rendered":"<div class='__iawmlf-post-loop-links' style='display:none;' data-iawmlf-post-links='[{&quot;id&quot;:871,&quot;href&quot;:&quot;https:\\\/\\\/astillas.net\\\/wiki\\\/Exim4AliasLDAP&quot;,&quot;archived_href&quot;:&quot;&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:872,&quot;href&quot;:&quot;http:\\\/\\\/www.exim.org\\\/exim-html-current\\\/doc\\\/html\\\/spec_html\\\/ch-file_and_database_lookups.html#SECTldap&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20260214220239\\\/https:\\\/\\\/www.exim.org\\\/exim-html-current\\\/doc\\\/html\\\/spec_html\\\/ch-file_and_database_lookups.html&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2026-04-15 16:11:52&quot;,&quot;http_code&quot;:200},{&quot;date&quot;:&quot;2026-04-24 11:22:53&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-04-24 11:22:53&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:873,&quot;href&quot;:&quot;https:\\\/\\\/curl.haxx.se\\\/rfc\\\/rfc2255.txt&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20190925164515\\\/https:\\\/\\\/curl.haxx.se\\\/rfc\\\/rfc2255.txt&quot;,&quot;redirect_href&quot;:&quot;https:\\\/\\\/curl.se\\\/rfc\\\/rfc2255.txt&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2026-04-24 11:23:01&quot;,&quot;http_code&quot;:503}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-04-24 11:23:01&quot;,&quot;http_code&quot;:503},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:874,&quot;href&quot;:&quot;http:\\\/\\\/www.datadisk.co.uk\\\/html_docs\\\/exim\\\/routers.htm&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20260415161545\\\/https:\\\/\\\/www.datadisk.co.uk\\\/html_docs\\\/exim\\\/routers.htm&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2026-04-24 11:23:12&quot;,&quot;http_code&quot;:206}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-04-24 11:23:12&quot;,&quot;http_code&quot;:206},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:875,&quot;href&quot;:&quot;https:\\\/\\\/astillas.net\\\/wiki\\\/Exim_y_LDAP&quot;,&quot;archived_href&quot;:&quot;&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;}]'><\/div>\n<p>&#8230; y las notas que he tomado. No todas, algunas est\u00e1n tambi\u00e9n en mi <a href=\"https:\/\/astillas.net\/wiki\/Exim4AliasLDAP\">wiki<\/a>.<\/p>\n<p><!--more--><\/p>\n<h3>Prop\u00f3sitos<\/h3>\n<ul>\n<li>Entender c\u00f3mo funciona un enrutador en la configuraci\u00f3n de exim4.<\/li>\n<li>Escribir uno para obtener los usuarios locales.<\/li>\n<li>Aprender c\u00f3mo se testea un enrutador en exim4.<\/li>\n<\/ul>\n<h3>Conceptos<\/h3>\n<p>En la jerga de exim un enrutador (<em>router<\/em>) es c\u00f3digo que opera sobre direcciones de correo electr\u00f3nico. Al contrario que un transporte (<em>transport<\/em>), que es la parte del programa que env\u00eda mensajes de correo electr\u00f3nico a una cola de mensajes del programa, bien para despacharlas localmente con alg\u00fan programa, bien para enviarlas a otros servidores fuera de su entorno.<\/p>\n<p>El enrutador puede cambiar las direcciones, decidir si son v\u00e1lidas o no y qu\u00e9 transporte usar en caso afirmativo. Esto es, se usan tanto para validar direcciones como para decidir qu\u00e9 hacer con ellas a continuaci\u00f3n. Un enrutador puede funcionar para los dos fines o s\u00f3lo para uno.<\/p>\n<p>Las direcciones de correo electr\u00f3nico se procesan pas\u00e1ndolas en orden por cada uno de los enrutadores, siempre que se cumplan algunas precondiciones en los mismos (por ejemplo si la parte del dominio de la direcci\u00f3n es local o no), hasta que uno de ellos indica que la direcci\u00f3n es aceptable o debe ser rechazada.<\/p>\n<p>Cumplidas las condiciones un enrutador recibe la direcci\u00f3n y decide lo que sucede a continuaci\u00f3n retornando alguno de estos valores:<\/p>\n<ul>\n<li><strong>accept<\/strong>: el enrutador acepta la direcci\u00f3n y, o bien le asigna un transporte, o bien crea una o m\u00e1s direcciones hijas. El proceso de la direcci\u00f3n se interrumpe en \u00e9l a menos que tenga el atributo <strong>unseen<\/strong>. Las posibles direcciones hijas son procesadas de forma independiente comenzando por el primer enrutador de la lista; puede tambi\u00e9n definirse cu\u00e1l con el empleo de <strong>redirect_router<\/strong>.<\/li>\n<li><strong>pass<\/strong>: el enrutador acepta la direcci\u00f3n pero no puede manejarla \u00e9l mismo y pide que se pase a otro enrutador; \u00e9ste puede ser el siguiente en la lista (comportamiento predeterminado) o el indicado en la opci\u00f3n <strong>pass_router<\/strong>.<\/li>\n<li><strong>decline<\/strong>: el enrutador no reconoce la direcci\u00f3n y no la acepta por lo que debe pasar al siguiente enrutador en la lista a menos que exista el atributo <strong>no_more<\/strong>, que convierte la acci\u00f3n <em>decline<\/em> en <em>fail<\/em>.<\/li>\n<li><strong>fail<\/strong>: el enrutador\u00a0 determina que la direcci\u00f3n es fallida y que el sistema debe crear un mensaje de rebote. Si existe el atributo <strong>unseen<\/strong> se seguir\u00e1 procesando la direcci\u00f3n de correo.<\/li>\n<li><strong>defer<\/strong> (aplazar): el enrutador no puede ocuparse de la direcci\u00f3n en este momento -es un fallo temporal- por lo que no se detiene el proceso de env\u00edo hasta el siguiente intento.<\/li>\n<li><strong>error<\/strong>: hay alg\u00fan error en el enrutador (errores de s\u00edntaxis o cualquier otra cosa) y el env\u00edo debe aplazarse.<\/li>\n<\/ul>\n<p>Si la direcci\u00f3n pasa por todos los enrutadores sin haber sido aceptada por alguno se da por no v\u00e1lida y se crea un mensaje de rebote.<\/p>\n<h3>Funciones de b\u00fasqueda en LDAP<\/h3>\n<p>Existen <a href=\"http:\/\/www.exim.org\/exim-html-current\/doc\/html\/spec_html\/ch-file_and_database_lookups.html#SECTldap\">tres tipos de b\u00fasqueda<\/a> en un directorio LDAP en <em>exim<\/em>. Ambas emplean un URL como forma de pasar los par\u00e1metros y se diferencian en los resultados que devuelven:<\/p>\n<ol>\n<li><strong>ldap<\/strong>: obliga a que el resultado sea una \u00fanica entrada. Si hay m\u00e1s se considera un error.<\/li>\n<li><strong>ldapm<\/strong>: permite que el resultado devuelva m\u00e1s de una entrada, retornando los atributos de todas ellas.<\/li>\n<li><strong>ldapdn<\/strong>: el resultado debe ser una \u00fanica entrada pero no devuelve ning\u00fan atributo; en su lugar retorna el DN de la entrada.<\/li>\n<\/ol>\n<p>Para las b\u00fasquedas con <em>ldap<\/em> y <em>ldapm<\/em> debe existir alg\u00fan atributo que retornar. En caso contrario <em>Exim4<\/em> considera la b\u00fasqueda infructuosa.<\/p>\n<p>El URL de consulta sigue las normas del <a href=\"https:\/\/curl.haxx.se\/rfc\/rfc2255.txt\">RFC 2255<\/a> y, dado que no existe forma de pasar credenciales u otro tipo de informaci\u00f3n, la funci\u00f3n de b\u00fasqueda admite una lista de pares variables\/valor de los que cito algunos:<\/p>\n<ul>\n<li>USER = DN para acreditarse en el directorio (<em>bind DN<\/em>); es conveniente emplear la funci\u00f3n <strong><span class=\"docbook_option\">quote_ldap_dn<\/span><\/strong> para proteger caracteres extra\u00f1os, como los espacios en blanco.<\/li>\n<li>PASS = contrase\u00f1a de acceso; tambi\u00e9n conviene utilizar entrecomillado pero esta vez empleando la funci\u00f3n <strong>quote<\/strong>.<\/li>\n<li>SIZE = limita el n\u00ba de entradas retornadas.<\/li>\n<li>TIME = establece un temporizador para la b\u00fasqueda.<\/li>\n<\/ul>\n<p>El URL est\u00e1 compuesto entonces por los siguientes elementos, de los cuales s\u00f3lo es obligatorio el primero:<\/p>\n<ol>\n<li>Esquema: <code>ldap:\/\/<\/code><\/li>\n<li>Servidor y puerto: <code>ldap:\/\/localhost:389<\/code><\/li>\n<li>Base de b\u00fasqueda: <code>ldap:\/\/localhost:389\/ou=users<\/code><\/li>\n<li>Atributos a recuperar: <code>ldap:\/\/\/ou=users?name,mail<\/code><\/li>\n<li>\u00c1mbito de b\u00fasqueda (base,one o sub): <code>ldap:\/\/ou=users?mail?sub<\/code><\/li>\n<li>Filtro de b\u00fasqueda: <code>ldap:\/\/ou=users?mail?one?(uid=coco)<\/code><\/li>\n<li>Extensiones.<\/li>\n<\/ol>\n<p>Los valores retornados depender\u00e1n del operador de b\u00fasqueda (<em>ldap<\/em>,<em>ldapm<\/em> y <em>ldapdn<\/em>) y de lo que encuentre.<\/p>\n<h4>Opciones de configuraci\u00f3n para LDAP<\/h4>\n<ul>\n<li><strong>ldap_default_servers<\/strong>: lista de servidores LDAP con los que contactar en orden si no se indica ninguno en el URL.<\/li>\n<li><strong>ldap_start_tls<\/strong>: fuerza el uso del cifrado v\u00eda TLS sobre una conexi\u00f3n regular.<\/li>\n<\/ul>\n<h3>Enrutador para destinos locales en LDAP<\/h3>\n<p>A continuaci\u00f3n podemos ver el enrutador que tengo funcionando en varios sistemas reducido a la expresi\u00f3n m\u00ednima que funciona.<\/p>\n<pre class=\"lang:default decode:true \">ldap_users:\r\n        debug_print = \"R: LDAP users lookup for $local_part@$domain\"\r\n        driver  = accept\r\n        domains = +local_domains\r\n        condition = ${lookup ldap {ldap:\/\/LDAP_SERVER\/LDAP_BASE??sub?(uid=${quote_ldap:$local_part})}}\r\n        transport = LOCAL_DELIVERY\r\n\r\n<\/pre>\n<h3>Depurando la configuraci\u00f3n<\/h3>\n<p>Una vez realizamos los cambios en la configuraci\u00f3n recreamos \u00e9sta sobre un archivo temporal para probarla antes de pasarla a producci\u00f3n.<\/p>\n<pre class=\"lang:sh decode:true\">$ cd \/etc\/exim4\r\n$ sudo update-exim4.conf -v -o test.conf\r\n$<\/pre>\n<p>Podemos pasarle primero un chequeo sint\u00e1ctico empleando lo siguiente:<\/p>\n<pre class=\"lang:sh decode:true \">$ sudo exim4 -bV -C \/etc\/exim4\/test.conf<\/pre>\n<p>Pero al no realizar expansi\u00f3n de valores tiene una utilidad limitada. Si necesitamos ver con m\u00e1s detalle lo que ocurre en cada fase (el enrutado nuevo por ejemplo) emplearemos lo siguiente:<\/p>\n<pre class=\"lang:sh decode:true\">$ sudo exim4 -bt -C \/etc\/exim4\/test.conf -d+route prueba@empresa.net\r\n...\r\n...\r\nfully qualified name = empresa.net\r\nhost_find_bydns yield = HOST_FIND_FAILED (0); returned hosts:\r\n  localhost &lt;null&gt; MX=0 *\r\ndnslookup router declined for prueba@empresa.net\r\n\"more\" is false: skipping remaining routers\r\nno more routers\r\nprueba@empresa.net is undeliverable: all relevant MX records point to non-existent hosts\r\nsearch_tidyup called\r\n&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Exim pid=3757 terminating with rc=2 &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>Enlaces y referencias<\/h3>\n<ul>\n<li><a href=\"http:\/\/www.datadisk.co.uk\/html_docs\/exim\/routers.htm\">Ejemplos de enrutadores para Exim4<\/a><\/li>\n<li><a href=\"https:\/\/astillas.net\/wiki\/Exim_y_LDAP\">Exim y LDAP en mi wiki <\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8230; y las notas que he tomado. No todas, algunas est\u00e1n tambi\u00e9n en mi wiki.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","webmentions_disabled_pings":false,"webmentions_disabled":false,"footnotes":""},"categories":[2],"tags":[18,25,221,335],"class_list":["post-1846","post","type-post","status-publish","format-standard","hentry","category-software","tag-administracion-de-sistemas","tag-email","tag-exim","tag-ldap"],"_links":{"self":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/1846","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/comments?post=1846"}],"version-history":[{"count":0,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/1846\/revisions"}],"wp:attachment":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/media?parent=1846"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/categories?post=1846"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/tags?post=1846"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}