« November 2002 | Main | January 2003 »

December 18, 2002

产生mail loop的原因及解决方案

Mail loop是一个很常见,但有时却又让人很难发现故障所在的问题。如何去发现和解决呢?这里以我自己遇到的mail loop问题为例子,来分析一下个中原因。

日志里关于mail loop的内容如下:

Dec 18 18:35:20 smtp postfix/cleanup[9526]: 4846417D5E: 
    message-id=<20021218223122.C5B6C680A@smtp.hzqbbc.com> 
Dec 18 18:35:20 smtp postfix/qmgr[9342]: 4846417D5E:
    from=<hzqbbc@hzqbbc.com>, size=1431, nrcpt=4 (queue active) 
Dec 18 18:35:20 smtp postfix/local[9585]: C4F5117D5C: 
    to=<postmaster@192.168.0.27>, relay=local, delay=33,
    status=sent (forwarded as 4846417D5E) 
Dec 18 18:35:20 smtp postfix/local[9585]: 4846417D5E:
    to=<postmaster@192.168.0.27>, relay=local, delay=22, 
    status=bounced (mail forwarding loop for postmaster@192.168.0.27) 

这里ldap的entry是:
dn: mail=postmaster@overtheland.com,virtualDomain=overtheland.com,o=myldap
objectClass: top
objectClass: MailAccount
objectClass: MailAlias
accountActive: TRUE
mailacceptAction: RELAY
mail: postmaster@overtheland.com
homeDirectory: overtheland.com/postmaster
mailbox: overtheland.com/postmaster/Maildir/
quota: 20971520S,1000C
maildrop: postmaster@smtp.overtheland.com
maildrop: root@overtheland.com
maildrop: postmaster@192.168.0.27
maildrop: hzqbbc@redhut.net

相应的ldap设置是:
=================================================================
ldapstaraliasfixup_query_filter = (&(maildrop=%s)(accountActive=TRUE))
ldapstaraliasfixup_result_attribute = mail
~~~~~~~~~~~~
ldapforwardings_query_filter =(&(mail=%s)(accountActive=TRUE))
ldapforwardings_result_attribute = maildrop
~~~~~~~~~~~~~

这里为什么有问题呢?很简单的解释:我发信给root@192.168.0.27。按照alias部分的ldap
设定,信笺应该投递给postmaster@overtheland.com。。确实正常的投递了。不过问题也就
来了。因为还设置了forward部分,而它expect的是maildrop属性的值,这里maildrop有多个值
其中包括了root@192.168.0.27,这样forward时除了给那些非root@192.168.0.27的地址发信外
还会给root@192.168.0.27自己发信。。。这个就产生loop了(看log可看到)

之后。由于root@overtheland.com并不存在机器上(只是一个postmaster@overtheland.com)
的一个alias)。而这时pipe将信笺给了maildrop,maildrop查ldap时并没有办法查得出
root@overtheland.com就是postmaster@overtheland.com(这个是maildrop的ldap部分缺陷,
有待改进)。因此返回user unknow。这个时候自然得给发信者。。。

之后就是很混乱的loop及bounce 信笺了。所以注意一点。forward及alias必须分开来
设置(用不同属性)否则就麻烦了。

而有关类似的mail loop问题的讨论,在Postfix邮件列表上非常多,这里仅举一例:

寄件者:Dirk Datzert (Dirk.Datzert@rasselstein-hoesch.de)
主旨:postfix and ldap

View this article only
新闻群组:mailing.postfix.users
日期:2001-04-10 14:54:04 PST

Hi all,

I have a postfix question with ldap using:

How can I configure aliases_maps and virtual_maps for the following
issue:

a user has a local 'mail'/'mailalternateaddress' with 'uid' and an
'mailforwardingaddress'

I could configure for local delivery:

alias_maps: ldap:aliases

aliases_query_filter = (│(mail=%s)(mailalternateaddress=%s))
aliases_result_attribute = uid

If a user has no local address I can forward:

virtual_maps: ldap:forwarders

forwarders_query_filter = (│(mail=%s)(mailalternateaddress=%s))
forwarders_result_attribute = mailforwardingaddress

Now my question:

