How to integrate E.F.A with Active Directory on 3.0.0.9

Questions and answers about how to do stuff
User avatar
shawniverson
Posts: 2785
Joined: 13 Jan 2014 23:30
Location: Rushville, Indiana, USA
Contact:

How to integrate E.F.A with Active Directory on 3.0.0.9

Post by shawniverson » 20 Mar 2016 11:50

Here's a small how-to to integrate with AD ;)

That's right, you can pull all of your email users into E.F.A. and authenticate against AD (probably any LDAP server)!

Follow these steps.

1) Create a user and password (proxy service account) in AD to allow username lookups

2) Configure Mailwatch

Edit /var/www/html/mailscanner/conf.php

Code: Select all

// LDAP settings
define('USE_LDAP',                true);
define('LDAP_HOST',      'server.example.com');
define('LDAP_PORT',      '389');
define('LDAP_DN',        'DC=example,DC=com');
define('LDAP_USER',      'LDAPProxy@example.com');
define('LDAP_PASS',      'secret');
define('LDAP_SITE',      'default-first-site-name');
Further down in the same file...change 'proxyaddresses' to 'mail' if needed depending on your LDAP implementation.

Code: Select all

define('LDAP_EMAIL_FIELD', 'mail');
If you are performing searches against your whole Active Directory domain or forest, you may need this setting turned on:

Code: Select all

define('LDAP_MS_AD_COMPATIBILITY', true);
3) Make sure php-ldap is installed

Code: Select all

sudo yum install php-ldap
That's it. Enjoy!
Version eFa 4.0.0 RC3 now available in testing repo. Come join us in advancing eFa!

duesen
Posts: 12
Joined: 30 Mar 2016 15:35
Location: Austria

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by duesen » 04 Apr 2016 15:10

Hello shawniverson!

Thank you for the howto.

If this posting is missplaced feel free to delete or move it to some better place.

@otherusers
This is working for us but for productive environments i would suggest to wait for an answer of shawniversion to aggree with the following steps.
Keep in mind that manual changes on the configfiles need to "survive" an E.F.A-Update.

For a more complete ldap integration I did the following steps to let postfix query our Active-Directory (LDAP) Domain for valid recipients:

1.) create a file /etc/postfix/ldap_relay_recipient_maps.cf

Code: Select all

#/etc/postfix/ldap_relay_recipient_maps.cf
#example for Windows AD-Server
server_host = ip.address.of.ldap-server
# I needed "DC=" twice because of our AD structure. Examine your AD to know what to put in here!
search_base = OU=yourOU,DC=yourDC,DC=yourDC
scope = sub
bind_dn = windomain\proxyuser
bind_pw = password
bind = yes
query_filter = (|(proxyAddresses=smtp:%s) (proxyAddresses=SMTP:%s))
result_attribute = mail
2.) add this to /etc/postfix/main.cf

Code: Select all

relay_recipient_maps = ldap:/etc/postfix/ldap_relay_recipient_maps.cf
3.)

Code: Select all

service MailScanner restart
-
duesen

User avatar
shawniverson
Posts: 2785
Joined: 13 Jan 2014 23:30
Location: Rushville, Indiana, USA
Contact:

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by shawniverson » 07 Apr 2016 23:47

:text-bravo:

Looks like a winner to me. Simple and effective.
Version eFa 4.0.0 RC3 now available in testing repo. Come join us in advancing eFa!

seltsam030
Posts: 1
Joined: 23 Feb 2016 14:39

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by seltsam030 » 19 Apr 2016 14:39

Hello together,

thank you guys for this inspiration and your work!
My main target ist to validate mail adresses against my exchange or active directory, i don't want to let them users white- or greylisting by themselves for different reasons.So it is not necessary to import them as users from my point of view.
So, my Question is, do i have to do both steps or is it enough to do it like duesen ?
Is the step (published by duesen) additionally or an alternative to shawniversions solution?
Thank you for your support.

Seltsam030
--
Windows, supported by linux systems :D

duesen
Posts: 12
Joined: 30 Mar 2016 15:35
Location: Austria

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by duesen » 19 Apr 2016 18:01

To only query if the incoming RCPT TO: address is valid you only have to do the above mentioned steps in postfix.

But...

BE CAREFULL WITH THE LDAP SETTINGS:
By now I did not figure out how to use SSL for the AD-Query. The user and password to query your AD-server (both postfix and mailwatch) is sent in plaintext.
If anyone has a solution on how to use SSL in this case ... you are welcome!
-
duesen

lambert
Posts: 5
Joined: 19 Apr 2016 05:35

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by lambert » 20 Apr 2016 03:52

Has anyone explored integrating with multiple AD servers?

We currently host a Barracuda server for a couple of dozen Exchange Servers owned by other companies. The Barracuda uses LDAP queries to get the valid users and (optionally) authentication credentials for each of those domains.

I like the EFA concept and would like to replace the Barracuda with it. I just don't quite understand how to get all of the various domains integrated. I could just use an EFA instance per domain, but I would rapidly run out of IP addresses.

The Barracuda system is due for renewal in a month. I would like to get this figured out quickly. I'm willing to pay for the help.

