Score:0

How to proxy IMAP/POP3 connection to appropriate backend mail server by domain

ng flag

I have system with multiple email server (exchange, zimbra) for multiple domain. So when users of domain A want connect to server for getting email they have to use IP of server A (Ex: 192.168.10.253), same way with user of domain B, they have to use IP of server B (Ex: 192.168.20.253).

I want simplify connection between users and mail server by create a proxy server for IMAP/POP3 connection but I can not find solution to do it, is there anyway to do it? pls give me the keywork or a solution for better. Thank you so much.

Image description for my question

Score:0
ng flag

This is my solution, hope it help.

This is my proxy system architect

This is configre in nginx

mail {
         auth_http localhost:80/ldap_auth.php;
         pop3_capabilities "TOP" "USER";
         imap_capabilities "IMAP4rev1" "UIDPLUS";

        server {
                listen     110;
                protocol   pop3;
                pop3_auth plain apop cram-md5;
                proxy      on;
        }

        server {
                listen     143;
                protocol   imap;
                proxy      on;
        }
}

This is source code in ldap_auth.php

<?php
if (!isset($_SERVER["HTTP_AUTH_USER"]) || !isset($_SERVER["HTTP_AUTH_PASS"])) {
    fail();
}

$username = $_SERVER["HTTP_AUTH_USER"];
$userpass = $_SERVER["HTTP_AUTH_PASS"];
$protocol = $_SERVER["HTTP_AUTH_PROTOCOL"];

// default backend port
$backend_port = 110;

if ($protocol == "imap") {
    $backend_port = 143;
}

$backend_ip["domain1.com"] = "10.0.250.251";
$backend_ip["domain2.com"] = "10.0.220.140";

// Authenticate the user or fail
if (!authuser($username, $userpass)) {
    fail();
    exit;
}

$userserver = getmaildomain($username);

$server_ip = (isset($backend_ip[$userserver])) ? $backend_ip[$userserver] : $userserver;

// Pass!
pass($server_ip, $backend_port);

//END

function authuser($user, $pass)
{
    $pass = str_replace('%20', ' ', $pass);
    $pass = str_replace('%25', '%', $pass);
    $emailDomain = getmaildomain($user);
    $emailUsername = getmailuser($user);

    $ldapconfig['host'] = '10.0.250.241';
    $ldapconfig['port'] = '389';
    $ldapconfig['basedn'] = 'ou=' . $emailDomain . ',dc=topdomain,dc=vn';
    $ldapconfig['binduser'] = 'cn=admin,dc=topdomain,dc=vn';
    $ldapconfig['bindpass'] = 'P@ssw0rd';
    $ds = ldap_connect($ldapconfig['host'], $ldapconfig['port']);

    if (isset($ds)) {
        ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
        ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
        ldap_set_option($ds, LDAP_OPT_NETWORK_TIMEOUT, 10);

        if (isset($user) && isset($pass)) {
            if (ldap_bind($ds, $ldapconfig['binduser'], $ldapconfig['bindpass'])) {
                if ($search_result = ldap_search($ds, $ldapconfig['basedn'], "(|(uid=%U)(sAMAccountName=%U))")) {
                    $entries = ldap_get_entries($ds, $search_result);
                    if ($entries['count'] == 1) {
                        $dn = $entries[0]['dn'];
                        if (ldap_bind($ds, $dn, $pass)) {
                            return true;
                        } else {
                            return false;
                        }
                    }
                }
            }
        }
    }
    return false;
}

function getmaildomain($user)
{
    return substr($user, strpos($user, '@') + 1);
}

function getmailuser($user)
{
    return substr($user, 0, strpos($user, '@'));
}

function fail()
{
    header("Auth-Status: Invalid login or password");
    exit;
}

function pass($server, $port)
{
    header("Auth-Status: OK");
    header("Auth-Server: $server");
    header("Auth-Port: $port");
    exit;
}

this is configuration in OpenLDAP Font-end

include /etc/ldap/schema/core.schema 
include /etc/ldap/schema/corba.schema 
include /etc/ldap/schema/cosine.schema 
include /etc/ldap/schema/duaconf.schema 
include /etc/ldap/schema/dyngroup.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/java.schema 
include /etc/ldap/schema/misc.schema 
include /etc/ldap/schema/nis.schema 
include /etc/ldap/schema/openldap.schema 
include /etc/ldap/schema/collective.schema 
include /etc/ldap/schema/pmi.schema 
include /etc/ldap/schema/ppolicy.schema
allow bind_v2
# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral  ldap://root.openldap.org

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

# Load dynamic backend modules: 
modulepath  /usr/lib/ldap 
moduleload  rwm.la
moduleload  back_meta.la 
moduleload  back_ldap.la
loglevel -1
            #######################################################################
# LDAP remote server definitions
            #######################################################################

#Fontend
database meta
suffix "dc=topdomain,dc=vn"
rootdn "cn=admin,dc=topdomain,dc=vn"
rootpw P@ssw0rd

#doamin1.vn - Server
uri "ldap://10.0.250.251/ou=domain1.vn,dc=topdomain,dc=vn"
readonly no 
lastmod off
suffixmassage "ou=domain1.vn,dc=topdomain,dc=vn" "DC=domain1,DC=vn"
map attribute uid sAMAccountName
idassert-bind bindmethod=simple
binddn="CN=ldap,CN=Users,DC=domain1,DC=vn"
credentials="P@ssw0rd"
idassert-authzFrom "dn.exact:cn=admin,dc=topdomain,dc=vn"

#doamin1.vn - Server
uri "ldap://10.0.220.45/ou=domain2.vn,dc=topdomain,dc=vn"
readonly no 
lastmod off
suffixmassage "ou=domain2.vn,dc=topdomain,dc=vn" "DC=domain2,DC=vn"
map attribute uid sAMAccountName
idassert-bind bindmethod=simple
binddn="CN=LDAP Admin,CN=Users,DC=domain2,DC=vn"
credentials="P@ssw0rd"
idassert-authzFrom "dn.exact:cn=admin,dc=topdomain,dc=vn"
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.