![如何通过域名将 IMAP/POP3 连接代理到适当的后端邮件服务器](https://linux22.com/image/767426/%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87%E5%9F%9F%E5%90%8D%E5%B0%86%20IMAP%2FPOP3%20%E8%BF%9E%E6%8E%A5%E4%BB%A3%E7%90%86%E5%88%B0%E9%80%82%E5%BD%93%E7%9A%84%E5%90%8E%E7%AB%AF%E9%82%AE%E4%BB%B6%E6%9C%8D%E5%8A%A1%E5%99%A8.png)
我的系统包含多个电子邮件服务器(Exchange、Zimbra),用于多个域。因此,当域 A 的用户想要连接到服务器以获取电子邮件时,他们必须使用服务器 A 的 IP(例如:192.168.10.253),域 B 的用户也是如此,他们必须使用服务器 B 的 IP(例如:192.168.20.253)。
我想通过为 IMAP/POP3 连接创建代理服务器来简化用户和邮件服务器之间的连接,但我找不到解决方案,有什么办法吗?请给我关键字或更好的解决方案。非常感谢。
答案1
这是我的解决方案,希望它有所帮助。
这是我的代理系统架构师
这是 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;
}
}
这是 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;
}
这是 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"