zane93
Posts: 31
Joined: 08 Mar 2016 22:08

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by zane93 » 25 Apr 2016 23:03

lambert wrote:Has anyone explored integrating with multiple AD servers?

We currently host a Barracuda server for a couple of dozen Exchange Servers owned by other companies. The Barracuda uses LDAP queries to get the valid users and (optionally) authentication credentials for each of those domains.

I like the EFA concept and would like to replace the Barracuda with it. I just don't quite understand how to get all of the various domains integrated. I could just use an EFA instance per domain, but I would rapidly run out of IP addresses.

The Barracuda system is due for renewal in a month. I would like to get this figured out quickly. I'm willing to pay for the help.
Consolidate into a single domain generic domain xyz.com, add all your other Alternative UPN suffixes to xyz.com, and then use OU's to consolidate users and groups for each company. This is what I do as an Exchange 2016 provider but have not integrated with efa yet. I am looking into integration though.

My AD structure is:
xyz.com
-OU- doamins
-OU-123.com
-users
-OU- 456.com
-users
ect.....

I'm not sure if EFA will query / search into each OU or not if it does then the above should work. But I think more home work would have to be done on php-ldap to be sure.

lambert
Posts: 5
Joined: 19 Apr 2016 05:35

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by lambert » 02 May 2016 20:42

I don't run the exchange servers for these customers. I just filter their e-mail. I don't think I have the ability to implement one AD to rule them all. Many of these servers are in dentist/doctor offices on DSL/cable connections with port forwards allowing my mail filtering subnet to connect to the LDAP port.

dbrunt
Posts: 64
Joined: 28 Nov 2015 00:09

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by dbrunt » 13 Sep 2016 18:00

Lambert,

Here's what we did so postfix can query LDAP in multiple AD's for valid recipients.
We created multiple .cf files as above:

/etc/postfix/ldap-AD_1.cf:

Code: Select all

server_host = 10.0.0.51

search_base = dc=company-canada,dc=com
bind = yes
bind_dn = CN=LDAPProxy,OU=Service Accounts and Guests,OU=company,DC=company-canada,DC=com
bind_pw = ********
query_filter = (|(mail=%s)(proxyAddresses=smtp:%s))
leaf_result_attribute = mail
# result_format = %S OK
result_format = OK
version = 3
/etc/postfix/ldap-AD_2.cf:

Code: Select all

server_host = mail.company2.org

search_base = dc=company2,dc=local
bind = yes
bind_dn = CN=LdapProxy,OU=SBSUsers,OU=Users,OU=MyBusiness,DC=company2,DC=local
bind_pw = ********
query_filter = (|(mail=%s)(proxyAddresses=smtp:%s))
leaf_result_attribute = mail
# result_format = %S OK
result_format = OK
version = 3
and then modified the following within smtp_recipient_restrictions in/etc/postfix/main.cf:

Code: Select all

check_recipient_access hash:/etc/postfix/recipient_access, check_policy_service inet:127.0.0.1:2501
to:

Code: Select all

check_recipient_access ldap:/etc/postfix/ldap-AD_1.cf, ldap:/etc/postfix/ldap-AD_2.cf, hash:/etc/postfix/recipient_access, check_policy_service inet:127.0.0.1:2501, reject
So it looks like:

Code: Select all

smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_non_fqdn_recipient, reject_unknown_recipient_domain, check_recipient_access ldap:/etc/postfix/ldap-AD_1.cf, ldap:/etc/postfix/ldap-AD_2.cf, hash:/etc/postfix/recipient_access, check_policy_service inet:127.0.0.1:2501, reject
This also works in /etc/postfix/main.cf:

Code: Select all

relay_recipient_maps = ldap:/etc/postfix/ldap-AD_1.cf,ldap:/etc/postfix/ldap-AD_2.cf
It depends on what you want the reject message to say...Access Denied, or Relay Recipient not found.
Note: this is only to allow postfix to query for valid recipients.

For MailWatch to use LDAP authentication, I believe EFA still only allows for one AD domain to be configured as per the original post in this thread.

-Daniel
Last edited by dbrunt on 13 Sep 2016 22:07, edited 1 time in total.

lambert
Posts: 5
Joined: 19 Apr 2016 05:35

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by lambert » 13 Sep 2016 18:27

Daniel,

Thank you for your message. That helps with the actual e-mail handling side of the equation.

It would be nice to have the UI side work as well. But, this is a good chunk of the problem space resolved.

We didn't get any feedback in time so we went ahead and renewed with Barracuda Networks. I'm still interested in getting this going before April 2017.

SupportOU
Posts: 47
Joined: 12 Sep 2016 18:47

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by SupportOU » 20 Sep 2016 20:48

Hola,
Can you also use LDAP for SASL auth? So auth plain sasl is querying AD instead of the local users of the system? I got sasl working now with dovecot and that works fine with local users.
No GUI needed, as long as the configs survive an upgrade. I used webmin and all my config was screwed up.
Grtz,

dbrunt
Posts: 64
Joined: 28 Nov 2015 00:09

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by dbrunt » 25 Oct 2016 02:20

