Skip to content

Recentste berichten

  • After 13 and a bit it’s time for 13!
  • Na 13 en een beetje, komt 13?
  • Dining-out!
  • Lekker eten
  • Special night

Most Used Categories

  • Algemeen (190)
  • Algemeen @en (106)
  • Werk (83)
  • Lekker (eten en drinken) (55)
    • Recepten (8)
  • Motor (36)
  • Trouwen (27)
  • Fiets (25)
Skip to content

tom.scholten.nu

Tom's personal log

Subscribe
  • About me
  • Archief
    • CMS Framework
    • Postfix LDAP Howto
      • Postfix LDAP Howto
      • Postfix LDAP Howto v2.0 part two
    • Scroller.txt
  • Archive
  • aXBo – Testing
  • Cookie Policy
  • iPad
  • iPad
  • iPhone
    • iPhone (1.0)
      • Modem/proxy usage
    • iPhone (2.0)
  • iPhone
  • LoBySS
  • LoBySS
  • Music
  • Muziek
    • Never ending story (Limahl)
    • SnoWMusic
    • The Load out / Stay (just a little bit longer)
  • OSX Tools and Stuff
  • OSX Tools and Stuff
  • Over mij
  • Postfix LDAP Howto v2.1
  • Postfix LDAP Howto v2.1
  • Postfix MySQL howto v1.0
  • Recipes
  • Speedtouch SIP spoof (716)
  • WPG2
  • Wiki

Postfix LDAP Howto

.

.

.

.

.

.

.

.

.

.

.This howto is outdated and kept here for historical purposes, please proceed to the newer version by following this link.

.

.

.

.

.

.


 

 

  

Full-fledged Postfix using LDAP HOWTO

Postfix, LDAP, IMAP, WebMail, Virus- and spamscanning/checking mail system
by Tom Scholten and author of likewise documents

Special thanks to Richard from UnixGuru.nl

 

 

 


The document provides a description or howto if you will to build a unix-based postfix mailserver capable of multiple virtual domains and users based upon LDAP. There are other documents describing how to implement Postfix and LDAP, and this howto is based upon them, but is written as a 'from-scratch' to 'fully-operational' manual, as i found a great tutorial on Postfix-Mysql including a nice PHP admin frontend besides the great JAMM approach which has also a nice, but in java (server pages), admin tool. Plans for now are to deliver both a perl/cgi interface AND a PHP interface to administrate you're very own Postfix-LDAP mail system.

 


This page aims at describing how i installed and configured Postfix with virtual domains, ldap and virusscanning on a FreeBSD 5.x system
There is no reason why this wouldn’t work on any other UN*X system, including all flavors of linux, *bsd, hpux, tru64, solaris or aix. Maybe on SCO but i don’t like either there OS nor their attitude.
Ofcourse no responsibility or liability blah blah blah, to be continued

 

 


Heads up : The proposed mailserver in this document is using amavis for content scanning, i’m working on a second version of this document using MailScanner instead of amavis, hopefully with user-specific SpamAssassin rules in LDAP (using SA 3.x)

 


Installed software (on FreeBSD)

Installed packages from the portstree (in no particular order, let alone dependancy order)

  • procmail (3.22)
  • postfix (2.2.1)
  • courier-imap (3.0.4,1)
  • squirrelmail (1.4.3a)
  • apache2 (2.0.50)
  • php (4.3.7)
  • openldap (2.0.25)
  • clamav (0.74)
  • amavisd-new (20030616)
  • p5-SpamAssassin (2.63)

Assumptions

Assumptions made for this howto

  • The example domain name will be ‘example.org’
  • The virtual users (mail)directory store will live under /usr/virtual
  • The virtual user used is vmail (group vmail) uid/gid are both 2001
  • The scanner runs as vscan/vscan (2002/2002)

OpenLDAP configuration