How can I configure postfix to do both for one user: delivery local and
forward ?

Thanx,
Dirk

-
To unsubscribe, send mail to majordomo@postfix.org with content
(not subject): unsubscribe postfix-users
第 4 条留言
寄件者:LaMont Jones (lamont@hp.com)
主旨:Re: postfix and ldap


View this article only
新闻群组:mailing.postfix.users
日期:2001-04-10 16:04:07 PST

> aliases_query_filter = (│(mail=%s)(mailalternateaddress=%s))
> aliases_result_attribute = uid
> virtual_maps: ldap:forwarders
> forwarders_query_filter = (│(mail=%s)(mailalternateaddress=%s))
> forwarders_result_attribute = mailforwardingaddress
> Now my question:
>
> How can I configure postfix to do both for one user: delivery local and
> forward ?

result_attribute is a _LIST of attributes, so if you can get the changes
down to one map (merge alias and virtual), then you can just say:
_result_attribute = uid mailforwardingaddress

Untested, your mileage may vary, but we have similar things working in
production.

lamont

Wietse关于mail loop的解释

m 如何防止mail loop?看看wietse如何说的 ( 2003年1月2日21:28 )

http://groups.google.com/groups?hl=zh-CN&lr=&ie=UTF-8&inlang=zh-CN&threadm=a3f25j%24urn%241%40FreeBSD.csie.NCTU.edu.tw&rnum=6&prev=/groups%3Fq%3Dmail%2Bloop%2Blist%2Bgroup:mailing.postfix.users%26hl%3Dzh-CN%26lr%3D%26ie%3DUTF-8%26inlang%3Dzh-CN%26selm%3Da3f25j%2524urn%25241%2540FreeBSD.csie.NCTU.edu.tw%26rnum%3D6

You must list myhostname under mydestination:

mydestination = $myhostname localhost.$mydomain ...

Otherwise you will have a mail loop.

Wietse

寄件者:Wietse Venema (wietse@porcupine.org)
主旨:Re: mail loops back to myself


View this article only
新闻群组:mailing.postfix.users
日期:2003-01-18 17:29:08 PST

Is clanetsys.homeunix.net listed in mydestination? See the
main.cf file comments for guidance.

Is clanetsys.homeunix.net listed in virtual_alias_domains?
See the virtual(5) manual page for guidance.

Is clanetsys.homeunix.net listed in virtual_mailbox_domains?
See the VIRTUAL_README file for guidance.

If the domain is not listed in any of the above, then mail
will loop.

Wietse

Posted by hzqbbc at 05:58 PM | Comments (0)

December 09, 2002

Postfix更换Logo了

一直以来,Postfix的logo都没有,现在,终于有一个了!不过不知道是谁设计的呢?感觉看上去还以为是mailman呢,但不管如何,有了就是有了!

请看这里:

具体地址在:

新Logo (2002-12-9)

Posted by hzqbbc at 09:58 PM | Comments (1)

December 05, 2002

限制特定用户收发邮件的高级访问控制方法

一般邮件应用稍微有一电规模的企业,大多都会涉及到这样的应用需求:

某销售A只能收到来自163.com及sina.com的邮件
某技术员B只能给内部用户发邮件,不允许向外网发邮件,但可以收到外网邮件
某主管可以收发内、外网邮件
......

如何实现呢?Postfix 1.x就已经可以通过配置实现这些功能了。

以下是邮件列表里Noel Jones 提出的解决方案:

Hello!

I have the same problem:

1. I need to permit some internal users (not all) to send mail to any
external user (Internet)
2. I need to permite any external user to send mail to some my internal
users (not all)

In fact, the problem is: just "some" of my internal users have permission to
receive mail from and send mail to the Internet.

How can I solve this?

寄件者:Noel Jones (njones@megan.vbhcs.org)
主旨:Re: RES: User Restriction.....


View this article only
新闻群组:mailing.postfix.users
日期:2002-12-04 15:18:04 PST

At 05:39 PM 12/4/02 -0200, raissa.medeiros@caixa.gov.br wrote:
>1. I need to permit some internal users (not all) to send mail to any
>external user (Internet)
>2. I need to permite any external user to send mail to some my internal
>users (not all)
>
>In fact, the problem is: just "some" of my internal users have permission
>to receive mail from and send mail to the Internet.
>
>How can I solve this?
>
>Thanks,
>Raissa