lambert wrote:Has anyone explored integrating with multiple AD servers?

We currently host a Barracuda server for a couple of dozen Exchange Servers owned by other companies. The Barracuda uses LDAP queries to get the valid users and (optionally) authentication credentials for each of those domains.

I like the EFA concept and would like to replace the Barracuda with it. I just don't quite understand how to get all of the various domains integrated. I could just use an EFA instance per domain, but I would rapidly run out of IP addresses.

The Barracuda system is due for renewal in a month. I would like to get this figured out quickly. I'm willing to pay for the help.
See viewtopic.php?f=15&t=1637&hilit=multiple+ldap
We are filtering for multiple clients with their own Exchange. You will have to create a local DNS zone (clientdomain.local) for EFA to look up the IP address of each LDAP server to authenticate against. The address is for the zone itself.

6714
Posts: 7
Joined: 09 Nov 2016 08:57

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by 6714 » 09 Nov 2016 09:10

Hello, i tested the actual Version of efa appliance.
my questions.

The AD Users can logon in the efa appliance, this works fine

Code: Select all

// LDAP settings
define('USE_LDAP',         true);
define('LDAP_SSL',         false); // set to true if using LDAP with SSL encryption
define('LDAP_HOST',        's1.domain.net');
define('LDAP_PORT',        '389');
define('LDAP_DN',          'DC=domain,DC=net');
define('LDAP_USER',        'ldapuser');
define('LDAP_PASS',        'domainpass');
define('LDAP_SITE',        'default');
// can be set to 'proxyaddresses' or 'mail'. Please refer to your LDAP system manual for the right keyword
define('LDAP_EMAIL_FIELD', 'proxyaddresses');
// Microsoft Active Directory compatibility support for searches from Domain Base DN
define('LDAP_MS_AD_COMPATIBILITY', true);
The AD Users LDAP recipients not works with this settings, why ?

Code: Select all

cat /etc/postfix/ldap_relay_recipient_maps.cf
#/etc/postfix/ldap_relay_recipient_maps.cf
#example for Windows AD-Server
server_host = s1.domain.net
# I needed "DC=" twice because of our AD structure. Examine your AD to know what to put in here!
search_base = DC=domain,DC=net
scope = sub
bind_dn = ldapuser
bind_pw = domainpass
bind = yes
query_filter = (|(proxyAddresses=smtp:%s) (proxyAddresses=SMTP:%s))
result_attribute = proxyAddresses
The LDAP lookup error:

Code: Select all

Nov  9 09:55:42 mgw postfix/smtpd[23899]: warning: dict_ldap_lookup: Search error 9: Partial results and referral received
Nov  9 09:55:42 mgw postfix/smtpd[23899]: warning: ldap:/etc/postfix/ldap_relay_recipient_maps.cf lookup error for "user@domain.net"
The AD-DC is an Windows 2012, the dns on efa function fine (s1 or s1.domain.net)

Thanks for help !

6714
Posts: 7
Joined: 09 Nov 2016 08:57

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by 6714 » 09 Nov 2016 10:46

ok that function, must version = 3 :

Code: Select all

cat ldap-users.cf
server_host = s1.domain.net
search_base = dc=domain,dc=net
bind = yes
bind_dn = ldapuser
bind_pw = domainpass
query_filter = (|(mail=%s)(proxyAddresses=smtp:%s))
leaf_result_attribute = mail
# result_format = %S OK
result_format = OK
version = 3

c0mputerking
Posts: 29
Joined: 26 Aug 2014 23:47

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by c0mputerking » 15 Nov 2016 21:43

Hello I am a totally newbie with LDAP, but it would be really great to get LDAP working with EFA I am running a brand new EFA 3.0.1.5 and Zimbra LDAP email server. I have added the suggested lines to my /var/www/html/mailscanner/conf.php. However i do not see any users being added to EFA i know it is not magic but when and how are the users supposed to be added? Is there a log i can check somewhere? I did read some other posts on this forum about LDAP but they were all for older versions.

// LDAP settings
define('USE_LDAP', true);
define('LDAP_SSL', false);
define('LDAP_HOST', '10.0.10.129');
define('LDAP_PORT', '389');
define('LDAP_DN', 'DC=mydomain,DC=ca');
define('LDAP_USER', 'ryan@mydomain.ca');
define('LDAP_PASS', 'supersecretpassword');
define('LDAP_SITE', 'default');
//define('LDAP_EMAIL_FIELD', 'mail');

Next i will try adding the postfix parts

GJurriens
Posts: 10
Joined: 28 Mar 2016 10:29

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by GJurriens » 29 Nov 2016 19:02

Is there an option to exclude a domain from LDAP lookups?
I have one domain that I would like to have filtered, but another that I can't have filtered (because there is no domain structure behind that domain).

stusmith
Posts: 63
Joined: 27 Jan 2017 15:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by stusmith » 21 Feb 2017 13:51

We are in an interesting scenario in which we have external service that send e-mail notifications on our behalf - sometimes through our server. As such, I needed to require authentication for using our EFA as a relay.

I added:

Code: Select all

