Postfix + Exchange + ActiveDirectory;如何混合使用它们

Postfix + Exchange + ActiveDirectory;如何混合使用它们

我的客户有多家分公司,一家总部,总部有一个域名:business.com

许多分支机构中的所有用户都需要有一个总部电子邮件地址:[email protected] 总部以外的任何人都需要将电子邮件转发到外部电子邮件地址。总部的所有用户的电子邮件都将发送到 Microsoft Exchange。用户在 Active Directory 中列在两个不同的 OU 下:HeadOfficeSubOffice

这是可以配置的吗?我在谷歌上搜索过,但找不到任何以这种方式设置的示例或企业。

编辑:Postfix 将接受所有电子邮件,需要确定将电子邮件转发到外部帐户或将其递送至 MS Exchange。

我读了一些有关 MS Exchange 的资料,知道您可以“启用邮件”联系人进行转发 - 但我不知道每个 AD 帐户是否都需要 Exchange CAL?

最终目标是将电子邮件转发到外部帐户、分支机构或接受总部的电子邮件。

也许我不需要担心 Postfix 来执行此任务.....

http://www.windowsitpro.com/article/exchange-server-2010/exchange-server-licensing-some-of-your-questions-answered

“那么客户端访问许可证 (CAL) 呢?您需要为每个连接到 Exchange 的用户提供一个 CAL。虽然这可能不是 100% 准确,但我更愿意将其视为每个邮箱一个 CAL;对于组织外的用户、使用邮箱的自动化工具等,则有例外。Exchange 不会强制执行此限制,因此您需要确保为您支持的一组客户端拥有正确数量的 CAL。”

答案1

虽然严格来说这并没有回答您的问题,但只需对下面的 perl 脚本进行一些修改,您想要实现的目标应该相当容易。

perl 脚本查询活动目录并返回指定 OU 内与脚本中的模式匹配的电子邮件地址列表,然后重新生成 postfix 用于确定需要接受电子邮件的有效电子邮件地址的配置文件。

perl 脚本由 bash 脚本调用,并通过 cron 启动。

通过一些工作,应该可以相当容易地调整脚本以允许您执行所需的操作。

请注意,您需要在 AD 中创建一个用户,并使用 perl 脚本中指定的详细信息,并且该用户帐户需要对 AD 中相关对象的读取权限。

$hqbase确定将搜索电子邮件地址的容器。

创建以下 bash 脚本,通过 cron 启动:

#!/bin/bash
# Get the email addresses from AD, if it fails exit the script
/root/getadsmtp.pl || exit
# Now convert the list into a file that postfix can understand
/usr/sbin/postmap /etc/postfix/exchange_recipients

以下是从上述 shell 脚本调用的文件 getadsmtp.pl。您需要修改它才能获得所需的结果。

use Net::LDAP;
use Net::LDAP::Control::Paged;
use Net::LDAP::Constant ( "LDAP_CONTROL_PAGED" );

$VALID = "/etc/postfix/exchange_recipients";

$dc1="dc1.example.local";
$dc2="dc2.example.local";

$hqbase="ou=foo,dc=example,dc=com";

$user="cn=postfix_xfer,ou=Services,ou=users,ou=foo,dc=example,dc=com";
$passwd="passwordgoeshere";

$noldapserver=0;
$ldap = Net::LDAP->new($dc1) or
   $noldapserver=1;
if ($noldapserver == 1)  {
   $ldap = Net::LDAP->new($dc2) or
      die "Error connecting to specified domain controllers $@ \n";
}

$mesg = $ldap->bind ( dn => $user,
                     password =>$passwd);
if ( $mesg->code()) {
    die ("error:", $mesg->code(),"\n","error name: ",$mesg->error_name(),
        "\n", "error text: ",$mesg->error_text(),"\n");
}

$page = Net::LDAP::Control::Paged->new( size => 990 );

@args = ( base     => $hqbase,
         filter => "(& (mailnickname=*) (| (&(objectCategory=person)
                    (objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))
                    (&(objectCategory=person)(objectClass=user)(|(homeMDB=*)
                    (msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=contact))
                    (objectCategory=group)(objectCategory=publicFolder)(objectClass=msExchDynamicDistributionList) ))",
          control  => [ $page ],
          attrs  => "proxyAddresses",
);

my $cookie;
while(1) {
  # Perform search
  my $mesg = $ldap->search( @args );

  foreach my $entry ( $mesg->entries ) {
    my $name = $entry->get_value( "cn" );
    # LDAP Attributes are multi-valued, so we have to print each one.
    foreach my $mail ( $entry->get_value( "proxyAddresses" ) ) {
     # Test if the Line starts with one of the following lines:
     # proxyAddresses: [smtp|SMTP]:
     # and also discard this starting string, so that $mail is only the
     # address without any other characters...
     if ( ( $mail =~ s/^(smtp|SMTP)://gs ) &&
          ( ( $mail =~ m/example.co.uk/ ) ||
            ( $mail =~ m/example.com/ ) ||
            ( $mail =~ m/example.org/ ) ||
            ( $mail =~ m/example.net/ ) ) ) {
       push(@valid, $mail." OK\n");
     }
    }
  }

  # Only continue on LDAP_SUCCESS
  $mesg->code and last;

  # Get cookie from paged control
  my($resp)  = $mesg->control( LDAP_CONTROL_PAGED ) or last;

  $cookie    = $resp->cookie or last;

  # Set cookie in paged control
  $page->cookie($cookie);
}

if ($cookie) {
  # We had an abnormal exit, so let the server know we do not want any more
  $page->cookie($cookie);
  $page->size(0);
  $ldap->search( @args );
  # Also would be a good idea to die unhappily and inform OP at this point
     die("LDAP query unsuccessful");
}
open VALID, ">$VALID" or die "CANNOT OPEN $VALID $!";
print VALID @valid;

close VALID;

希望这对你有所帮助。

相关内容