First edit slapd.conf in /usr/local/etc/openldap, the example below does NOT have a safe password (secret), which you should create using slappasswd from the commandline. It asks you to type you’re password twice and then prints out the string to be used. You can use another (than SSHA, the default) algorythm, man slappasswd for more information! Also in the example below there are NO acl’s so anyone has access to you’re information, consider RTFM on (Open)LDAP to secure you’re LDAPtree some more.

slapd.conf

include         /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/etc/openldap/schema/mailserver.schema

#######################################################################
# ldbm database definitions
#######################################################################

database        ldbm
suffix          "dc=example,dc=org"

rootdn          "cn=Manager,dc=example,dc=org"
#rootpw          secret
rootpw		{SSHA}FyQuk6XJK4aYcz1fh6RhbG2g/CtvCtz3

# The database directory MUST exist prior to running slapd AND
# should only be accessable by the slapd/tools. Mode 700 recommended.
directory       /var/db/openldap-data

# Indices to maintain
index   objectClass     pres,eq
index   mail,cn         eq,sub

# logging
loglevel 256

OpenLDAP scheme for mailserver

Next, create the LDAPscheme to be used for our mailserver in /usr/local/etc/openldap/schema

The used mailserver.schema

#
# OID prefix: 1.3.6.1.4.1.12461
#
# Attributes: 1.3.6.1.4.1.12461.1.1
#

attributetype ( 1.3.6.1.4.1.12461.1.1.1 NAME 'postfixTransport'
DESC 'A string directing postfix which transport to use'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{20} SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.12461.1.1.2 NAME 'accountActive'
DESC 'A boolean telling whether an account is active or not'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.12461.1.1.3 NAME 'lastChange'
DESC 'Time in unix time of last change in entry'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )

#attributetype ( 1.3.6.1.4.1.12461.1.1.4 NAME 'jvd'
#        DESC 'A virtual domain managed by Jamm'
#        EQUALITY caseIgnoreIA5Match
#        SUBSTR caseIgnoreIA5SubstringsMatch
#        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

# The following attributes are borrowed from Courier's schema so that
# the Jamm Schema can live on its own.

attributetype ( 1.3.6.1.4.1.12461.1.1.5 NAME 'mailbox'
DESC 'The absolute path to the mailbox for a mail account in a non-default location'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.12461.1.1.6 NAME 'quota'
DESC 'A string that represents the quota on a mailbox'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.12461.1.1.7 NAME 'clearPassword'
DESC 'A separate text that stores the mail account password in clear text'
EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128})