#/etc/postfix/main.cf
smtpd_sender_restrictions = permit_sasl_authenticated,
Then:

Code: Select all

ldap_servers: ldap://<xxx.xxx.xxx.xxx>
ldap_search_base:  cn=Users,dc=<DOMAIN>,dc=<DOMAIN-SUFFIX>
ldap_filter: (&(sAMAccountName=%u)(!(userAccountControl=514))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
ldap_bind_dn:  CN=<SERVICE USER>,CN=Users,DC=<DOMAIN>,DC=<DOMAIN-SUFFIX>
ldap_password: <PASSWORD>
NOTE: DON'T ADD THE BRACKETS, BUT REPLACE EVERYTHING INSIDE BRACKETS WITH YOUR OWN VALUES
And:

Code: Select all

#/etc/sasl2/smtpd.conf
mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 LDAP
pwcheck_method: saslauthd
auxprop_plugin: sasldb
$ sudo chkconfig --list saslauthd
saslauthd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
$sudo service saslauthd start


I really recommend updating the sections above to include the (!(userAccountControl=514))(!(userAccountControl:1.2.840.113556.1.4.803:=2)) section to all the LDAP filters. For active directory, this prevents letting accounts that are locked out or disabled access the system. DO NOT add this to your recipients filters or e-mail will be rejected for locked out or disabled users - probably not what you want.

Our policy is typically to disable accounts and forward e-mail to a manager in the event an employee leaves the company and rejected mail for disabled users would not facilitate this.

stusmith
Posts: 63
Joined: 27 Jan 2017 15:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by stusmith » 21 Feb 2017 14:05

It looks like the relevant file to modify is /var/www/html/mailscanner/functions.conf, starting at line 2610

Code: Select all

#/var/www/html/mailscanner/functions.conf

 //search for $user in LDAP directory
        if (LDAP_EMAIL_FIELD === 'mail' && strpos($user, '@')) {
            $ldap_search_results = ldap_search($ds, LDAP_DN, LDAP_EMAIL_FIELD . "=$user") or die(__('ldpaauth203'));
        } elseif (strpos($user, '@')) {
            $ldap_search_results = ldap_search($ds, LDAP_DN, LDAP_EMAIL_FIELD . "=SMTP:$user") or die(__('ldpaauth203'));
        } else {
            // Windows LDAP (with legacy NT support)
            $ldap_search_results = ldap_search($ds, LDAP_DN, "sAMAccountName=$user") or die(__('ldpaauth203'));
        }

I'll try to play around with this and see if I can incorporate a locked/disabled account query filter. It's probably not a bad idea to incorporate a group membership for permissions here as well ( and for the saslauthd setup ). That would allow restrictions such as not preventing service accounts from accessing the mailscanner interface or preventing vendor accounts from using the SMTPD service.

Assuming that your environment has a need for that...

stusmith
Posts: 63
Joined: 27 Jan 2017 15:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by stusmith » 21 Feb 2017 14:58

Okay, I think I've got it.

File is /var/www/html/mailscanner/functions.php, line 2610

Code: Select all

#/var/www/html/mailscanner/functions.php

        $ldap_query_sAMAccountName_custom = "(&(objectClass=user)(objectCategory=person)(sAMAccountName=$user)(!(userAccountControl=514))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))";
        $ldap_query_Email_Field_custom = "(&(objectClass=user)(objectCategory=person)(" . LDAP_EMAIL_FIELD . "=$user)(!(userAccountControl=514))(!(userAccountControl:1.2.840.113556.1.4.803:=2)));
        $ldap_query_Email_SMTP_custom = "(&(objectClass=user)(objectCategory=person)(" . LDAP_EMAIL_FIELD . "=SMTP:$user)(!(userAccountControl=514))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))";

        //search for $user in LDAP directory
        if (LDAP_EMAIL_FIELD === 'mail' && strpos($user, '@')) {
            //$ldap_search_results = ldap_search($ds, LDAP_DN, LDAP_EMAIL_FIELD . "=$user") or die(__('ldpaauth203'));
            $ldap_search_results = ldap_search($ds, LDAP_DN, $ldap_query_Email_Field_custom) or die(__('ldpaauth203'));
        } elseif (strpos($user, '@')) {
            //$ldap_search_results = ldap_search($ds, LDAP_DN, LDAP_EMAIL_FIELD . "=SMTP:$user") or die(__('ldpaauth203'));
            $ldap_search_results = ldap_search($ds, LDAP_DN, $ldap_query_Email_SMTP_custom) or die(__('ldpaauth203'));
        } else {
            // Windows LDAP (with legacy NT support)
            //$ldap_search_results = ldap_search($ds, LDAP_DN, "sAMAccountName=$user") or die(__('ldpaauth203'));
            $ldap_search_results = ldap_search($ds, LDAP_DN, $ldap_query_sAMAccountName_custom) or die(__('ldpaauth203'));
        }


From my tests this will prevent locked and disabled accounts from logging into the mailscanner web interface. You can add a group membership check here if you need to as well by adding (memberOf=<CN of group>) inside of the last parenthesis of the filter. If you're using Windows and have the RSAT tools installed, then it's fairly easy to get this by using the command dsquery group -name "<group name>"

I think somewhere above someone had added a question about using SSL or LDAPS. I'll add that to my 'TODO' list.

stusmith
Posts: 63
Joined: 27 Jan 2017 15:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by stusmith » 21 Feb 2017 21:48

Okay. LDAPS. Not working for sasl auth yet, but I'll try that next.

So, my assumption is that you've got a certificate for your AD DC already. In my case, I've got ADCS running PKI for my domain. I'll assume since you're using Windows that you've got the certificate in .DER format. What you'll want to get is the CA certificate for your domain controller - in my case, it's the root CA from the ADCS PKI server.

I can convert that to PEM format using openssl:

Code: Select all

openssl x509 -inform der -in certificate.cer -out ca-cert.pem
Next, copy this file to /etc/openldap/certs. I usually use putty so I'd use

Code: Select all

pscp ca-cert.pem user@efa-host:/etc/openldap/certs/ca-cert.pem
Edit the file: /etc/openldap/ldap.conf

Code: Select all


# LDAP Defaults
#

# See ldap.conf(5) for details
# This file should be world readable but not world writable.

#BASE   dc=example,dc=com
#URI    ldap://ldap.example.com ldap://ldap-master.example.com:666

#SIZELIMIT      12
#TIMELIMIT      15
#DEREF          never

TLS_REQCERT     never
TLS_CACERTDIR   /etc/openldap/certs
BASE    DC=<YOURDOMAIN>,DC=<YOURDOMAIN SUFFIX>
URI     ldaps://<FQDN of your DC>
This file should be copied to the $HOME of the user running the MailScanner process and renamed to .ldaprc. Which in our case is looks like it might be apache? I got this to work under my account, using a test script I created in php ( to get the ldap query working for disabled and locked out users )

test.php based on http://php.net/manual/en/function.ldap-bind.php and the modifications made in the earlier post to the ldap query.

Code: Select all

#/home/<myhome>/test.php
// config
$ldapserver = "ldaps://<FQDN of your DC>";
$ldapuser      = '<DN of your service account user>';
$ldappass     = '<secret>';
$ldaptree    = "<LDAP search base>";
$user        = "<this is the username we want to test authentication for>";


define("LDAP_EMAIL_FIELD", "proxyAddresses");

// connect
$ldapconn = ldap_connect($ldapserver) or die("Could not connect to LDAP server.");
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);