Restricting also who can receive mail from the internet changes the example
I posted a few minutes ago.

In the example below, the same list of restricted_users is used for
controlling both who can send and who can receive internet mail. If you
don't require the local_plus feature, just leave that part out.

  1. in main.cf:
  1. use restriction classes to make restricted_users file more readable.
    smtpd_restriction_classes = local_only, local_plus

local_only =
reject_unauth_destination
permit_mynetworks
reject

local_plus =
check_recipient_access hash:/etc/postfix/local_plus
check_sender_access hash:/etc/postfix/local_plus
reject_unauth_destination
permit_mynetworks
reject

  1. this is the default setting, required for this setup.
    smtpd_delay_reject = yes
  1. we'll do this in sender restrictions to avoid open relay problems.
    smtpd_sender_restrictions =
    check_sender_access hash:/etc/postfix/restricted_users
    check_recipient_access hash:/etc/postfix/restricted_users

and in /etc/postfix/restricted_users
# /etc/postfix/restricted_users
# this file contains a list of users only allowed to send and receive local
mail
# postmap this file after changes
# local users not listed here have no restrictions
user1@miodemi.com local_only
user2@miodemi.com local_plus

and in /etc/postfix/local_plus:
# /etc/postfix/local_plus
# this file contains allowed destinations and senders
# for users restricted to local_plus
# postmap this file after changes
miproveedor.com OK

Remember to "postmap local_plus" and "postmap restricted_users" after
making changes to them.
Remember to run "postfix reload" after changing main.cf

我自己常用的限制方法

有几个方法:

1) smtpd_restriction_classes = local_only
设置一个限制类别叫local_only,然后参考access(5)的格式做一个访问控制:

local_only = check_recipient_access hash:/etc/postfix/maps/my_rcpt

文件my_rcpt内容:

163.com RELAY
21cn.com RELAY
hzqbbc.com RELAY

然后,设置:

smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/maps/mysender 

mysender内容:

hzqbbc@local.hzqbbc.com   local_only 

这样凡是Mail from:的信只能RCPT TO: 到163.com, 21cn.com及 hzqbbc.com 三个地方了。其他的都发不出去。

按这个方法,还可以设置更多的类别,例如remote_only以及不限制的帐号等。但这些都只对from:限制。而且不管是否SASL后的。所以有一定缺陷。不过,已经达到目的了。

2)使用snapshot版的policy策略
根据某个hash表或配置文件,判断对应的sender和recipient是否匹配,匹配就返回OK或者DUNNO或者RELAY等(可能RELAY已经过时,这个是postfix 1.1.x的)如果不匹配就返回错误代码

按postfix所带的smtpd-policy.pl模式,修改一下就可以使用了。详细参考POLICY_README等。

3)使用APF for postfix
详细地址:http://apf.org.cn/addon/

其实和2)方法是基本一致的。同样利用postfix内置的policy功能。

Last Update: 2005-06-06

Posted by hzqbbc at 07:34 PM | Comments (0)

December 02, 2002

维护Postfix的一些脚本、程序集锦

作为一名Postfix的管理员,维护Postfix的正常运行,并随时排除故障,这是最基本的任务。本文提供了一些我自己写及平时搜集到的脚本和程序,以便实现自动化的维护和操作。包括自动清理日志,分析日志,自动增加用户等等。

分析拒收邮件的日志分析程序
作者:Wietse Venema

Message 6 in thread
寄件者:Wietse Venema (wietse@porcupine.org)
主旨:Re: Freebsd Postifx Daily messages


View this article only
新闻群组:mailing.postfix.users
日期:2002-12-01 10:48:47 PST

Here's my own /etc/periodic/daily/460.status-mail-rejects script,
and yes it needs updating when logging formats change.

This script will not show rejected mail when the client never
returned after a soft (450) error code from the server. I use 450
for non-FQDN HELO hostnames, so that I can whitelist mis-configured
sites that aren't spammers.

Wietse


#!/bin/sh
# 