attributetype ( 1.3.6.1.4.1.12461.1.1.8 NAME 'maildrop'
DESC 'RFC822 Mailbox - mail alias'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

attributetype ( 1.3.6.1.4.1.12461.1.1.9 NAME 'mailsource'
DESC 'Message source'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

# Back to more of Jamm specific attributes

attributetype ( 1.3.6.1.4.1.12461.1.1.10 NAME 'editAliases'
DESC 'A boolean telling whether a domain manager can edit Aliases'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.12461.1.1.11 NAME 'editAccounts'
DESC 'A boolean telling whether a domain manager can edit Accounts'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.12461.1.1.12 NAME 'editPostmasters'
DESC 'A boolean telling whether a domain manager can edit Postmasters'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.12461.1.1.13 NAME 'editCatchAlls'
DESC 'A boolean telling whether a domain manager can edit CatchAlls'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.12461.1.1.14 NAME 'delete'
DESC 'A boolean telling whether this item is marked for deletion'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )

#
# Objects: 1.3.6.1.4.1.12461.1.2
#

objectclass ( 1.3.6.1.4.1.12461.1.2.1 NAME 'mailAccount'
SUP top STRUCTURAL
DESC 'Mail account objects'
MUST ( mail $ homeDirectory $ mailbox $ accountActive $ lastChange $
delete )
MAY ( uidNumber $ gidNumber $ uid $ cn $ description $ quota $
userPassword $ clearPassword ) )

objectclass ( 1.3.6.1.4.1.12461.1.2.2 NAME 'mailAlias'
SUP top STRUCTURAL
DESC 'Mail aliasing/forwarding entry'
MUST ( name $ mail $ maildrop $ accountActive $ lastChange )
MAY ( mailsource $ cn $ description $ userPassword ) )

objectclass ( 1.3.6.1.4.1.12461.1.2.3 NAME 'mailDomain'
SUP domain STRUCTURAL
DESC 'Virtual Domain entry to be used with postfix transport maps'
MUST ( dc $ accountActive $ lastChange $ delete $ editAccounts $
editPostmasters )
MAY ( postfixTransport $ description  ) )
#        SUP top STRUCTURAL
#       MUST ( jvd $ accountActive $ lastChange $ delete $ editAccounts $

objectClass ( 1.3.6.1.4.1.12461.1.2.4 NAME 'mailPostmaster'
SUP top AUXILIARY
DESC 'Added to a mailAlias to create a postmaster entry'
MUST roleOccupant )

Ready, Aim, OpenLDAP

Now start up you’re OpenLDAP server either by hand or use /usr/local/etc/rc.d/slapd.sh start and verify that slapd is running (ps ax | egrep slap[d]). If it’s running were ready to fill …


OpenLDAP tree layout and initial ldif

This initial ldif will create you’re domains, so if you have many, just stick to one or two at the time to test out, were creating the following tree.

 

org
|
example----------Manager
|
mail
|
+----------------------------------+-----------------------------+----------------------------+
example.org somenudomain.nu someoldaccount.demon.org domain3.org

 

setup ldif file
warning! if you have openldap22 or above, you should add to the primary dc= objects the following lines (whatever is the dc declared, for the first entry below it becomes ‘example’ for the other (mail) object it becomes mail

 

objectClass: dcObject
dc: whatever
# example
dn: dc=example, dc=org
objectClass: top
objectClass: organization
objectClass: dcObject
o: example
dc: example

# MAnager
dn: cn=Manager,dc=example,dc=org
objectClass: top
objectClass: organizationalRole
cn: Manager

# mail, example
dn: dc=mail, dc=example, dc=org
objectClass: top
objectClass: organizationalunit
objectClass: dcObject
ou: mail
dc: mail

# example.org, mail, example
dn: dc=example.org, dc=mail, dc=example,dc=org
accountActive: TRUE
editPostmasters: TRUE
editAccounts: TRUE
objectClass: top
objectClass: mailDomain
dc: example.org
delete: FALSE
lastChange: 111
postfixTransport: virtual:

# somenudomain.nu, mail, example
dn: dc=somenudomain.nu, dc=mail, dc=example,dc=org
accountActive: TRUE
editPostmasters: TRUE
editAccounts: TRUE
objectClass: top
objectClass: mailDomain
dc: somenudomain.nu
delete: FALSE
lastChange: 111
postfixTransport: virtual:

# someoldaccount.demon.org, mail, example
dn: dc=someoldaccount.demon.org, dc=mail, dc=example,dc=org
accountActive: TRUE
editPostmasters: TRUE
editAccounts: TRUE
objectClass: top
objectClass: mailDomain
dc: someoldaccount.demon.org
delete: FALSE
lastChange: 111
postfixTransport: virtual:

# domain3.org, mail, example
dn: dc=domain3.org, dc=mail, dc=example,dc=org
accountActive: TRUE
editPostmasters: TRUE
editAccounts: TRUE
objectClass: top
objectClass: mailDomain
dc: domain3.org
delete: FALSE
lastChange: 111
postfixTransport: virtual:

cat FILENAME | ldapadd -x -D ‘cn=Manager,dc=example,dc=org’ -w secret to add the information to your LDAP server


OpenLDAP scripts

Using the script provide below we can add users, according to the domain setup shown below using the following commands
example

  • ./ldapadduser.pl vivian example.org "Secret123" mailbox | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret
  • ./ldapadduser.pl alexander example.org "Dog=Cr@zy" mailbox | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret
  • ./ldapadduser.pl roland_dg example.org "a1zihw" mailbox | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret
  • ./ldapadduser.pl postmaster example.org alexander@example.org,vivian@example.org alias | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret
  • ./ldapadduser.pl webmaster example.org john@webbuilders.com alias | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret
  • ./ldapadduser.pl "*" example.org vivian@example.org alias | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret

somenudomain.nu

  • ./ldapadduser.pl ian somenudomain.nu "vivian" mailbox | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret
  • ./ldapadduser.pl postmaster somenudomain.nu alexander@example.org alias | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret
  • ./ldapadduser.pl webmaster somenudomain.nu "w3bs1t3" mailbox | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret

someoldaccount.demon.org

  • ./ldapadduser.pl "*" someoldaccount.demon.org @somenudomain.nu alias | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret

domain3.org

  • ./ldapadduser.pl postmaster domain3.org alexander@example.org alias | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret
  • ./ldapadduser.pl webmaster domain3.org alexander@example.org alias | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret

And so, we should have created a tree looking like this, with vivian@example.org receiving all ‘non-existing-mailbox’ mail from example.org and all mail from ‘someoldaccount.demon.org’ delivered to somenudomain.nu (so you can email ian@someoldaccount.demon.org and still reach ian, whom (ofcourse) should have procmail or so set up to warn people about his changed domain name, but that’s outside the scope of this document). Also mind that postmaster@example.org is delivered to BOTH alexander AND vivian. The add-script just makes to ‘maildrop’s in the LDAP tree!

 

 

org
|
example----------Manager
|
mail
|
+----------------------------------+-----------------------------+----------------------------+
example.org somenudomain.nu someoldaccount.demon.org domain3.org
Vivian ian *@ -> somenudomain.nu postmaster
Alexander postmaster webmaster
Roland_dG webmaster
postmaster
webmaster
*@ -> vivian@example.org

 

perl script to generate ldif for changing/adding users (just use ldapmodify instead of the suggested ldapadd)

 

#!/usr/local/bin/perl
# ldapadduser.pl
#
# AddUser-LDAP: Generate User entry for adding in LDAP
# Author:       Raymond Ho
# History:      Modify from genuser.pl from
#               MacGyver aka Habeeb J. Dihu
# 20040601	Tom Scholten, modified to do much more than just adding
# Copyright (C) 2002, He Zhi Qiang Raymond.Ho

use Carp;
croak "Usage: $0 [accountname] [example.org] [cleartext-password|foo@bar.com{,bar@foo.com,com@foo.bar}] [mailbox|alias]

accountname being everything before the @ or if you would like a 'fallthrough/wildcard' match "*" (don't let shell interpret the *!!!)

examples
Create new mailbox for user132@domain1.org using password MySecretPw
$0 user132 domain1.org MySecretPw mailbox

Map whole domain4.org to domain5.org
$0 "*" domain4.org @domain5.org alias

Create fallthough catch for domain6.org to postmaster@domain6.org
$0 "*" domain6.org postmaster@domain6.org alias

Create a webmaster@domain3.org alias which expands to the scriptmanager and contentmanager addresses
$0 webmaster domain3.org scriptmanager@domain3.org,contentmanager@domain3.org alias

" unless $#ARGV == 3;

# Random salt.
$salt = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64];

# output list
$dn             = "dn: mail=$ARGV[0]@$ARGV[1],dc=$ARGV[1], dc=mail,dc=example, dc=orgn";
$change         = "lastChange: 1n";
$obj1           = "objectClass: topn";
if ( $ARGV[3] eq "mailbox" ) {
$obj2           = "objectClass: mailAccountn";
$mailbox        = "mailbox: $ARGV[1]/$ARGV[0]/Maildir/n";
$home           = "homeDirectory: /usr/virtualn";
$clearpwd       = "clearPassword: $ARGV[2]n";
$userpwd        = "userPassword: {crypt}".crypt($ARGV[2], $salt)."n";
$uid            = "uid: $ARGV[0]n";
$del            = "delete: FALSEn";
}
elsif ( $ARGV[3] eq "alias" ) {
$obj2           = "objectClass: mailAliasn";
@aliases        = split(/,/,$ARGV[2]);
foreach $alias (@aliases)
{
$maildrop       .= "maildrop: $aliasn";
}
if ( $ARGV[0] eq "*" ) {
$uid            = "name: @$ARGV[1]n";
} else {
$uid            = "name: $ARGV[0]n";
}
} else {
croak "Cannot continue, choose either mailbox or aliasn";
}
$at             = "accountActive: TRUEn";
#if ( $ARGV[0] eq "*" ) {
#        $mail           = "mail: @$ARGV[1]n";
#} else {
$mail           = "mail: $ARGV[0]@$ARGV[1]n";
#}

# output to stdin
print "$dn$change$uid$obj1$obj2$at$del$mail$home$mailbox$maildrop$clearpwd$userpwd";

print  "n# pipe this throug -> | ldapadd -x -D 'cn=Manager,dc=example,dc=org' -w secret <- to insert into ldapn";

OpenLDAP searching

Now let’s try to find our entries in LDAP Search domains in the tree
# ldapsearch -x -wsecret -D "cn=Manager, dc=example, dc=org" -s sub -b "dc=mail,dc=example,dc=org" "(&(objectClass=mailDomain)(accountActive=TRUE))" Search accounts in the tree
# ldapsearch -x -wsecret -D "cn=Manager, dc=example, dc=org" -s sub -b "dc=mail,dc=example,dc=org" "(&(objectClass=mailAccount)(accountActive=TRUE))" Search aliases in the tree
# ldapsearch -x -wsecret -D "cn=Manager, dc=example, dc=org" -s sub -b "dc=mail,dc=example,dc=org" "(&(objectClass=mailAlias)(accountActive=TRUE))"


ClamAV, virusscanner

ClamAV uses /usr/local/etc/clamav.conf for configuration, the only changes made were

  • changed localsocket to /var/amavis/clamd
  • changed user to vscan

AMaViS, contentscanner

AMaViS uses /usr/local/etc/amavis.conf for configuration,

  • changed MyDomain to example
  • changed user/group to vscan
  • Also change the settings described below;
-- replaced the lines containing
$final_virus_destiny      = D_BOUNCE;  # (defaults to D_BOUNCE)
$final_banned_destiny     = D_BOUNCE;  # (defaults to D_BOUNCE)
$final_spam_destiny       = D_BOUNCE;  # (defaults to D_REJECT)
$final_bad_header_destiny = D_PASS;  # (defaults to D_PASS), D_BOUNCE suggested
-- with the following lines
$final_virus_destiny = D_DISCARD; # (defaults to D_BOUNCE)
$final_banned_destiny = D_DISCARD; # (defaults to D_BOUNCE)
$final_spam_destiny = D_DISCARD; # (defaults to D_REJECT)
$final_bad_header_destiny = D_PASS; # (defaults to D_PASS), D_BOUNCE suggested
-- uncommented the following lines and the second was changed to /var/amavis/clamd
['Clam Antivirus-clamd',
&ask_daemon, ["CONTSCAN {}n", "/var/amavis/clamd"],
qr/bOK$/, qr/bFOUND$/,
qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
# NOTE: run clamd under the same user as amavisd;  match the socket
# name (LocalSocket) in clamav.conf to the socket name in this entry
# When running chrooted one may prefer: ["CONTSCAN {}n","$MYHOME/clamd"],

Starting the content scanner

Now startup clamav using /usr/local/etc/rc.d/clamav-clamd.sh start after updating /etc/rc.conf with a line

  • clamav_clamd_enable="YES"
  • clamav_freshclam_enable="YES"
  • amavisd_enable="YES"

The last being optional but recommended since it will update you’re database, so consider using it and also running /usr/local/etc/rc.d/clamav-freshclam.sh start. After making sure /var/amavis/clamd exists and (ofcourse) ps ax | egrep clam[d] returns a running process, start AMAVIS using /usr/local/etc/rc.d/amavisd.sh start and verify we can use it to send mail, as taken from the README from Amavis/Postfix.

--> $ telnet 127.0.0.1 10024
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 [127.0.0.1] ESMTP amavisd-new service ready
--> MAIL FROM:
250 2.1.0 Sender test@example.com OK
--> RCPT TO:
250 2.1.5 Recipient postmaster OK
--> DATA
354 End data with .
--> Subject: test1
-->
--> test1
--> .
*** 250 2.6.0 Ok, id=31859-01, from MTA: 250 Ok: queued as 90B7F16F--> MAIL FROM:
250 2.1.0 Sender test@example.com OK
--> RCPT TO:
250 2.1.5 Recipient postmaster OK
--> DATA
354 End data with .
--> Subject: test2 - virus test pattern
-->
--> X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
--> .
you should get one of the following replies (or similar), depending on
your $final_virus_destiny and *virus_lovers* settings in amavisd.conf:
*** 550 5.7.1 Message content rejected, id=16968-01 - VIRUS: EICAR-AV-Test
*** 250 2.5.0 Ok, but 1 BOUNCE
*** 250 2.7.1 Ok, discarded, id=16984-01 - VIRUS: EICAR-AV-Test
*** 250 2.6.0 Ok, id=17041-01, from MTA: 250 Ok: queued as 3F1841A5F5
--> QUIT
221 2.0.0 [127.0.0.1] (amavisd) closing transmission channel
Connection closed by foreign host.

Configure postfix

Changes to postfix’ main.cf, also change other settings to customize you’re requirements. Setting ‘soft_bounce=yes’ for testing purposes while starting out using you’re new mailserver would be a wise decision!

# Transports
transport_server_host = localhost
transport_search_base = dc=mail,dc=example,dc=org
transport_query_filter = (&(dc=%s)(objectClass=mailDomain)(accountActive=TRUE)(delete=FALSE))
transport_result_attribute = postfixTransport
#transport_cache = yes
transport_bind = no
transport_scope = one
# Aliases
aliases_server_host = localhost
aliases_search_base = dc=mail,dc=example,dc=org
aliases_query_filter = (&(objectClass=mailAlias)(mail=%s)(accountActive=TRUE))
aliases_result_attribute = maildrop
aliases_bind = no
#aliases_cache = yes
# Accounts
accounts_server_host = localhost
accounts_search_base = dc=mail,dc=example,dc=org
accounts_query_filter = (&(objectClass=mailAccount)(mail=%s)(accountActive=TRUE)(delete=FALSE))
accounts_result_attribute = mailbox
accounts_bind = no
#accounts_cache = yes
accountsmap_server_host = localhost
accountsmap_search_base = dc=mail,dc=example,dc=org
accountsmap_query_filter = (&(objectClass=mailAccount)(mail=%s)(accountActive=TRUE)(delete=FALSE))
accountsmap_result_attribute = mail
accountsmap_bind = no
#accountsmap_cache = yes
# Transport map
transport_maps = ldap:transport
mydestination = $myhostname, localhost.$mydomain, $mydomain, mail.$mydomain, $transport_maps
# Virtual maps
virtual_maps = ldap:aliases, ldap:accountsmap
# Virtual accounts
virtual_mailbox_base = /usr/virtual
virtual_mailbox_maps = ldap:accounts
virtual_minimum_uid = 2000
virtual_uid_maps = static:2000
virtual_gid_maps = static:2000
# Local accounts
local_alias_maps = hash:/etc/aliases
local_recipient_maps = $local_alias_maps unix:passwd.byname
# local_transport should set to "virtual" to deliver mail to local VirtualAccount
# 's $HOME direcotry . or not set here, mail delivery would be failure
local_transport = virtual
local_recipient_maps = $alias_maps unix:passwd.byname $virtual_mailbox_maps

# AMAVIS
content_filter = smtp-amavis:[127.0.0.1]:10024

Changes to postfix’ master.cf (optionally replace the ‘y’ with ‘n’ depending on you’re chroot wishes). Make sure ‘virtual’ and ‘maildrop’ also exist in master.cf

smtp-amavis unix -      -       y     -       2  smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
127.0.0.1:10025 inet n  -       y     -       -  smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o strict_rfc821_envelopes=yes
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000

Starting you’re mailserver

Next again edit /etc/rc.conf to disable sendmail and enable postfix
Insert

  • sendmail_enable="NONE"

Comment out/remove

  • sendmail_enable="YES"
  • sendmail_flags="-bd"
  • sendmail_pidfile="/var/spool/postfix/pid/master.pid"
  • sendmail_outbound_enable="NO"
  • sendmail_submit_enable="NO"
  • sendmail_msp_queue_enable="NO"

Now would be a great time to start postfix, but before you do touch /var/log/maillog and open a second terminal, screen or whatever and do a tail -f /var/log/maillog there (as well as maybe a tail on /var/log/messages) to see what’s going on. Now you’re ready to start postfix simply by typing postfix start


Verify mail sending and receiving

Verify that you can send mail by sending yourself mail. If using an address@example.org which is an alias (pointing outside one of the domains for wich your new postfix server receives mail) please check you’re headers and confirm their ok. If receiving on a mailbox address (at your new postfix server), look in /usr/virtual and confirm you have a new directory named example.org (depending on the recipient). Below that directory your mailbox name (as a directory) should emerge, containing various maildir files. Besides checking that your mail was received also check the headers!

Note that users of a mailbox should have received at least one email to have their directory (and maildir files) in place When you create a new mailbox (not alias), you should send the new user a ‘welcome’ mail of some kind to let postfix create their ‘homedirectory’ in /usr/virtual. When omitted the user will receive an error when checking mail (either via imap/pop or when using webmail)


Webmail, a web frontend to mail

In this howto we choose squirrelmail. Why? Because it’s a good, safe and easy to install webmail application. When using FreeBSD we can install squirrelmail from ports, but i decided to just download the package and do everything by hand. Either way you’ll end up with a squirrelmail directory (/usr/local/www/data/squirrelmail) which contains a file called configure. Run ./configure in the squirrelmail directory and a menu will appear. For our sample setup the following defaults were changed

2 - Server Settings
1 - Domain
example.org
3 - Sendmail or SMTP
SMTP
A - Update IMAP settings (reveals new options)
4 - IMAP server
localhost
5 - IMAP port
993
6 - Authentication type
login
7 - Secure IMAP (TLS)
true
8 - Server software
courier
B - Update SMTP settings (reveals new options))
4 - SMTP server
localhost
5 - SMTP port
25
R - Return to main menu

You can change more options if you like, and even install some nice plugins from the squirrelmail website but this will do for now. Point your webbrowser to http://www.example.org/squirrelmail and login as one of your mailbox users. Happy webmailing!


Documents and resources used

Besides RTFM on various packages used to install a number of special resources will be named below the packages linklist; (in no particular order)

  • Postfix, MTA used
  • Spam tagging software
  • LDAP software
  • Webmail software
  • Mailinglist software (when done, you could add mailinglists, not captured in this document)
  • ClamAV Antivirus software
  • Short for [A] [MA]il [VI]rus [S]canner
  • Apache webserver for webmail and admin (php) interface
  • The admin interface was build using php

Most usefull to produce this document was :http://janus.errornet.de/ with his pdf and schema
((mirrored here) pdf and schema)

Others resources used

  • http://jamm.sourceforge.net everything else seems to be based upon this
  • http://www.vriesman.tk detailed enough for me

 

 

Tom Scholten is Unix specialist with Snow B.V., a Dutch Technical Consultancy Company supplying specialists in the field of Networking and Unix

 

 


freebsd        

Geef een reactie

Your email address will not be published. Required fields are marked *

Copyright All Rights Reserved | Theme: BlockWP by Candid Themes.