$ldap_query_sAMAccountName_custom = "(&(objectClass=user)(objectCategory=person)(sAMAccountName=$user)(!(userAccountControl=514))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))";
$ldap_query_Email_Field_custom = "(&(objectClass=user)(objectCategory=person)(" . LDAP_EMAIL_FIELD . "=$user)(!(userAccountControl=514))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))";
$ldap_query_Email_SMTP_custom = "(&(objectClass=user)(objectCategory=person)(" . LDAP_EMAIL_FIELD . "=SMTP:$user)(!(userAccountControl=514))(!(userAccountControl:1.2.840.113556.1.4.803:=2))

if ($ldapconn) {
    // binding to ldap server
    $ldapbind = ldap_bind($ldapconn, $ldapuser, $ldappass) or die ("Error trying to bind: ".ldap_error($ldapconn)."\n");
    // verify binding
    if ($ldapbind) {
        echo "LDAP bind successful...";


        $result = ldap_search($ldapconn,$ldaptree, $ldap_query_Email_SMTP_custom) or die ("Error in search query: ".ldap_error($ldapconn));
        $data = ldap_get_entries($ldapconn, $result);

        // SHOW ALL DATA
        echo 'Dump all data' . "\n";
        //print_r($data);
        echo '';

        for ($i=0; $i<$data["count"]; $i++) {
                echo "user: " . $data[$i]["dn"] . "\n";
        }



        echo "Number of entries found: " . ldap_count_entries($ldapconn, $result) . "\n";
    } else {
        echo "LDAP bind failed...\n";
        if (ldap_get_option($ldapconn, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error)) {
                echo "Error Binding to LDAP: $extended_error\n";
        } else {
                echo "Error Binding to LDAP: no additional information is available.\n";
        }
I run this with php -e test.php from /home/<my home drive>. This will ONLY work once you've copied /etc/openldap/ldap.conf to your home drive and renamed it .ldaprc. According to this https://www.mkssoftware.com/docs/man5/ldap_config.5.asp which was the first hit and I'm too lazy to search the actual OpenLDAP documentation just this minute, .ldaprc can be placed in the current working directory and function properly. So I'm hopeful that I can drop it in the /var/www/html/MailScanner/ directory and we'll be off and running. I recommend using

Code: Select all

sudo tcpdump -i eth0 host <Your DC FQDN>
to verify that you're connecting via LDAPS and that the data is encrypted.

So, next, edit /var/www/html/mailscanner/conf.php

Code: Select all

define('LDAP_HOST',        'ldaps://<Your DC FQDN>');
define('LDAP_PORT',        '389');
( I also copied the .ldaprc to /var/www/html/mailscanner/ folder, but I think that was not a necassary step )

I did not have mch luck using port 636. I received an error on the webpage when I attempted to log in. However, using 389 as above but preprending the server fully-qualified domain name with the ldaps:// uri-prefix did the trick. Verified with tcpdump as above.

I also managed to install python-ldap and python3 to try and work out how to automagically synchronize my 'users' table in the mailscanner database Active Directory. It's awesome that the recipient maps lookup live, but I can't trust my users to log into the new spam filter in order to generate a record to allow them to get spam non-delivery reports. I did it manually the first time using Softerra LDAP browser and exporting to a CSV which I imported into mysql, but I'm not a fan of manual processes like that on an ongoing basis. Too many things will come up and I'll get sidetracked and miss one.

Anyway, I hope this has been helpful to someone.

--EDITED--
SASL authentication is now using LDAPS after completing the above steps, edit the file below.
/etc/saslauthd.conf

Code: Select all

ldap_servers: ldaps://<Your DC FQDN>

stusmith
Posts: 63
Joined: 27 Jan 2017 15:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by stusmith » 28 Feb 2017 19:10

I forgot to mention the recipient restrictions:

/etc/postfix/relay_recipient_maps.cf

Code: Select all

/etc/postfix/ldap_relay_recipient_maps.cf
#
#
server_host = ldaps://<FQDN DC hostname>
search_base = CN=Users,DC=<Your Domain>,DC=<Your Domain Suffix>
version = 3
scope = sub
bind_dn = CN=<Your AD Account>,CN=Users,DC=<Your Domain>,DC=<Your Domain Suffix>
bind_pw = <super secret stuff>
domain = <your FQDN domain>
bind = yes
query_filter = (|(proxyAddresses=smtp:%s)(proxyAddresses=SMTP:%s))
result_attribute =
leaf_result_attribute = proxyAddresses
you can test this with: *NOTE* you need to supply the full path to the file from the root, otherwise, it will wig out.
postmap -q '<an e-mail address that's valid for Exchange>' ldap:/etc/postfix/relay_recipient_maps.cf

stusmith
Posts: 63
Joined: 27 Jan 2017 15:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by stusmith » 28 Feb 2017 19:26

Also, I have a Python3 script that I'm using with the 'PyMySQL' and 'ldap3' modules which queries my Active Directory for users and group memberships, then queries the mailscanner database and updates each user with their Active Directory attributes. It then updates the user_filter to allow users to see the quarantines for distribution groups for which they are members.

I'll post it here once I clean some things up. I extended two database tables, adding a column in users and a column in user_filters.

Code: Select all

sudo yum install python34
/usr/bin/pip3.4 install ldap3
/usr/bin/pip3.4 install PyMySQL

mysql mailscanner -u root -p

ALTER TABLE users ADD COLUMN guid varchar(36);
ALTER TABLE user_filters ADD COLUMN manual enum('N','Y') default 'Y';
This addition of the 'manual' column lets the script flush all of the 'automatically' added filters from the table for each user it updates while preserving filters added from the web interface. Adding the guid column for the Active Directory objectGUID will eventually let me track when a user has been renamed or their SMTP address has changed and to update their attributes and add a 'temporary' filter to allow them to see the mail from their old address.

Right now, it just performs an INSERT INTO users (blah, blah, blah) ON DUPLICATE KEY UPDATE (blah blah blah) so it needs a little love there. The eventual plan is to have it read a configuration file in which the LDAP configuration will be stored, as well as the queries for each server.

kwaci
Posts: 1
Joined: 19 Mar 2017 06:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by kwaci » 19 Mar 2017 06:35

Hello,
I have been installing E.F.A 3.0.1.8 and it work great. 8-)

Need advise regarding query Active-Directory (LDAP) Domain for valid recipients.
My config still not query Active-Directory.
My Domain : contoso.local (only for internal)
My Domain alias : contoso.com (for public)

Error Log
Mar 19 13:02:33 mailgw postfix/smtpd[28633]: connect from mail.edustria.be[185.159.220.230]
Mar 19 13:02:35 mailgw sqlgrey: grey: from awl match: updating 185.159.220(185.159.220.230), echo@mailtester.com(echo@mailtester.com)
Mar 19 13:02:35 mailgw postfix/smtpd[28633]: warning: dict_ldap_lookup: Search error 9: Partial results and referral received
Mar 19 13:02:35 mailgw postfix/smtpd[28633]: warning: ldap:/etc/postfix/ldap_relay_recipient_maps.cf lookup error for "nonexistent.e-mail_745881@contoso.com"
Mar 19 13:02:35 mailgw postfix/smtpd[28633]: NOQUEUE: reject: RCPT from mail.edustria.be[185.159.220.230]: 451 4.3.0 <nonexistent.e-mail_745881@contoso.com>: Temporary lookup failure; from=<echo@mailtester.com> to=<nonexistent.e-mail_745881@contoso.com> proto=ESMTP helo=<mailtester.com>
Mar 19 13:02:36 mailgw sqlgrey: grey: from awl match: updating 185.159.220(185.159.220.230), echo@mailtester.com(echo@mailtester.com)
Mar 19 13:02:36 mailgw postfix/smtpd[28633]: warning: dict_ldap_lookup: Search error 9: Partial results and referral received
Mar 19 13:02:36 mailgw postfix/smtpd[28633]: warning: ldap:/etc/postfix/ldap_relay_recipient_maps.cf lookup error for "user1@contoso.com"
Mar 19 13:02:36 mailgw postfix/smtpd[28633]: NOQUEUE: reject: RCPT from mail.edustria.be[185.159.220.230]: 451 4.3.0 <user1@contoso.com>: Temporary lookup failure; from=<echo@mailtester.com> to=<user1@contoso.com> proto=ESMTP helo=<mailtester.com>
Mar 19 13:02:36 mailgw postfix/smtpd[28633]: disconnect from mail.edustria.be[185.159.220.230] ehlo=1 mail=1 rcpt=0/2 rset=1 vrfy=0/2 quit=1 commands=4/8



etc/postfix/ldap_relay_recipient_maps.cf
#example for Windows AD-Server
server_host = "myhost"
# I needed "DC=" twice because of our AD structure. Examine your AD to know what to put in here!
search_base = DC=contoso,DC=local
scope = sub
bind_dn = "myuser"
bind_pw = "mypassword"
bind = yes
query_filter = (&(userPrincipalName=%s)(objectClass=person)(!(userAccountControl=514)))
result_attribute = userPrincipalName

stusmith
Posts: 63
Joined: 27 Jan 2017 15:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by stusmith » 23 Mar 2017 12:56

kwaci wrote:
19 Mar 2017 06:35
Hello,
I have been installing E.F.A 3.0.1.8 and it work great. 8-)

