From b302204ce7ddf7fb15284fd7c1cba19b279ba3c2 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 20 Aug 2012 00:21:05 +0200 Subject: Reorganizing the LDAP-related sections. --- fripost-docs.org | 530 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 317 insertions(+), 213 deletions(-) diff --git a/fripost-docs.org b/fripost-docs.org index 3211faf..794705a 100644 --- a/fripost-docs.org +++ b/fripost-docs.org @@ -278,7 +278,9 @@ LDAP server = the server that stores users credentials and various other informa smarthost = the server receiving email from the internet (configured as MX) -outgoing SMTP = a SMTP server that can relay mails of authenticated users (via SASL). +outgoing SMTP = the message transfer agent (MTA), that will relay emails originating from our network. + +incoming SMTP = the mail submission agent (MSA), that will receive emails from our users (via ESMTPSA). *** Configuring an SSH tunnel between two hosts @@ -355,7 +357,7 @@ host using something like: telnet localhost $ORIGIN_PORT -*** Configuring the LDAP server +*** Configuring the main LDAP server (provider) On Debian Squeeze, OpenLDAP's configuration no longer uses `/etc/ldap/slapd.conf' (by default, but may completely ignore it in the future), but the @@ -395,18 +397,90 @@ SLAPD_SERVICES="ldap:///127.0.0.1:389 ldapi:///" wrapped into SSH or SSL/TLS tunnels.) (Note: Unless specified, connections through the sockets bind with the users -permissions, hence regular users may not be able to explore the tree.) +permissions, hence regular users may not be able to explore the directory.) We can check the configuration with - ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" + sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" + +and modify the directory using a .ldif file with + + sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f "" + +(granted writing rights, see below) + +**** Performance considerations + +References: +- https://wiki.zimbra.com/wiki/OpenLDAP_Performance_Tuning_5.0 +- http://www.openldap.org/doc/admin24/tuning.html + + +1. On single- and dual-core systems, change the maximum number of +threads to 8. (The default, 16, is fine for 4- and 8-core systems.) -and modify a .ldif file with + :: ldapmodify -Y EXTERNAL -H ldapi:/// + + dn: cn=config + changetype: modify + add: olcThreads + olcThreads: 8 + + +2. It may be a good idea to modify DB_CONFIG, depending on the output +of + + db4.8_stat -m -h /var/lib/ldap/ | head -16 + +(For optimal performance, the Requested pages found in the cache +should be above 95%, and the pages forced from the cache should be 0.) + +and - ldapmodify -Y EXTERNAL -H ldapi:/// -f "" + db4.8_stat -m -h /var/lib/ldap/ | head -16 + +(For optimal performance, usage should be within 85% of the configured +values.) + +**** Database configuration + + :: mkdir -m 0700 /var/lib/ldap/mailHosting && chown openldap:openldap /var/lib/ldap/mailHosting + +We may want to remove the existing (default, empty) database on a fresh installation: + +:HIDDEN: +slapcat -n1 # Ensure it is empty +/etc/init.d/slapd stop +mv /var/lib/ldap/DB_CONFIG /var/lib/ldap/mailHosting +find /var/lib/ldap/ -maxdepth 1 -type f -delete +rm -f '/etc/ldap/slapd.d/cn=config/olcDatabase={1}hdb.ldif' +:END: + +And define ours: + + :: ldapadd -Y EXTERNAL -H ldapi:/// + + dn: olcDatabase=hdb,cn=config + objectClass: olcDatabaseConfig + objectClass: olcHdbConfig + olcDbDirectory: /var/lib/ldap/mailHosting + olcSuffix: o=mailHosting,dc=fripost,dc=org + olcLastMod: TRUE + olcDbCheckpoint: 512 30 + # Require LDAPv3 protocol and authentication prior to directory + # operations. + olcRequires: LDAPv3 authc + # We don't want to give "canCreate{Alias,ML}" write access to alias/ml + # attributes. + olcAddContentAcl: FALSE + # The root user has all rights on the whole database (when SASL-binding + # on a UNIX socket). + olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth **** Fripost's schema +TODO: upgrade + 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). @@ -478,35 +552,18 @@ Jamm's (http://jamm.sourceforge.net/howto/html/implementation.html). 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) - -TODO: Because of the use of `mailLocalAddress', we cannot use wildcard on aliases -with the current schema. It should be amended as follows: - - olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.3 NAME 'mailAliasGoto' - DESC 'The target of e-mail virtual aliases.' - EQUALITY caseIgnoreIA5Match - SUBSTR caseIgnoreIA5SubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE ) - olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.4 NAME 'mailAliasFrom' - DESC 'The login part of virtual aliases.' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) - olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.2 NAME 'virtualAliases' - SUP top STRUCTURAL - DESC 'Virtual Aliases.' - MUST ( mailAliasGoto $ mailAliasFrom $ isActive ) +`sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config"', or read +http://www.openldap.org/doc/admin24/schema.html#Attribute%20Type%20Specification . +(For instance, 1.3.6.1.4.1.1466.115.121.1.26 is a IA5String, meaning unicode is +allowed.) +We can now add it to the schema directory: -We can now add it to the schema list: - - ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/fripost.ldif + sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/fripost.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.) +`/etc/ldap/slapd.d/cn=config/cn=schema/' and to restart slapd. Ensure that nothing +[databases, ACL, indices,...] are making use of the schema, of course.) Note: If the LDIF files our schema depends on are not in loaded (in `/etc/ldap/slapd.d/cn=config/cn=schema/'), @@ -520,21 +577,21 @@ following: 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 '. +and add with `sudo ldapadd -Y EXTERNAL -H ldapi:/// -f '. [TODO: that's just ugly. Find a better way.] - ***** Add custom indexes -The default indexes below are not enough for our purpose, since we will heavily -be looking for e.g., the `uid' attribute. +TODO: upgrade - :: ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" +The default indexes below are not enough for our purpose, since e.g., +Postfix will heavily be looking for e.g., the `uid' attribute. + + :: sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" olcDbIndex [...] olcDbIndex: objectClass eq - - :: /etc/ldap/fripost/indexes.ldif + :: /etc/ldap/fripost/index.ldif dn: olcDatabase={1}hdb,cn=config changetype: modify @@ -576,7 +633,7 @@ TODO: After having amended the schema as specified above, we'll also need a olcDbIndex: mailAliasGoto,mailAliasFrom eq,sub -ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/indexes.ldif +sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/index.ldif :: ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" @@ -592,22 +649,27 @@ ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/indexes.ldif olcDbIndex: owner eq -Note: We can add indexes on a populated database, but then we need to reindex the tree: +Note: We can add indexes on a populated database, but then we need to reindex the directory: sudo /etc/init.d/slapd stop - sudo -u openldap slapindex + sudo -u openldap slapindex -b 'o=mailHosting,dc=fripost,dc=org' sudo /etc/init.d/slapd start ***** Restrict the access -The default ACL is not restrictive enough for our purpose. +TODO: upgrade + +The default ACL is not restrictive enough for our purpose: We don't want +the services to see passwords, and the users should see/edit only the +relevant bits. + Note: The ACLs are evaluated in order, hence the more specific rules should come first. We are using the so-called "Sets" to let the users manage their domain themselves. See section 8.5 "Sets - Granting rights based on relationships" in LDAP's manual http://www.openldap.org/doc/admin24/access-control.html for details. - :: ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" + :: sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" olcAccess [...] 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 @@ -679,14 +741,14 @@ ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/acl.ldif [...] Note: Users are allowed to manage their domain, but an admin is needed to add a domain to the -tree. A possibility to avoid that with a web-form is to send a mail to the postmaster@example.org +directry. A possibility to avoid that with a web-form is to send a mail to the postmaster@example.org (or even to the mail that appears in the WHOIS) with a confirmation hash. That would simply require a new ACL with writable [ou=virtual,...]/children, and [dc=...,ou=virtual,...]/entry. (And probably a "semi-admin" with only these rights.) -**** Create the base tree +**** Create the base entries - :: /etc/ldap/fripost/base.ldif + :: ldapadd -xWD cn=admin,dc=fripost,dc=org dn: o=mailHosting,dc=fripost,dc=org objectClass: organization @@ -704,15 +766,13 @@ a new ACL with writable [ou=virtual,...]/children, and [dc=...,ou=virtual,...]/e objectClass: organizationalUnit description: E-mail services -ldapadd -xWD cn=admin,dc=fripost,dc=org -f /etc/ldap/fripost/base.ldif +To delete an entry (add `-r' to delete the whole sub-tree): + ldapdelete -xWD cn=admin,dc=fripost,dc=org 'dc=example.org,ou=virtual,o=mailHosting,dc=fripost,dc=org' -To delete a leaf (`-r' to delete the whole sub-tree): - ldapdelete -r -xWD cn=admin,dc=fripost,dc=org 'dc=example.org,ou=virtual,o=mailHosting,dc=fripost,dc=org' +**** Populate the directory -**** Populate the tree - - :: /tmp/populate.ldif + :: ldapadd -xWD cn=admin,dc=fripost,dc=org dn: cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org objectClass: simpleSecurityObject @@ -760,18 +820,18 @@ To delete a leaf (`-r' to delete the whole sub-tree): mailLocalAddress: user-alias isActive: TRUE -ldapadd -xWD cn=admin,dc=fripost,dc=org -f /tmp/populate.ldif - Note: This should obviously be wrapped in a script; `ldapadd' reads the standard input, so there's no need to write on disk. The salted SHA-1 can be created with e.g., `slappasswd -h "{SSHA}"'. -**** Check the SASL binds (authentication) +**** Check the ACLs + +TODO: upgrade `slapacl' is an helpful tool to debugs the ACLS. For instance, to check what are the rights of user@fripost.org on the domain example.org, we can run: - slapacl -b 'dc=example.org,ou=virtual,o=mailHosting,dc=fripost,dc=org' -D 'uid=user,dc=fripost.org,ou=virtual,o=mailHosting,dc=fripost,dc=org' + sudo slapacl -b 'dc=example.org,ou=virtual,o=mailHosting,dc=fripost,dc=org' -D 'uid=user,dc=fripost.org,ou=virtual,o=mailHosting,dc=fripost,dc=org' We can also check ACLs with concrete examples: @@ -781,11 +841,9 @@ should return the whole dn: "uid=user,dc=fripost.org,ou=virtual,o=mailHosting,dc=fripost,dc=org" -**** Check the ACL - ***** Admin -`slpacat' (run as root) dumps everything in the tree, including the (hashed) +`slpacat' (run as root) dumps everything in the subtree, including the (hashed) passwords. So should ldapsearch -xWD "cn=admin,dc=fripost,dc=org" -b 'ou=virtual,o=mailHosting,dc=fripost,dc=org' @@ -814,7 +872,7 @@ should return all the information for this very user, but not e.g., the password The user should be able to change his/her password, and aliases in his/her own domain: - :: /tmp/usermod.ldif + :: ldapmodify -xWD "uid=user,dc=fripost.org,ou=virtual,o=mailHosting,dc=fripost,dc=org" dn: uid=user,dc=fripost.org,ou=virtual,o=mailHosting,dc=fripost,dc=org changetype: modify @@ -826,7 +884,6 @@ The user should be able to change his/her password, and aliases in his/her own d add: mailLocalAddress mailLocalAddress: user-alias2@example.org -ldapmodify -xWD "uid=user,dc=fripost.org,ou=virtual,o=mailHosting,dc=fripost,dc=org" -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.] @@ -844,75 +901,33 @@ We now ensure that the leaf has been updated: On other modifications, for instance of `maildir', `ldapmodify' should refuse with `Insufficient access (50)'. -**** Partial replication on the MXs +**** Using SyncProv, to define our main server as the provider -In case the LDAP goes down, we partly (e.g., we omit the passwords) replicate the LDAP -tree on the MXs. +Our main LDAP server (provider) will sent periodic updates of the directory to +other servers (consumers, running on the MX:s). -Documentation: http://www.openldap.org/doc/admin22/syncrepl.html - http://www.zytrax.com/books/ldap/ch7/#ol-syncrepl-rap +References: +- http://www.openldap.org/doc/admin24/replication.html#Syncrepl +- http://www.zytrax.com/books/ldap/ch7/#ol-syncrepl-rap +- man 5 slapo-syncprov -***** Installation - -Cf. installation of the master LDAP server. -(We also need to install fripost's schema and indexes.) - -In the rest of this section, we assume there is a tunnel from the master -LDAP server to the slave (i.e., ldap://127.0.0.1:3890 on the slaves actually -speaks to the master). + :: ldapmodify -Y EXTERNAL -H ldapi:/// -Following LDAP's terminology, the master server is also called "production", -and the slave is known as "consumer". - -***** Using syncprov (on the master) - -We first need to load the module `syncprov.la'. - - :: /etc/ldap/fripost/modules.ldif - dn: cn=module{0}, cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov.la -ldapmodify -Y EXTERNAL -H ldapi:/// -f modules.ldif - -The master can now define itself as the provider. - - :: /etc/ldap/fripost/syncprov.ldif + :: ldapadd -Y EXTERNAL -H ldapi:/// dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov - # contextCSN saved to database every 50 updates or 5 minutes + # contextCSN saved to database every 50 updates or 5 + # minutes olcSpCheckpoint: 50 5 - -ldapadd -Y EXTERNAL -H ldapi:/// -f syncprov.ldif - -***** Using syncrepl (on the slave) - - :: /etc/ldap/fripost/syncrepl.ldif - - dn: olcDatabase={1}hdb,cn=config - changetype: modify - replace: olcSyncRepl - olcSyncRepl: rid=000 - provider=ldap://127.0.0.1:3890 - type=refreshAndPersist - retry="5 5 300 +" - searchbase="o=mailHosting,dc=fripost,dc=org" - attrs="*,+" - scope=sub - schemachecking=off - bindmethod=simple - binddn="cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org" - credentials="xxxxxx" - -ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/syncrepl.ldif - -(Since we in our case we have several slaves, we may want to increment the -rid.) + syncprov-reloadhint: TRUE *** Configuring the main IMAP server **** Install packages @@ -923,91 +938,27 @@ sudo aptitude install postfix postfix-ldap TODO: add file contents -**** Setting up the MDA - -# squeeze has dovecot-1.2. upgrade notes: -# - we might want to upgrade to their sieve (instead of cmusieve) -# - we want to add the -s flag to deliver in master.cf - -***** Installing - -sudo aptitude install dovecot-imapd - -***** Configuring - - -:: /etc/dovecot/dovecot.conf - - protocol lda { - # Address to use when sending rejection mails. - postmaster_address = postmaster@fripost.org - - # Hostname to use in various parts of sent mails, eg. in Message-Id. - # Default is the system's real hostname. - hostname = imap.fripost.org - - # Support for dynamically loadable plugins. mail_plugins is a space separated - # list of plugins to load. - #mail_plugins = - #mail_plugin_dir = /usr/lib/dovecot/modules/lda - - # Binary to use for sending mails. - sendmail_path = /usr/lib/sendmail - - # UNIX socket path to master authentication server to find users. - auth_socket_path = /var/run/dovecot/auth-master - - # Enabling Sieve plugin for server-side mail filtering - mail_plugins = cmusieve - } - [...] - - ## dovecot-lda specific settings - ## - socket listen { - master { - path = /var/run/dovecot/auth-master - mode = 0600 - user = xxx # User running Dovecot LDA - #group = mail # Or alternatively mode 0660 + LDA user in this group - } - } - -:: /etc/postfix/master.cf - - dovecot unix - n n - - pipe - flags=DRhu user=xxx:xxx argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient} -n - - -:: /etc/postfix/main.cf - virtual_mailbox_domains = ldap:$config_directory/ldap/ldap_virtual_mailbox_domains.cf virtual_mailbox_maps = ldap:$config_directory/ldap/ldap_virtual_mailbox_maps.cf virtual_alias_maps = ldap:$config_directory/ldap/ldap_virtual_alias_maps.cf - + ldap:$config_directory/ldap/ldap_virtual_alias_catchall_maps.cf [...] - virtual_transport = dovecot - dovecot_destination_recipient_limit = 1 - -http://wiki.dovecot.org/LDA/Postfix -http://www.tehinterweb.co.uk/roundcube/#pisieverules - +***** Virtual lookups -On the MX's, the slave (a partial replicate of the main LDAP server server) -may only listen on a UNIX socket in Postfix's chroot jail; To specify that, -in `/etc/default/slapd', change `SLAPD_SERVICES' to +Ideally, Postfix would send the request to a UNIX socket (hence on the MX:s, +OpenLdap would not listen to the network). Note that the socket has to be in +Postfix's chroot jail; To specifify that, change `SLAPD_SERVICES' in +`/etc/default/slapd' to SLAPD_SERVICES="ldapi://%2Fvar%2Fspool%2Fpostfix%2Fvar%2Frun%2Fldapi/????x-mod=0777" -Note that in the configuration files below, the `server_host' is relative -to Postfix's jail, hence one should drop the prefix "%2Fvar%2Fspool%2Fpostfix". -On the other hand, to test the files with `postmap' one has to put back -the prefix. - +Note that in the configuration files below, the `server_host' is relative to +Postfix's jail, hence one should drop the prefix "/var/spool/postfix". But to +test the files with `postmap' one has to put back the prefix (or chroot first). -TODO: Postfix 2.7 does not support SASL binds. Hence one cannot SASL bind on +TODO: Postfix 2.7 does not support SASL binds. Hence one cannot SASL-bind to the socket with the EXTERNAL mechanism, which leads to a flood of warnings "connection_read(XX): no connection!" in the syslog. One can also reproduce the warning with @@ -1017,16 +968,20 @@ instead of the proper (The first one performs a simple bind and does not unbind properly, while the second one is safe and performs a SASL bind with the EXTERNAL mechanism.) -See also - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=643970 - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=660223 - http://www.openldap.org/lists/openldap-software/200811/msg00078.html +See also: +- http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=643970 +- http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=660223 +- http://www.openldap.org/lists/openldap-software/200811/msg00078.html + +TODO: For the time being, we stick to simple binds on 127.0.0.1:389, but when +"wheezy" will be the next Debian stable, we will do the following instead [Not +tested] -TODO: In the time being, we stick to simple binds on 127.0.0.1:389, but with -Postfix 2.8, one could do [Not tested] bind = sasl sasl_mechs = EXTERNAL +This will be both more secure (SASL vs. simple bind) and efficient (UNIX socket +vs. inet). :: /etc/postfix/ldap/ldap_virtual_mailbox_domains.cf @@ -1101,12 +1056,77 @@ Note: There is no way to get rid of the warning `Fixed query_filter [...] is probably useless'. It is harmless in our case, since the search base is precise enough. However, we add a logcheck exception not to be flooded. +TODO: That will change with the new schema. + +**** Setting up the MDA + +# squeeze has dovecot-1.2. upgrade notes: +# - we might want to upgrade to their sieve (instead of cmusieve) +# - we want to add the -s flag to deliver in master.cf + +***** Installing + +sudo aptitude install dovecot-imapd + +***** Configuring + +:: /etc/dovecot/dovecot.conf + + protocol lda { + # Address to use when sending rejection mails. + postmaster_address = postmaster@fripost.org + + # Hostname to use in various parts of sent mails, eg. in Message-Id. + # Default is the system's real hostname. + hostname = imap.fripost.org + + # Support for dynamically loadable plugins. mail_plugins is a space separated + # list of plugins to load. + #mail_plugins = + #mail_plugin_dir = /usr/lib/dovecot/modules/lda + + # Binary to use for sending mails. + sendmail_path = /usr/lib/sendmail + + # UNIX socket path to master authentication server to find users. + auth_socket_path = /var/run/dovecot/auth-master + + # Enabling Sieve plugin for server-side mail filtering + mail_plugins = cmusieve + } + + [...] + + ## dovecot-lda specific settings + ## + socket listen { + master { + path = /var/run/dovecot/auth-master + mode = 0600 + user = xxx # User running Dovecot LDA + #group = mail # Or alternatively mode 0660 + LDA user in this group + } + } + +:: /etc/postfix/master.cf + + dovecot unix - n n - - pipe + flags=DRhu user=xxx:xxx argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient} -n + + +:: /etc/postfix/main.cf + + virtual_transport = dovecot + dovecot_destination_recipient_limit = 1 + +http://wiki.dovecot.org/LDA/Postfix +http://www.tehinterweb.co.uk/roundcube/#pisieverules **** Test delivery sudo mkdir -p /home/mail/virtual/fripost.org/ - :: /tmp/example.ldif + :: ldapadd -xWD cn=admin,dc=fripost,dc=org dn: dc=fripost.org,ou=virtual,o=mailHosting,dc=fripost,dc=org objectClass: virtualDomain @@ -1117,13 +1137,12 @@ sudo mkdir -p /home/mail/virtual/fripost.org/ userPassword: test666 isActive: TRUE -ldapadd -xWD cn=admin,dc=fripost,dc=org -f /tmp/example.ldif sudo /etc/init.d/postfix restart echo "test at `date`" | mail -s "test" exempel@fripost.org -**** Configuring dovecot +**** Configuring Dovecot sudo aptitude install dovecot-imapd @@ -1169,13 +1188,13 @@ userdb static { user = nobody :END: -**** Use LDAP authenticate binds, and LDAP user queries. +***** Use LDAP authenticate binds, and LDAP user queries. -Instead of making a SQL query to fetch the (hashed) passwords, which implies to -expose all credentials to Dovecot, an other approach is to forward the login -information to our LDAP server, that will match it against the hashed copy contained -in its database. This way if your IMAP server is compromised, the attacker will not -have access to all the e-mails and user credentials. +Instead of making a LDAP query to fetch the (hashed) passwords, which implies +to expose all (hashed) credentials to Dovecot, an other approach is to forward +the login information to our LDAP server, that will match it against the hashed +copy contained in its database. This way if your IMAP server is compromised, +the attacker will not have access to all the e-mails and user credentials. Documentation: http://wiki2.dovecot.org/HowTo/DovecotOpenLdap @@ -1223,18 +1242,101 @@ smarthosts. **** Prerequisites Before this can work we must make sure that: -- the RDAP replication is working -- there is an SSH tunnel for the smtp +- SyncProv is configured on our main LDAP server, and +- There is an SSH tunnel for the smtp. If they are both setup, we can configure postfix on the smarthost to relay emails through the tunnel. +**** Configuring a partial replicate of the LDAP directory + +Partial, since we will restrict the replication to what is needed for Postfix +virtual lookups. In particular, the passwords will not be replicated. + +Refererences: +- http://www.openldap.org/doc/admin24/replication.html#Syncrepl +- http://www.zytrax.com/books/ldap/ch7/#ol-syncrepl-rap + +In the rest of this section, we assume there is a tunnel from the provider +LDAP server to the consumer (i.e., ldap://127.0.0.1:3890 on the MX actually +speaks to the the main provider). + +***** Installation + +Cf. installation on the main LDAP server. (We also need to install Fripost's +schema and indexes, but not the ACLs.) + +***** Using SyncRepl + + :: ldapmodify -Y EXTERNAL -H ldapi:/// + + dn: olcDatabase={1}hdb,cn=config + changetype: modify + replace: olcSyncRepl + # Increase the rid for the different consumers + olcSyncRepl: rid=000 + provider=ldap://127.0.0.1:3890 + bindmethod=simple + binddn="cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org" + credentials="xxxxxx" + type=refreshAndPersist + retry="5 5 300 +" + searchbase="ou=virtual,o=mailHosting,dc=fripost,dc=org" + filter="(&(|(objectClass=FripostVirtualDomain)(objectClass=FripostVirtualMailbox)(objectClass=FripostVirtualAlias)(objectClass=FripostVirtualML))(fripostIsStatusActive=TRUE))" + attrs="fripostIsStatusActive,fripostMaildrop,fvd,fvu,fva,fvml,fripostMLCommand,fripostMLManager" + scope=sub + schemachecking=off + +(Since in our case we have several slaves, we increment the rid accross the +different MX:s.) + +***** Restrict the access + +Ideally, we would use the following single ACL + + :: ldapmodify -Y EXTERNAL -H ldapi:/// + + dn: olcDatabase={1}hdb,cn=config + changetype: modify + replace: olcAccess + olcAccess: to dn.subtree="ou=virtual,o=mailHosting,dc=fripost,dc=dev" + by dn.exact="gidNumber=121+uidNumber=113,cn=peercred,cn=external,cn=auth" =rsd + +Were 113 and 121 are the uid and gid of the "postfix" user, respectively (which +you can find by typing `id postfix'). This would give =rsd access to the +"postfix" user on the directory, when SASL-binding on a UNIX socket. However +SASL binding have only been introduced with Postfix 2.8 [TODO: after upgrade, +change that], so we will use anonymous access for the time being. It isn't very +satisfactory, but since the replicate stripped out the irrelevant and critical +bits it should be fine for now. + +Ensure that authentication is not required, and that no ACL is defined (the +default is then to allow read access to anyone). + + :: sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" "(olcDatabase={1}hdb)" olcRequires olcAccess + [...] + olcRequires: LDAPv3 + **** Configuration files TODO: add the necessary configuration files -*** Configuring the outgoing SMTP -We will offer a SMTP relay for authenticated users (via SASL). +*** Configuring the outgoing SMTP (MTA) + +**** Install packages + +sudo aptitude install postfix postfix-ldap + +**** /etc/postfix/main.cf + +TODO: add file contents + +*** Configuring the Mail Submission Agent (MSA) + +We offer a SMTP relay for authenticated users (via SASL). Currently the MSA and +MTA are hosted on the same machine (gnu). + +Firewall: The MSA needs 587/TCP in, and the MTA 25/TCP both in and out. **** Install packages @@ -1247,7 +1349,7 @@ In the rest of this section, we assume there is a tunnel from the master LDAP server to the machine that hosts SASLauthd (i.e., ldap://127.0.0.1:3890 on this machine actually speaks to the master). -**** Configure saslauthd +**** Configure SASLauthd :: /etc/default/saslauthd [...] @@ -1269,9 +1371,10 @@ this machine actually speaks to the master). ldap_filter: (&(objectClass=virtualMailbox)(uid=%U)(isActive=TRUE)) ldap_scope: base -We need to bind to `cn=SASLauth,...' here, because SASLauthd performs the search -before binding to the user (unlike Dovecot). Hence it needs to have read access -on the user's entry (except his/her password, of course). +We need to bind to `cn=SASLauth,...' here, because SASLauthd performs the +search before binding to the user (unlike Dovecot). Hence it needs to have read +access on the user's entry (except his/her password, of course). TODO: maybe +=sd access is enough actually? After restarting saslauthd (`/etc/init.d/saslauthd restart'), we can test the authentication: @@ -1371,6 +1474,7 @@ can be obtained by the command echo -ne '\000user@fripost.org\000user' | openssl base64 **** Anonymize the senders + If RoudCube automatically anonymize the sender (by simply shortening the trace), it's not the case (by default) for SquirrelMail, or when clients connect via ESMTP/ESMTPS/ESMTPA/ESMTPSA. Here are a couple of traces we want @@ -1438,7 +1542,7 @@ This possible by adding "smtp_header_checks = regexp:$config_directory/smtp_head in the Postfix's main.cf, with a suitable file "smtp_header_check" in the Postfix configuration directory. -Yet an other option is not to hide the trace, but rather forge it to +Yet another option is not to hide the trace, but rather forge it to pretend that the ESMTP/... connections are all coming from localhost. This way we are not hiding the fact that a client has logged in using a valid certificate, and in case of an SMTP relay, the early part of the -- cgit v1.2.3