echo ""; echo "Scanning maillog for rejections:" 
zcat -fc /var/log/maillog.0* /var/log/maillog | egrep reject: | \
cut -d : -f 5- | sort | uniq -c | sort -nr | \
grep -v '^  *[1-2]  *[^ ]* [^ ]* from [^ ]*: 450 ' 

echo "";
echo "Scanning maillog for warnings:" 
zcat -fc /var/log/maillog.0* /var/log/maillog | egrep warning: | \
cut -d : -f 5- | sort | uniq -c 

print "";
echo "Scanning maillog for trouble:" 
zcat -fc /var/log/maillog.0* /var/log/maillog | egrep '(fatal|panic):' 

exit 

Post a follow-up to this message

一个简单的分析log的脚本
Author: Michael Tokarev


#!/bin/sh 
# Parses postfix style logs 

if [ $# -ne 2 ]; then 
 echo "Usage: `basename $0` logfile search-criteria" 
 exit 1 
fi 

TMPLOG="/tmp/`basename $0`.work.$$" 
MATCHES="/tmp/`basename $0`.matches.$$" 
LOGFILE="$1" 

if [ "${LOGFILE}" != "-" -a ! -f ${LOGFILE} ]; then 
 echo "File not found (${LOGFILE})" 
 exit 2 
fi 

if echo ${LOGFILE} │ egrep '\.bz2$' >/dev/null 2>&1; then 
 CAT="bunzip2 -c ${LOGFILE}" 
elif echo ${LOGFILE} │ egrep '\.(Z│gz)$' >/dev/null 2>&1; then 
 CAT="gunzip -c ${LOGFILE}" 
elif [ "${LOGFILE}" = "-" ]; then 
 cat > ${TMPLOG}.orig 
 CAT="cat ${TMPLOG}.orig" 
else 
 CAT="cat ${LOGFILE}" 
fi 

shift 

${CAT} │ egrep -i "$1" │ \ 
 awk '$9 ~ /^[A-Z0-9][A-Z0-9]*:$/ {print $1 " *" $2 ".*" $9}' > ${MATCHES} 
[ -s ${MATCHES} ] && ${CAT} │ egrep -i -f ${MATCHES} 

[ -f ${TMPLOG}.orig ] && rm ${TMPLOG}.orig 
[ -f ${TMPLOG} ] && rm ${TMPLOG} 
[ -f ${MATCHES} ] && rm ${MATCHES} 

exit 0

我写的一个简单邮件IN/OUT分析脚本
Author: hzqbbc

是参考了Wietse的reject 分析脚本后,得到启发写的,希望对用Postfix的朋友有点帮助。


#!/bin/bash
# mail-statistic.sh : 
# Simple script for analysis Postfix maillog 
# Version: 0.03 
# Author: hzqbbc@hzqbbc.com 
# 

RAN=`echo $RANDOM` 
echo "Mail log analysis ID is $RAN " 
echo "Checking ...................." 
echo "" 
echo "" 
# make a direcotry to contain temp log file 
mkdir $RAN 
cp /var/log/maillog $RAN/maillog 
zcat /var/log/maillog.*.gz >> $RAN/maillog 

# statistic recipient 
echo "Part one : - Top 10 Recipient domain " 
fgrep to= $RAN/maillog | cut -d\< -f2 | cut -d\> -f1 | \
cut -d@ -f2 | sort | uniq -c | sort -nr |head 
echo "" 
echo "" 

# statistic sender 
echo "Part two: - Top 10 Sender domain " 
fgrep from= $RAN/maillog | cut -d\< -f2 | cut -d\> -f1 | \ 
cut -d@ -f2 | sort | uniq -c | sort -nr | head 
echo "" 
echo "" 

# statistic destination mail total count 
echo "Part three: Total lines and sizes of log, And total mail sent" 
echo "Log_lines = `cat $RAN/maillog | wc -l | awk '{ print $1 }'`" 
echo "Log_sizes = `du -s $RAN/maillog | awk '{ print $1}'`" 
echo "Mail_sent = `cat $RAN/maillog | fgrep status=sent | wc -l | \ 
awk '{ print $1 }'`" 
rm -rf $RAN

Posted by hzqbbc at 10:07 AM | Comments (0)