Need advise regarding query Active-Directory (LDAP) Domain for valid recipients.
My config still not query Active-Directory.
My Domain : contoso.local (only for internal)
My Domain alias : contoso.com (for public)

Error Log
Mar 19 13:02:33 mailgw postfix/smtpd[28633]: connect from mail.edustria.be[185.159.220.230]
Mar 19 13:02:35 mailgw sqlgrey: grey: from awl match: updating 185.159.220(185.159.220.230), echo@mailtester.com(echo@mailtester.com)
Mar 19 13:02:35 mailgw postfix/smtpd[28633]: warning: dict_ldap_lookup: Search error 9: Partial results and referral received
Mar 19 13:02:35 mailgw postfix/smtpd[28633]: warning: ldap:/etc/postfix/ldap_relay_recipient_maps.cf lookup error for "nonexistent.e-mail_745881@contoso.com"
Mar 19 13:02:35 mailgw postfix/smtpd[28633]: NOQUEUE: reject: RCPT from mail.edustria.be[185.159.220.230]: 451 4.3.0 <nonexistent.e-mail_745881@contoso.com>: Temporary lookup failure; from=<echo@mailtester.com> to=<nonexistent.e-mail_745881@contoso.com> proto=ESMTP helo=<mailtester.com>
Mar 19 13:02:36 mailgw sqlgrey: grey: from awl match: updating 185.159.220(185.159.220.230), echo@mailtester.com(echo@mailtester.com)
Mar 19 13:02:36 mailgw postfix/smtpd[28633]: warning: dict_ldap_lookup: Search error 9: Partial results and referral received
Mar 19 13:02:36 mailgw postfix/smtpd[28633]: warning: ldap:/etc/postfix/ldap_relay_recipient_maps.cf lookup error for "user1@contoso.com"
Mar 19 13:02:36 mailgw postfix/smtpd[28633]: NOQUEUE: reject: RCPT from mail.edustria.be[185.159.220.230]: 451 4.3.0 <user1@contoso.com>: Temporary lookup failure; from=<echo@mailtester.com> to=<user1@contoso.com> proto=ESMTP helo=<mailtester.com>
Mar 19 13:02:36 mailgw postfix/smtpd[28633]: disconnect from mail.edustria.be[185.159.220.230] ehlo=1 mail=1 rcpt=0/2 rset=1 vrfy=0/2 quit=1 commands=4/8



