diff options
-rw-r--r-- | fripost-docs.org | 560 |
1 files changed, 354 insertions, 206 deletions
diff --git a/fripost-docs.org b/fripost-docs.org index abed845..5e7367b 100644 --- a/fripost-docs.org +++ b/fripost-docs.org @@ -267,7 +267,8 @@ access to all credentials. Of course the LDAP server should only be listening to the machines hosting these services and ideally, should not be directly facing the internet. -[TODO: Find a suitable LDAP schema, and drop the MySQL database] +[TODO: Replace the MySQL database by an LDAP tree.] + The main server will also be responsible for keeping all users in an MySQL database that will be replicated using MySQL. @@ -624,6 +625,9 @@ On Debian Squeeze, OpenLDAP's configuration no longer uses `/etc/ldap/slapd.conf `/etc/ldap/slapd.d' directory instead. Unfortunately most of the online tutorials are describing methods using `/etc/ldap/slapd.conf'. +[Note: This has been written by a LDAP noob. It should probably be +rewritten/compressed in a couple of months. /Guilhem, 2012-04-03.] + **** Install packages Here is a basic installation tutorial for Debian Squeeze: @@ -663,130 +667,271 @@ and modify a .ldif file with **** Fripost's schema -We base our schema on qmail's: http://dhits.nl/download/qmail.new.schema . -Note: our schema is not standalone, see the section below. - -Put the code below into `/tmp/fripost.ldif', and run - ldapadd -Y EXTERNAL -H ldapi:/// -f /tmp/fripost.ldif - -dn: cn=mailAccount,cn=schema,cn=config -objectClass: olcSchemaConfig -cn: mailAccount -olcAttributeTypes: ( 1.3.6.1.4.1.12461.1.1.1 NAME 'mailbox' - DESC 'The path to the mailbox.' - EQUALITY caseExactIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) -olcAttributeTypes: ( 1.3.6.1.4.1.12461.1.1.2 NAME 'domain' - DESC 'The path to the mailbox.' - EQUALITY caseIgnoreIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) -olcAttributeTypes: ( 1.3.6.1.4.1.12461.1.1.3 NAME 'quota' - DESC 'The quota on a mailbox e.g., "50MB".' - EQUALITY caseExactIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) - - -# Note: For the meaning of the sequences of digits above, grep the output of -# ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" -# (For instance, 1.3.6.1.4.1.1466.115.121.1.26 is a IA5String, meaning the spaces -# doesn't matter) - +We base our schema on qmail's (http://dhits.nl/download/qmail.new.schema) and +Jamm's (http://jamm.sourceforge.net/howto/html/implementation.html). + + + :: /etc/ldap/local/mail.fripost.org.ldif + + dn: cn=mail.fripost.org,cn=schema,cn=config + objectClass: olcSchemaConfig + cn: mail.fripost.org + olcAttributeTypes: ( 1.3.6.1.4.1.12461.1.1.1 NAME 'mailbox' + DESC 'The path to the mailbox.' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + olcAttributeTypes: ( 1.3.6.1.4.1.12461.1.1.3 NAME 'quota' + DESC 'The quota on a mailbox e.g., "50MB".' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + olcAttributetypes: ( 1.3.6.1.4.1.12461.1.1.4 NAME 'isActive' + DESC 'Is the leaf active?' + EQUALITY booleanMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) + olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.1 NAME 'virtualDomain' + SUP top STRUCTURAL + DESC 'Virtual Domains' + MUST ( dc $ isActive ) + MAY ( description ) ) + olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.2 NAME 'virtualMailbox' + SUP top STRUCTURAL + DESC 'Mail Account Object' + MUST ( mail $ userPassword $ dc $ mailbox $ isActive ) + MAY ( mailLocalAddress $ gn $ sn $ quota ) ) + -# We will also use other attributes, coming from imported schemas: -# * uid, userid: RFC4519: user identifier. -# Usernames. Note that the case is ignored. -# * cn, commonName: RFC4519: common name(s) for which the entity is known by -# First name of the user. -# * sn, surName: RFC2256: last (family) name(s) for which the entity is known by -# -# Also, some attributes will be set automatically, see below. - - -[TODO: This is only an attempt to subsume the MySQL table `mailbox'. Do the same -for the 3 others.] - -**** Add a custom ACL - -The ACL is already properly defined (check it with `ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(|(cn=config)(olcDatabase={1}hdb))"'). - -olcAccess: {0}to attrs=userPassword,shadowLastChange - by self write - by anonymous auth - by dn="cn=admin,dc=fripost,dc=org" write - by * none -olcAccess: {1}to dn.base="" - by * read -olcAccess: {2}to * - by self write - by dn="cn=admin,dc=fripost,dc=org" write - by * read - -But we may want to hide the users' name to anyone but the admin. To this end, create a file -`/tmp/bigbrother.ldif' with the following content: - -dn: olcDatabase={1}hdb,cn=config -changetype: modify -add: olcAccess -olcAccess: {1}to dn.base="o=mailAccount,dc=fripost,dc=org" attrs=cn,sn by dn="cn=admin,dc=fripost,dc=org" write by * none - -and run `ldapmodify -QY EXTERNAL -H ldapi:/// -f /tmp/bigbrother.ldif'. We can -now check `ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(|(cn=config)(olcDatabase={1}hdb))"' -the difference: - -olcAccess: {0}to attrs=userPassword,shadowLastChange - by self write - by anonymous auth - by dn="cn=admin,dc=fripost,dc=org" write - by * none -olcAccess: {1}to dn.base="o=mailAccount,dc=fripost,dc=org" attrs=cn,sn - by dn="cn=admin,dc=fripost,dc=org" write - by * none -olcAccess: {2}to dn.base="" - by * read -olcAccess: {3}to * - by self write - by dn="cn=admin,dc=fripost,dc=org" write - by * read +Note: For the meaning of the sequences of digits above, grep the output of +`ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"' +(For instance, 1.3.6.1.4.1.1466.115.121.1.26 is a IA5String, meaning the spaces +don't matter) + +We can now add it to the schema list: + + ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org.ldif + +(A [dirty] way to delete the schema is to remove the coresponding file in +`/etc/ldap/slapd.d/cn=config/cn=schema/' and to restart slapd.) + +***** Add custom indexes + +The default indexes below are not enough for our purpose, since we will heavily +be looking for e.g., the `mail' attribute. + + :: ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" + [...] + olcDbIndex: objectClass eq + olcDbIndex: uid eq + olcDbIndex: cn eq + olcDbIndex: ou eq + olcDbIndex: dc eq + + + :: /etc/ldap/local/mail.fripost.org-index.ldif + + dn: olcDatabase={1}hdb,cn=config + changetype: modify + delete: olcDbIndex + olcDbIndex: objectClass eq + - + add: olcDbIndex + olcDbIndex: objectClass pres,eq + - + delete: olcDbIndex + olcDbIndex: dc eq + - + add: olcDbIndex + olcDbIndex: dc eq,sub + - + add: olcDbIndex + olcDbIndex: mail eq,sub + +ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-index.ldif + + + :: ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" + [...] + olcDbIndex: uid eq + olcDbIndex: cn eq + olcDbIndex: ou eq + olcDbIndex: objectClass pres,eq + olcDbIndex: dc eq,sub + olcDbIndex: mail eq,sub + +***** Restrict the access + +The default ACL is not restrictive enough for our purpose. +Note: The ACLs are evaluated in order, hence the more specific rules should come +first. + + :: ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" + [...] + olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=fripost,dc=org" write by * none + olcAccess: {1}to dn.base="" by * read + olcAccess: {2}to * by self write by dn="cn=admin,dc=fripost,dc=org" write by * read + [...] + + + :: /etc/ldap/local/mail.fripost.org-acl.ldif + + dn: olcDatabase={1}hdb,cn=config + changetype: modify + add: olcAccess + olcAccess: {0}to dn.children="dc=mail,dc=fripost,dc=org" attrs=userPassword + by self write + by dn="cn=admin,dc=fripost,dc=org" write + by anonymous auth + by * none + - + add: olcAccess + olcAccess: {1}to dn.children="o=mailboxes,dc=mail,dc=fripost,dc=org" attrs=gn,sn + by self write + by dn="cn=admin,dc=fripost,dc=org" write + by * none + - + add: olcAccess + olcAccess: {2}to dn.children="dc=mail,dc=fripost,dc=org" + by dn="cn=admin,dc=fripost,dc=org" write + by * read + +ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-acl.ldif + + + :: ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" + [...] + olcAccess: {0}to dn.children="dc=mail,dc=fripost,dc=org" attrs=userPassword by self write by dn="cn=admin,dc=fripost,dc=org" write by anonymous auth by * none + olcAccess: {1}to dn.children="o=mailboxes,dc=mail,dc=fripost,dc=org" attrs=gn,sn by self write by dn="cn=admin,dc=fripost,dc=org" write by * none + olcAccess: {2}to dn.children="dc=mail,dc=fripost,dc=org" by dn="cn=admin,dc=fripost,dc=org" write by * read + olcAccess: {3}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=fripost,dc=org" write by * none + olcAccess: {4}to dn.base="" by * read + olcAccess: {5}to * by self write by dn="cn=admin,dc=fripost,dc=org" write by * read + [...] [TODO: The proper way to define admin rights would be to make a group "Admin".] -**** Add a user +**** Create the base tree + + :: /etc/ldap/local/mail.fripost.org-base.ldif + + dn: dc=mail,dc=fripost,dc=org + objectClass: domain + dc: mail + + dn: o=mailboxes,dc=mail,dc=fripost,dc=org + objectClass: organization + o: mailboxes + description: Virtual mailboxes + + dn: o=domains,dc=mail,dc=fripost,dc=org + objectClass: organization + o: domains + description: Virtual domains + +ldapadd -cxWD cn=admin,dc=fripost,dc=org -f /etc/ldap/local/mail.fripost.org-base.ldif + + +To delete a leaf or a sub-tree: + ldapdelete -D cn=admin,dc=fripost,dc=org 'o=mailboxes,dc=mail,dc=fripost,dc=org' -W + +**** Populate the tree + + :: /tmp/populate.ldif + + dn: dc=fripost.org,o=domains,dc=mail,dc=fripost,dc=org + objectClass: top + objectClass: virtualDomain + dc: fripost.org + isActive: TRUE + + dn: mail=user@fripost.org,o=mailboxes,dc=mail,dc=fripost,dc=org + objectClass: top + objectClass: inetLocalMailRecipient + objectClass: virtualMailbox + mail: user@fripost.org + gn: First Name + sn: Last Name + userPassword: {SSHA}epZKWD1SiSe/dwL0to+jjnwFzxVUbFvg + dc: fripost.org + mailbox: fripost.org/user/ + isActive: TRUE + mailLocalAddress: user-alias@fripost.org + mailLocalAddress: user@example.org -We start by creating our base tree, in `/tmp/base.ldif': +ldapadd -cxWD cn=admin,dc=fripost,dc=org -f /tmp/populate.ldif -dn: o=mailAccount,dc=fripost,dc=org -o: Mail Users -objectClass: organization -(Run `ldapadd -cxWD cn=admin,dc=fripost,dc=org -f /tmp/base.ldif' to attach the tree'.) +Note: This should obviously be wrapped in a script; `ldapadd' reads the standard +input, so there's no need to write on disk. The password here is a the S-SHA1 hash +of "hackme", created with `slappasswd -s "{SSHA}"'. +Note: If the LDIF files our schema depends on are not in loaded (in `/etc/ldap/slapd.d/cn=config/cn=schema/'), +you may have to do it yourself. A dirty way is to create a file `/tmp/upgrade.conf' with the +following: -We are now ready to create a user. Open a file `/tmp/user.ldif', with the following content: + include /etc/ldap/schema/core.schema + include /etc/ldap/schema/cosine.schema + include /etc/ldap/schema/nis.schema + include /etc/ldap/schema/misc.schema -dn: uid=user,o=mailAccount,dc=fripost,dc=org -objectClass: top -objectClass: mailAccount -uid: user -cn: secret -userPassword: {SSHA}ByzkkO0jNcDwx3+1wZi6FVm0WoEI5Ivo -domain: fripost.org -mailbox: /hop/ -accountActive: TRUE +and a directory `/tmp/upgrade', then to run `slaptest -f /tmp/upgrade.conf -F /tmp/upgrade'. +It creates a bunch of LDIF files that you need to clean (cf. https://help.ubuntu.com/10.04/serverguide/C/samba-ldap.html) +and add with `ldapadd -Y EXTERNAL -H ldapi:/// -f <file.ldif>'. +[TODO: that's just ugly. Find a better way.] -And add it with `ldapadd -cxWD cn=admin,dc=fripost,dc=org -f /tmp/user.ldif'. (Note: this should -obviously be wrapped in a script; `ldapadd' reads the standard input, so there's no need to write -on disk.) Where the password is a the S-SHA1 hash of "hackme". +**** Check the SASL binds (authentication) +ldapwhoami -xD "mail=user@fripost.org,o=mailboxes,dc=mail,dc=fripost,dc=org" -W -To delete a user, you can run - ldapdelete -D cn=admin,dc=fripost,dc=org 'uid=user,o=mailAccount,dc=fripost,dc=org' -W +should return the whole dn: -`slapcat', run as root, dums everything in the tree, including the (hashed) passwords. However, run as a -non-authenticated user, the target's name remains hidden. +"mail=user@fripost.org,o=mailboxes,dc=mail,dc=fripost,dc=org" -We can check that the SASL binds work as excected: +**** Check the ACL - ldapwhoami -xD uid=user,ou=mailAccount,dc=fripost,dc=org -W +***** Admin + +`slpacat' (run as root) dumps everything in the tree, including the (hashed) +passwords. So should + + ldapsearch -xLLL -D "cn=admin,dc=fripost,dc=org" -b 'o=mailboxes,dc=mail,dc=fripost,dc=org' -W + +***** Anonymous user + +`ldapsearch -xLLL' should not return the user's name, or the (hashed) password. + +***** Self + +ldapsearch -xLLL -D "mail=user@fripost.org,o=mailboxes,dc=mail,dc=fripost,dc=org" -b 'o=mailboxes,dc=mail,dc=fripost,dc=org' -W + +should return all the information for this very user, but not e.g., the password of the other users. + + +The user should be able to change his/her password: + + :: /tmp/usermod.ldif + + dn: mail=user@fripost.org,o=mailboxes,dc=mail,dc=fripost,dc=org + changetype: modify + replace: userPassword + userPassword: hop + +ldapmodify -D "mail=user@fripost.org,o=mailboxes,dc=mail,dc=fripost,dc=org" -W -f /tmp/usermod.ldif + +[Note: Still that should be wrapped up in a script, and there is no need to write on +disk since the data is read from the standard input.] +[Note: If the task is merely to change the password, there is also `ldappasswd'.] + +We now ensure that the leaf has been updated: + + :: slapcat -s "mail=user@fripost.org,o=mailboxes,dc=mail,dc=fripost,dc=org" + [...] + userPassword:: aG9w + entryCSN: 20120404215647.957317Z#000000#000#000000 + modifiersName: mail=fripost@fripost.org,o=mailboxes,dc=mail,dc=fripost,dc=org + modifyTimestamp: 20120404215647Z + + +Doing the same thing with eg, trying to change the `mailbox', `ldapmodify' +refuses with `Insufficient access (50)'. *** Configuring the main IMAP server **** Install packages @@ -1013,22 +1158,23 @@ test our installation.) **** Configure saslauthd -Customize `/etc/default/saslauthd' as follows: - -START=yes -MECHANISMS=ldap -OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd" + :: /etc/default/saslauthd + [...] + START=yes + MECHANISMS=ldap + OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd" + [...] (The socket has to be readable by postfix.) -Now, in the `/etc/saslauthd.conf': + :: /etc/saslauthd.conf -ldap_servers: ldap://localhost -ldap_version: 3 -ldap_search_base: ou=accounts,dc=fripost,dc=org -ldap_scope: sub -ldap_filter: uid=%u -ldap_auth_method: bind + ldap_servers: ldap://localhost + ldap_version: 3 + ldap_search_base: o=mailboxes,dc=mail,dc=fripost,dc=org + ldap_scope: sub + ldap_filter: uid=%u + ldap_auth_method: bind After restarting saslauthd (`/etc/init.d/saslauthd restart'), we can test the authentication: testsaslauthd -u userid -p password. (The password cannot be @@ -1039,41 +1185,43 @@ prompted, so you may want to create a dummy user.) If everything goes through, it is now time to modify Postfix's main.cf: (Documentation: http://www.postfix.org/SASL_README.htm) -smtpd_sasl_authenticated_header = yes -smtpd_sasl_auth_enable = yes -smtpd_sasl_local_domain = -smtpd_sasl_exceptions_networks = $mynetworks -smtpd_sasl_security_options = noanonymous, noplaintext -smtpd_sasl_tls_security_options = noanonymous -broken_sasl_auth_clients = yes -smtpd_sasl_type = cyrus -smtpd_sasl_path = smtpd - -smtp_sasl_auth_enable = yes -smtp_sasl_password_maps = hash:$config_directory/sasl_passwd -smtp_sasl_security_options = noanonymous, noplaintext -smtp_sasl_tls_security_options = noanonymous - -# `sasl_passwd' may be empty but Postfix complains if it doesn't exist - -And still in the main.cf, add a policy stating that authenticate users are -allowed to connect and send mail: + :: /etc/postfix/main.cf + [...] + smtpd_sasl_authenticated_header = yes + smtpd_sasl_auth_enable = yes + smtpd_sasl_local_domain = + smtpd_sasl_exceptions_networks = $mynetworks + smtpd_sasl_security_options = noanonymous, noplaintext + smtpd_sasl_tls_security_options = noanonymous + broken_sasl_auth_clients = yes + smtpd_sasl_type = cyrus + smtpd_sasl_path = smtpd + smtp_sasl_auth_enable = yes + smtp_sasl_password_maps = hash:$config_directory/sasl_passwd + # Note: `sasl_passwd' may be empty but Postfix complains if it doesn't exist + smtp_sasl_security_options = noanonymous, noplaintext + smtp_sasl_tls_security_options = noanonymous + smtpd_recipient_restrictions = + permit_mynetworks + permit_sasl_authenticated + [...] + [...] -smtpd_recipient_restrictions = - permit_mynetworks - permit_sasl_authenticated - [...] Finally, we can add the submission service to our master.cf, with customized policy: -submission inet n - - - - smtpd - -o smtpd_tls_security_level=encrypt - -o smtpd_sasl_auth_enable=yes - -o smtpd_client_restrictions=permit_sasl_authenticated,reject - -o milter_macro_daemon_name=ORIGINATING - -We can now restart Postfix: `/etc/init.d/postfix restart'. + :: /etc/postfix/master.cf + [...] + submission inet n - - - - smtpd + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING + [...] +We now have to restart Postfix: `/etc/init.d/postfix restart'. (Maybe `postfix reload' +is enough actually.) **** Anonymize the senders If RoudCube automatically anonymize the sender (by simply shortening the @@ -1082,51 +1230,51 @@ connect via ESMTP/ESMTPS/ESMTPA/ESMTPSA. Here are a couple of traces we want to obfuscate, to prevent the recicipient and/or the intermediate SMTP relays to track the sender. -Received: from localhost (smtp.fripost.org [127.0.0.1]) - by fripost.org (Postfix) with ESMTP id C9DAB841F4 - for <recipient@example.org>; Thu, 22 Mar 2012 16:27:56 +0100 (CET) -Received: from fripost.org ([127.0.0.1]) - by localhost (smtp.fripost.org [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 8onAXWOvImDh for <recipient@example.org>; - Thu, 22 Mar 2012 16:27:56 +0100 (CET) -Received: from webmail.fripost.org (localhost [IPv6:::1]) - by fripost.org (Postfix) with ESMTP id 3ADAB8243D - for <recipient@example.org>; Thu, 22 Mar 2012 16:27:56 +0100 (CET) -Received: from 192.168.1.5 - (SquirrelMail authenticated user username) - by webmail.fripost.org with HTTP; - Thu, 22 Mar 2012 16:27:56 +0100 - -Received: from localhost (smtp.fripost.org [127.0.0.1]) - by fripost.org (Postfix) with ESMTP id 2D1098243D - for <recipient@example.org>; Thu, 22 Mar 2012 16:36:36 +0100 (CET) -Received: from fripost.org ([127.0.0.1]) - by localhost (smtp.fripost.org [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id Hr2J-eRTN0jI for <recipient@example.org>; - Thu, 22 Mar 2012 16:36:35 +0100 (CET) -Received: from client.example.org (client.example.org [192.168.1.1]) - (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) - (Client CN "client.example.org", Issuer "example.org" (not verified)) - by machine.org (Postfix) with ESMTPS id DA22981B95 - for <recipient@example.org>; Thu, 22 Mar 2012 16:36:35 +0100 (CET) -Received: (nullmailer pid 5057 invoked by uid 0); - Thu, 22 Mar 2012 15:36:34 -0000 - -Received: from localhost (smtp.fripost.org [127.0.0.1]) - by fripost.org (Postfix) with ESMTP id DBAFE816BB - for <recipient@example.org>; Thu, 22 Mar 2012 14:48:01 +0100 (CET) -Received: from fripost.org ([127.0.0.1]) - by localhost (smtp.fripost.org [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id Upen4QhYpKf4 for <recipient@example.org>; - Thu, 22 Mar 2012 14:48:01 +0100 (CET) -Received: from client.example.org (client.example.org [192.168.1.5]) - (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) - (Client CN "", Issuer "" (not verified)) - (Authenticated sender: username) - by fripost.org (Postfix) with ESMTPSA id 40284804F5 - for <recipient@example.org>; Thu, 22 Mar 2012 14:48:01 +0100 (CET) -Received: by client.example.org (Postfix, from userid 1000) - id 1D24F41747; Thu, 22 Mar 2012 14:48:00 +0100 (CET) + Received: from localhost (smtp.fripost.org [127.0.0.1]) + by fripost.org (Postfix) with ESMTP id C9DAB841F4 + for <recipient@example.org>; Thu, 22 Mar 2012 16:27:56 +0100 (CET) + Received: from fripost.org ([127.0.0.1]) + by localhost (smtp.fripost.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 8onAXWOvImDh for <recipient@example.org>; + Thu, 22 Mar 2012 16:27:56 +0100 (CET) + Received: from webmail.fripost.org (localhost [IPv6:::1]) + by fripost.org (Postfix) with ESMTP id 3ADAB8243D + for <recipient@example.org>; Thu, 22 Mar 2012 16:27:56 +0100 (CET) + Received: from 192.168.1.5 + (SquirrelMail authenticated user username) + by webmail.fripost.org with HTTP; + Thu, 22 Mar 2012 16:27:56 +0100 + + Received: from localhost (smtp.fripost.org [127.0.0.1]) + by fripost.org (Postfix) with ESMTP id 2D1098243D + for <recipient@example.org>; Thu, 22 Mar 2012 16:36:36 +0100 (CET) + Received: from fripost.org ([127.0.0.1]) + by localhost (smtp.fripost.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id Hr2J-eRTN0jI for <recipient@example.org>; + Thu, 22 Mar 2012 16:36:35 +0100 (CET) + Received: from client.example.org (client.example.org [192.168.1.1]) + (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) + (Client CN "client.example.org", Issuer "example.org" (not verified)) + by machine.org (Postfix) with ESMTPS id DA22981B95 + for <recipient@example.org>; Thu, 22 Mar 2012 16:36:35 +0100 (CET) + Received: (nullmailer pid 5057 invoked by uid 0); + Thu, 22 Mar 2012 15:36:34 -0000 + + Received: from localhost (smtp.fripost.org [127.0.0.1]) + by fripost.org (Postfix) with ESMTP id DBAFE816BB + for <recipient@example.org>; Thu, 22 Mar 2012 14:48:01 +0100 (CET) + Received: from fripost.org ([127.0.0.1]) + by localhost (smtp.fripost.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id Upen4QhYpKf4 for <recipient@example.org>; + Thu, 22 Mar 2012 14:48:01 +0100 (CET) + Received: from client.example.org (client.example.org [192.168.1.5]) + (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) + (Client CN "", Issuer "" (not verified)) + (Authenticated sender: username) + by fripost.org (Postfix) with ESMTPSA id 40284804F5 + for <recipient@example.org>; Thu, 22 Mar 2012 14:48:01 +0100 (CET) + Received: by client.example.org (Postfix, from userid 1000) + id 1D24F41747; Thu, 22 Mar 2012 14:48:00 +0100 (CET) (The first one was sent using a SquirrelMail; The second using ESMTPS; And the third using ESMTPSA). @@ -1150,22 +1298,22 @@ valid certificate, and in case of an SMTP relay, the early part of the trace (before it entered our Postfix sever) remains unchanged. For example, the early part of the third trace would become: -Received: from localhost (localhost [127.0.0.1]) - (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) - (Client CN "", Issuer "" (not verified)) - (Authenticated sender: username) - by fripost.org (Postfix) with ESMTPSA id 40284804F5 - for <recipient@example.org>; Thu, 22 Mar 2012 14:48:01 +0100 (CET) -Received: by client.example.org (Postfix, from userid 1000) - id 1D24F41747; Thu, 22 Mar 2012 14:48:00 +0100 (CET) + Received: from localhost (localhost [127.0.0.1]) + (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) + (Client CN "", Issuer "" (not verified)) + (Authenticated sender: username) + by fripost.org (Postfix) with ESMTPSA id 40284804F5 + for <recipient@example.org>; Thu, 22 Mar 2012 14:48:01 +0100 (CET) + Received: by client.example.org (Postfix, from userid 1000) + id 1D24F41747; Thu, 22 Mar 2012 14:48:00 +0100 (CET) (the other field remaining unchanged). This is also made possible by smtp_header_checks. In that case, the corresponding file would contain the following rexep, forging the header by pretending that the client has EHLO'ed from localhost: - /^Received:\s+from (\S+)\s+\(\S+\s+\S+\)(.*\sby fripost\.org \(Postfix\)\s+with E?SMTP(S|A|SA)\W.*)$/ - REPLACE Received: from localhost (localhost [127.0.0.1])${2} + /^Received:\s+from (\S+)\s+\(\S+\s+\S+\)(.*\sby fripost\.org \(Postfix\)\s+with E?SMTP(S|A|SA)\W.*)$/ + REPLACE Received: from localhost (localhost [127.0.0.1])${2} You can try out the regexp using "postmap -h -q - regexp:smtp_header_checks < email" (where `email' may also be a bunch of traces). |