Difference between revisions of "Mailutils:HOWTO:Sendmail MU LDAP"

From Mailutils
Jump to navigationJump to search
Line 194: Line 194:
 
</pre>
 
</pre>
  
== sendmail with STARTTLS, SMTPAUTH, LDAP and db44 support ==
+
== sendmail with [http://www.sendmail.com/sm/open_source/docs/m4/starttls.html STARTTLS], [http://www.sendmail.org/~ca/email/auth.html SMTPAUTH], [http://www.sendmail.com/sm/open_source/docs/m4/ldap.html LDAP] and db44 support ==
  
 
=== cyrus-sasl2 ===
 
=== cyrus-sasl2 ===

Revision as of 22:09, 30 August 2013

Task

  • to get users database accessible via LDAP (OpenLDAP as LDAP server)
  • to get multidomain (multi domains with separate (if needed) users for each domain) support in sendmail via mailutils

all described was deployed on FreeBSD

OpenLDAP

The important decision have to be made on account of the directory topology: flat namespace or a hierarchical one

look at

  • "LDAP System Administration" By Gerald Carter; ISBN: 1-56592-491-6
  • "Understanding and Deploying LDAP Directory Services", Second Edition By Timothy A. Howes Ph.D., Mark C. Smith, Gordon S. Good; ISBN: 0-672-32316-8.

slapd.conf

include         /usr/local/etc/openldap/schema/core.schema
include         /usr/local/etc/openldap/schema/cosine.schema
include         /usr/local/etc/openldap/schema/inetorgperson.schema
include         /usr/local/etc/openldap/schema/nis.schema
include         /usr/local/etc/openldap/schema/openldap.schema
include         /usr/local/etc/openldap/schema/misc.schema
include         /usr/local/etc/openldap/schema/ldapns.schema
include         /usr/local/etc/openldap/schema/asterisk.schema
include         /usr/local/etc/openldap/schema/sendmail.schema

loglevel        stats

pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args

modulepath      /usr/local/libexec/openldap
moduleload      back_bdb
moduleload      back_hdb
moduleload      back_monitor
moduleload      syncprov

TLSCACertificateFile  /usr/local/etc/openldap/ssl/cacert.pem
TLSCertificateFile    /usr/local/etc/openldap/ssl/srv1cert.pem
TLSCertificateKeyFile /usr/local/etc/openldap/ssl/srv1key.pem
TLSCipherSuite HIGH:MEDIUM:+TLSv1:!SSLv2:+SSLv3
TLSVerifyClient never
security ssf=128

access to dn.exact="" by * read
access to *
       by peername.ip=127.0.0.1 break
       by peername.ip=X.X.X.X break
access to *
       by set="[cn=bind,ou=group,dc=ibs]/memberUid & user/uid" read
       by set="[cn=admin,ou=group,dc=ibs]/memberUid & user/uid" write
       by self read
       by * search

database        bdb
suffix          "dc=foo,dc=bar"
rootdn          "cn=ldapmaster,dc=foo,dc=bar"
rootpw          {SSHA}Osdfkjwh89974500sdfjhjhLKJHKLJLKJlLKJljlj
directory       /var/db/openldap-data/foo.bar
monitoring      on

index   default eq,sub
index   objectClass eq
index   uidNumber eq
index   gidNumber eq
index   memberUid eq
index   cn,sn,uid,displayName pres,sub,eq
index   authorizedService eq
index   sendmailMTAAliasGrouping eq
index   sendmailMTACluster eq
index   sendmailMTAHost eq
index   sendmailMTAKey eq
index   sendmailMTAMapName eq

overlay memberof

overlay unique
unique_uri ldap:///ou=People,dc=foo,dc=bar?uid?sub?(authorizedService=mail@foo.bar)
unique_uri ldap:///ou=People,dc=foo,dc=bar?uid?sub?(authorizedService=mail@foo.com)

ldap.conf

BASE    dc=foo,dc=bar
URI     ldap://ldap.foo.bar:389
SIZELIMIT       0
TLS_REQCERT allow
TLS_CACERT /usr/local/etc/openldap/cacert.pem

.ldif

dn: uid=officeX-testuser,ou=People,dc=foo,dc=bar
cn: testuser@foo.bar
description: unique user across whole user database
gidnumber: 12345
homedirectory: /nonexistent
loginshell: /sbin/nologin
objectclass: top
objectclass: posixAccount
objectclass: inetOrgPerson
objectclass: organizationalPerson
objectclass: person
objectclass: inetLocalMailRecipient
sn: test user
uid: officeX-testuser
uidnumber: 10001
userpassword: {CRYPT}$1$dtyhERYdf$dfDGGsdHJKTIKT.34345DFSF/

dn: authorizedService=mail@foo.bar,uid=officeX-testuser,ou=People,dc=foo,dc=bar
associateddomain: foo.bar
authorizedservice: mail@foo.bar
cn: testuser@foo.bar
description: auxiliary service/s account (like email, web, e.t.c. access)
gidnumber: 10106
homedirectory: /var/mail/IMAP_HOMES/foo.bar/testuser@foo.bar
loginshell: /sbin/nologin
mu-mailbox: maildir:/var/mail/foo.bar/testuser@foo.bar
objectclass: posixAccount
objectclass: shadowAccount
objectclass: inetOrgPerson
objectclass: authorizedServiceObject
objectclass: domainRelatedObject
objectclass: mailutilsAccount
sn: testuser@foo.bar
uid: testuser@foo.bar
uidnumber: 10001
userpassword: {CRYPT}$1$dtyhERYdf$dfDGGsdHJKTIKT.34345DFSF/

dn: authorizedService=mail@foo.com,uid=officeX-testuser,ou=People,dc=foo,dc=bar
associateddomain: foo.com
authorizedservice: mail@foo.com
cn: testuser@foo.com
description: auxiliary service/s account (like email, web, e.t.c. access)
gidnumber: 10106
homedirectory: /var/mail/IMAP_HOMES/foo.com/testuser@foo.com
loginshell: /sbin/nologin
mu-mailbox: maildir:/var/mail/foo.com/testuser@foo.com
objectclass: posixAccount
objectclass: shadowAccount
objectclass: inetOrgPerson
objectclass: authorizedServiceObject
objectclass: domainRelatedObject
objectclass: mailutilsAccount
sn: testuser@foo.com
uid: testuser@foo.com
uidnumber: 10001
userpassword: {CRYPT}$1$dtyhERYdf$dfDGGsdHJKTIKT.34345DFSF/

test

# ldapsearch -xZZ -D uid=bind@mail.foo.bar,ou=people,dc=foo,dc=bar -w ***** -b ou=people,dc=foo,dc=bar -v "(&(authorizedService=mail@foo.bar)(uid=testuser))"                                      
ldap_initialize( <DEFAULT> )
filter: (&(authorizedService=mail@foo.bar)(uid=testuser))
requesting: All userApplication attributes
# extended LDIF
#
# LDAPv3
# base <ou=people,dc=foo,dc=bar> with scope subtree
# filter: (&(authorizedService=mail@foo.bar)(uid=testuser))
# requesting: ALL
#

# mail@foo.bar, officeX-testuser, People, foo, bar
dn: authorizedService=mail@foo.bar,uid=officeX-testuser,ou=People,dc=foo,dc=bar
associateddomain: foo.bar
authorizedservice: mail@foo.bar
cn: testuser@foo.bar
description: auxiliary service/s account (like email, web, e.t.c. access)
gidnumber: 10106
homedirectory: /var/mail/IMAP_HOMES/foo.bar/testuser@foo.bar
loginshell: /sbin/nologin
mu-mailbox: maildir:/var/mail/foo.bar/testuser@foo.bar
objectclass: posixAccount
objectclass: shadowAccount
objectclass: inetOrgPerson
objectclass: authorizedServiceObject
objectclass: domainRelatedObject
objectclass: mailutilsAccount
sn: testuser@foo.bar
uid: testuser@foo.bar
uidnumber: 10001
userPassword:: *****************************************

# search result
search: 3
result: 0 Success

# numResponses: 2
# numEntries: 1

sendmail with STARTTLS, SMTPAUTH, LDAP and db44 support

cyrus-sasl2

buil cyrus-sasl2 with ldap and saslauthd

saslauthd.conf

ldap_servers: ldap://ldap.foo.bar/
ldap_start_tls: yes
ldap_tls_cacert_file: /usr/local/etc/openldap/cacert.pem
ldap_auth_method: bind
ldap_bind_dn: uid=bind@mail.foo.bar,ou=people,dc=foo,dc=bar
ldap_password: ******
ldap_search_base: dc=foo,dc=bar
ldap_filter: (&(uid=%U)(authorizedService=mail@foo.bar))

test

# testsaslauthd -u testuser@foo.bar -p theverypassword
0: OK "Success."

sendmail

build config

site.config.m4

##
# general
APPENDDEF(`confINCDIRS', `-I/usr/local/include -I/usr/local/include/db44')
APPENDDEF(`confLIBDIRS', `-L/usr/local/lib -L/usr/local/lib/db44')

## DB44
#APPENDDEF(`confENVDEF', `-I/usr/local/include -I/usr/local/include/db44')
#APPENDDEF(`conf_sendmail_LIBS', `-L/usr/local/lib -L/usr/local/lib/db44')

# SASL2 (smtp authentication)
APPENDDEF(`confENVDEF', `-DSASL=2')
APPENDDEF(`conf_sendmail_LIBS', `-lsasl2')

# LDAP
APPENDDEF(`confMAPDEF', `-DLDAPMAP')
APPENDDEF(`confLIBS', `-lldap -llber')

# STARTTLS (smtp + tls/ssl)
APPENDDEF(`conf_sendmail_ENVDEF', `-DSTARTTLS -D_FFR_TLS_1')
APPENDDEF(`conf_sendmail_LIBS', `-lssl -lcrypto')

# rest
APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER -DSOCKETMAP -DMAP_REGEX -DNEWDB')

sendmail.mc

dnl * Sendmail configuration
divert(-1)
OSTYPE(freebsd6)
dnl * To eliminate 8->7 bit base64 enconding
define(`SMTP_MAILER_FLAGS',`8')
dnl * Do not reveal my version number
define(`confRECEIVED_HEADER',`$?sfrom $s $.$?_($?s$|from $.$_) $.
        by $j$?r with $r$. id $i$?u
        for $u$.; $b')
dnl * Also, disable VRFY,EXPN
define(`confPRIVACY_FLAGS',`authwarnings,novrfy,noexpn,noetrn,needmailhelo')

dnl * do STARTTLS
define(`confCACERT_PATH', `/etc/mail/certs')dnl
define(`confCACERT', `/etc/mail/certs/sendmail.pem')dnl
define(`localCERT', `/etc/mail/certs/sendmail.pem')dnl
define(`confSERVER_CERT', `localCERT')dnl
define(`confSERVER_KEY',  `localCERT')dnl
define(`confCLIENT_CERT', `localCERT')dnl
define(`confCLIENT_KEY',  `localCERT')dnl

dnl * do SMTPAUTH
define(`confAUTH_MECHANISMS', `LOGIN PLAIN')dnl
TRUST_AUTH_MECH(`LOGIN PLAIN')dnl

dnl * look for AuthOptions @ op.ps
define(`confAUTH_OPTIONS', `A p y')dnl


define(`confSAVE_FROM_LINES', `True')dnl
define(`HELP_FILE',`none')dnl
define(`confDELIVERY_MODE', `background')dnl

dnl * define(`confMAX_MESSAGE_SIZE',`31457280')
define(`confERROR_MESSAGE',`/etc/mail/error-header')dnl
define(`confREJECT_MSG',`550 Access denied. For our users call IT dpt 911')dnl
define(`confRELAY_MSG', `550 Relaying denied. For our users call IT dpt 911')dnl

dnl define(`confSMTP_LOGIN_MSG',`$j server; $b')
define(`confSMTP_LOGIN_MSG',`$j server ready.\nWelcome to us.\nSending UBE is forbidden.\nViolators will be severely prosecuted.')

dnl * DAEMON_OPTIONS(`Name=MTA,Addr=0.0.0.0')
DAEMON_OPTIONS(`Name=MTA,Addr=X.X.X.X')
DAEMON_OPTIONS(`Name=MTA-local0,Addr=127.0.0.1')
DAEMON_OPTIONS(`Name=MTA-local3,Addr=Y.Y.Y.Y')
DAEMON_OPTIONS(`Family=inet,Name=MTA-SSL,Port=465,M=abs')

# Maps
define(`confLDAP_DEFAULT_SPEC', `-H ldaps://ldap.foo.bar -b ou=foo.bar,ou=Sendmail,dc=foo,dc=bar -w3 -d uid=bind@mail.foo,ou=people,dc=foo,dc=bar -P /etc/mail/ldappass')dnl
define(`confLDAP_CLUSTER', `fo01')

LOCAL_CONFIG
Klocal_alias hash -T<TMPF> -o /etc/mail/aliases
Kldap_alias ldap -k (&(objectClass=sendmailMTAAliasObject)(sendmailMTAAliasGrouping=aliases)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAKey=%0)) -v sendmailMTAAliasValue
define(`ALIAS_FILE',`sequence: local_alias ldap_alias')

FEATURE(`access_db', `LDAP')
FEATURE(`mailertable', `LDAP')

FEATURE(use_cw_file)
FEATURE(use_ct_file)
FEATURE(redirect)
FEATURE(always_add_domain)
FEATURE(blacklist_recipients)
FEATURE(relay_entire_domain)

# Milter
define(`confMILTER_LOG_LEVEL',4)
INPUT_MAIL_FILTER(`mailfrom', `S=unix:/var/run/mailfromd/mailfromd.sock, F=T, T=S:120s;R:360s')

# Mailers
MAILER_DEFINITIONS
Mlocal-ldap,    P=/usr/local/sbin/maidag, F=lsDFMA5:/|@qSPfhn9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL,
                T=DNS/RFC822/X-Unix,
                A=maidag $u@$h

MAILER(smtp)

mailertable

in case to leave it as file, then in /etc/mail/mailertable put

foo.bar    local-ldap:foo.bar
foo.com    local-ldap:foo.com

in case to put in in LDAP we need:

dn: sendmailMTAMapName=mailer,ou=core.relay.foo.bar,ou=Sendmail,dc=foo,dc=bar
objectclass: sendmailMTA
objectclass: sendmailMTAMap
sendmailmtacluster: fo01
sendmailmtamapname: mailer

dn: sendmailMTAKey=foo.bar,sendmailMTAMapName=mailer,ou=core.relay.foo.bar,ou=Sendmail,dc=foo,dc=bar
objectclass: sendmailMTA
objectclass: sendmailMTAMap
objectclass: sendmailMTAMapObject
sendmailmtacluster: fo01
sendmailmtakey: foo.bar
sendmailmtamapname: mailer
sendmailmtamapvalue: local-ldap:foo.bar

dn: sendmailMTAKey=foo.com,sendmailMTAMapName=mailer,ou=core.relay.foo.bar,ou=Sendmail,dc=foo,dc=bar
objectclass: sendmailMTA
objectclass: sendmailMTAMap
objectclass: sendmailMTAMapObject
sendmailmtacluster: fo01
sendmailmtakey: foo.com
sendmailmtamapname: mailer
sendmailmtamapvalue: local-ldap:foo.com

test

sendmail -bt
> 3,0 testuser@foo.bar
canonify           input: testuser @ foo . bar
Canonify2          input: testuser < @ foo . bar >
Canonify2        returns: testuser < @ foo . bar . >
canonify         returns: testuser < @ foo . bar . >
parse              input: testuser < @ foo . bar . >
Parse0             input: testuser < @ foo . bar . >
Parse0           returns: testuser < @ foo . bar . >
ParseLocal         input: testuser < @ foo . bar . >
ParseLocal       returns: testuser < @ foo . bar . >
Parse1             input: testuser < @ foo . bar . >
MailerToTriple     input: < local-ldap : foo . bar > testuser < @ foo . bar . >
MailerToTriple   returns: $# local-ldap $@ foo . bar $: testuser < @ foo . bar . >
Parse1           returns: $# local-ldap $@ foo . bar $: testuser < @ foo . bar . >
parse            returns: $# local-ldap $@ foo . bar $: testuser < @ foo . bar . >

mu

config

configure \
    CPPFLAGS='-I/usr/local/include/ -I/usr/local/include/db44/ -I/usr/local/include/postgresql/ -I/usr/local/include/gnutls' \
    LDFLAGS='-L/usr/local/lib/ -L/usr/local/lib/postgresql/ -L/usr/local/lib/db44' \
    --enable-debug \
    --with-berkeley-db \
    --enable-pam \
    --with-gnutls \
    --with-postgres \
    --with-ldap \
    --disable-nls \
    --disable-nntp \
    --disable-radius

mailutils.rc

mailutils.rc

ldap {
  enable yes;
  url "ldap://ldap.foo.bar:389/";
  base "ou=people,dc=ibs";
  binddn "uid=bind@mai.foo.bar,ou=people,dc=foo,dc=bar";
  passwd "*****";
  tls yes;
  debug 1;
  field-map "name=uid:passwd=userPassword:uid=uidNumber:gid=gidNumber:gecos=gecos:dir=homeDirectory:shell=loginShell:mailbox=mu-mailBox";
  getpwnam "(|(&(authorizedService=mail@foo.bar)(uid=${user}))(&(authorizedService=mail@foo.bar)(cn=${user}))(&(authorizedService=mail@foo.com)(cn=${user})))";
  getpwuid "(|(&(authorizedService=mail@foo.bar)(uid=${user}))(&(authorizedService=mail@foo.bar)(cn=${user}))(&(authorizedService=mail@foo.com)(cn=${user})))";
};

auth {
  authorization generic:ldap:system;
  authentication generic:ldap:system;
};

mailbox {
  mailbox-type "maildir";
  mailbox-pattern "maildir:/var/mail;type=index;param=2;user=${user}";
};

locking {
  retry-count 400;
};

include /usr/local/etc/mailutils;


pop3d

tls {
  enable yes;
  ssl-cert /usr/local/etc/mailutils/ssl/mu.pem;
  ssl-key  /usr/local/etc/mailutils/ssl/mu.pem;
};

logging {
  facility local3;
};

debug {
  level "server.trace0";
  line-info yes;
};

#bulletin-source /var/spool/bulletin/bulletin.mbox;
#bulletin-db /var/spool/bulletin/bulletin;
max-children 30;
mode daemon;
pidfile /var/run/pop3d.pid;
timeout 180;

server X.X.X.X {
  transcript no;
  tls ondemand;
};

server Y.Y.Y.Y {
  transcript no;
  tls required;
};

server Y.Y.Y.Y:995 {
  transcript no;
  tls connection;
};


acl {
  log from any "Connect from ${address}";
};

imap4d

tls {
  enable yes;
  ssl-cert /usr/local/etc/mailutils/ssl/mu.pem;
  ssl-key  /usr/local/etc/mailutils/ssl/mu.pem;
};

logging {
  facility local2;
};

mandatory-locking {
  enable 1;
  lock-directory /tmp;
};

debug {
  level "server.trace0";
  line-info yes;
};

create-home-dir 1;
shared-namespace "/var/mail/IMAP_SHARE";
shared-mailbox-mode g=rw;

max-children 50;
mode daemon;
pidfile /var/run/imap4d.pid;
timeout 300;

server X.X.X.X {
  transcript yes;
  tls ondemand;
};

server Y.Y.Y.Y {
  transcript no;
  tls required;
};

server Y.Y.Y.Y:993 {
  transcript no;
  tls connection;
};

acl {
  log from any "Connect from ${address}";
#  allow Z.Z.Z.Z;
#  deny any;
};

maidag

debug {
  line-info yes;
};

logging {
  tag "maidag";
};

filter {
  language "sieve";
  pattern "/usr/local/etc/mailutils/scripts/%u";
};

test

#> telnet pop.foo.bar 110
Trying X.X.X.X...
Connected to pop.foo.bar.
Escape character is '^]'.
+OK POP3 Ready <24289.1377897169@relay.foo.bar>
user testuser@foo.bar
+OK
pass *****
+OK opened mailbox for testuser
quit
+OK
Connection closed by foreign host.

#> telnet imap.foo.bar 143
Trying X.X.X.X...
Connected to imap.foo.bar.
Escape character is '^]'.
* OK IMAP4rev1
00 login testuser@foo.bar *****
00 OK LOGIN Completed
11 logout
* BYE Session terminating.
11 OK LOGOUT Completed
Connection closed by foreign host.