etc/postfix/ldap_relay_recipient_maps.cf
#example for Windows AD-Server
server_host = "myhost"
# I needed "DC=" twice because of our AD structure. Examine your AD to know what to put in here!
search_base = DC=contoso,DC=local
scope = sub
bind_dn = "myuser"
bind_pw = "mypassword"
bind = yes
query_filter = (&(userPrincipalName=%s)(objectClass=person)(!(userAccountControl=514)))
result_attribute = userPrincipalName
You can use

Code: Select all

sudo postmap -q "your.users.email.address@yourdomain.com" /etc/postfix/ldap_relay_recipient_maps.cf
to check that the lookups are working.

I had to add

Code: Select all

version = 3
result_attribute =
leaf_result_attribute = proxyAddresses
Another thing that's confusing is that the queries will be different for the php for logging into the MailWatch interface and the ldap host lookup. Your query will work, but only if the userprincipalName is the same as the Email address. This is sometimes true, depending on how your environment is set up. ( It would be awesome if it was always true )

Adding the userAccountControl field is a good idea for login to MailWatch, but if you add it here your users will not receive Email if their account is locked out - probably not what you want. Filtering the objectClass=user and objectCategory=person also speeds up lookups for logins, but will prevent you from finding mail-enabled groups or Exchange distribution groups. If you don't have any mail-enabled groups or distribution lists in Active Directory, that's a good way to go as it will save you some query time. However, if you want to find groups you should remove that from your query.

If you've got a big directory structure, and you need some more speed, you can try,

Code: Select all

(&(|(&(objectClass=person)(objectCategory=user))(objectCategory=group))(|(proxyAddresses=smtp:%s)(proxyAddresses=SMTP:%s)))
which will get you users and groups that have SMTP addresses set in the proxyAddress property. If you've got a crazy big Active Directory environment and that's still too slow, O'Reilly has a great book on Active Directory, available in print ( https://www.amazon.com/Active-Directory ... 0596101732 and on Safari Bookshelf. I refer you there because if the isn't fast enough, you'll need to modify the schema to create a new index in the GC to speed things up. ...Sorry... my morning coffee just kicked in.

My search filter for address lookups here is:

Code: Select all

query_filter = (|(proxyAddresses=smtp:%s)(proxyAddresses=SMTP:%s))
result_attribute =
leaf_result_attribute = proxyAddresses
My result_attribute is empty, and my leaf_result_attribute is proxyAddresses. I expect that you'll need to set version = 3 to handle the referrals that you're getting.

I've also found, because I tend to make typos like they're going out of style, that I can use Softerra LDAP Browser to double check my settings ( to make sure that I'm not having login problems ) and I also use it to test my LDAP queries. The Browser product is free to use and download; you only have to purchase the Administrator version. I've used it so much over the years I feel guilty about not having bought the Administrator version just to support that company. You can find it here:http://www.ldapbrowser.com/info_softerr ... rowser.htm

stusmith
Posts: 63
Joined: 27 Jan 2017 15:24

Re: How to integrate E.F.A with Active Directory on 3.0.0.9

Post by stusmith » 23 Mar 2017 16:01

I've got a working python script that I use to synchronize MailWatch to Active Directory. I have a few more items to fix and items to polish before I post it here for all to enjoy, but I need some feedback.

Right now, I add filters to each user based on their group memberships and based on their exchange mailbox delegations. For example, if cindy.loo.who@whoville.com is in allthewhos.in@whoville.com, then Cindy-Loo gets a filter that allows her to manage the quarantine for allthewhos.in@whoville.com. Fine and well. Assuming Cindy-Loo also has the SendOnBehalf Exchange permission for grinchdog.max@whoville.com then she will be a member of the Max's Active Directory publicDelegates and will also get a filter for his address. ( Dogs can't type or use a standard mouse easily and thus need help checking their e-mail. Also, AFAIK, illiterate. )

However, quarantine reports become interesting. Right now, in order to simplify matters, I'm adding mailing lists as users in MailWatch. They don't have passwords, so they shouldn't be able to log in ( tested ). The main thing that this does is allow me to see the mailing lists and manage their preferences in terms of SPAM level, etc. Of course, newer versions of eFa send quarantine reports based on filters as well. This is a good thing. It means that users get notified when they have items in the quarantine of mailing lists.

The drawback becomes apparent when we turn on quarantine reports for "all users" with a database action and then we receive duplicates because cindy.loo.who@whoville.com gets her quarantine report, the report for her filter from allthewhos.in@whoville.com and then gets another report when allthewhos.in@whoville.com gets its quarantine report Email which is dutifully forwarded to all members of the list.

I have a couple of thoughts on the matter:
  1. First Approach: Modify the 'Users'
    • The absolute "correct" way to deal with this would be to change the mailscanner.users.type field to 'G' for groups and rewrite functions to make use of this by editing quarantine_report.php to exclude users matching this field and make sure that the python script sets this field when adding or updating Active Directory objects with objectClass=group
    • The simple way to resolve this is to add a tinyint(1) default='0' column isGroup to mailscanner.users and edit the SQL in quarantine_report.php to prevent sending reports to groups if we're going to send reports to users combined with editing my script to make sure that Active Directory objects with objectClass=group set the mailscanner.users.isGroup = '1' when adding or updating.
  2. Second Approach: Modify the 'Filters'
    • Add the column above to the mailscanner.user_filters table
    • Add a similar column IsDelegate
    • Make sure that the script tags the filter correctly
    • Add MailWatch configuration option to determine whether or not quarantine report Emails are exploded at the eFa or the server ( sent to the group, or sent to the users individually )
    • Add Mailwatch configuration option to determine if users get quarantine reports for their delegates
    • Edit quarantine_report.php to respect the above options
So, down to the meat of it:
  1. Is there a common use-case in which it is preferable to send quarantine reports to the list and have the mailserver explode the message for individuals as opposed to having this take place on the filtering appliance?
  2. Is there a common use-case in which it is not desirable to allow users to manage the quarantines of mailing lists in which they have memberships?
  3. Is there a common use-case in which it is not desirable to allow users to manage the quarantines of their delegates?
Finally, is it desirable to be able to filter user types ( Administrator, Domain Administrator ) against Active Directory group(s)? Does it make more sense to have those functions set manually?

Post Reply