邮件HA系统
NOTE:
This is a project in work, so it can be changed on the fly. There's also no guarantee this setup will work for you.
本项目正在进行中,随时会有所改变,所以不会保证你的安装是否有效。
Tested on FreeBSD 4.4-RELEASE with Postfix 1.1.4,1 (PCRE, OpenLDAP) and OpenLDAP v2. 0. Description简介
This setup is build with four freebsd boxes, three running postfix, one OpenLDAP. One is "smtp forwarder", reffered to as "forwarder" while other two's are "backend mail storage servers" reffered to as "backends". OpenLDAP server is reffered to as "ldap server".
本安装需要4个freebsd的系统,3个运行postfix,1个运行OpenLDAP。1个postfix作为smtp转发器,本文以后称作“转发器”,另外两个作为后端邮件存储服务器,本文以后称作“后端”,OpenLDAP服务器本文称作ldap服务器。
The idea is to have N forwarders and M backends, all living inependently. When mail comes to forwarder, mail is sent to all, I repeat, all backend servers.
设想有N个转发器和M个后端,都独立运行,当邮件到达转发器,将发送到所有的后端。
Forwarder is publicly available, while others (backends and LDAP) are in private network with LAN IP's (10.10.10.0/24). Forwarder has two NIC's between which is no routing - backends and ldap do not have Internet access!
转发器可以被公共访问,后端和LDAP在私有网段(10.10.10.0/24)。转发器有两个网卡,之间没有路由,后端和ldap不能从internet访问。
This setup allows us to fine-tune access rights for all servers and also to know there's no way for intruders to get to our data (ldap and backends).
本文介绍的安装可以优化所有服务器的访问权限,禁止入侵者获得我们的数据(ldap和后端)。
Here's a picture: 示意图
For failover system we'll use freevrrpd daemon. Installation and setup is described in my previous article (http://uni.x-si.org/vrrpd.html).
对于故障恢复,我们采用freevrrpd daemon,其安装和设置请参照http://uni.x-si.org/vrrpd.html
1. LDAP server setup(LDAP服务器设置)
Install OpenLDAP2 on ldap server (http://www.openldap.org/software/download/).
在ldap服务器安装OpenLDAP2
Ldap schema we use:
#---- start here ----
attributetype ( 2.5.4.80 NAME 'maildrop' SUP mail 
attributetype ( 2.5.4.81 NAME 'mailacceptinggeneralid' SUP mail 
attributetype ( 2.5.4.82 NAME 'mailowner' SUP name 
attributetype ( 2.5.4.83 NAME 'homedir' SUP name 
attributetype ( 2.5.4.90 NAME 'maildrop1' SUP mail 
attributetype ( 2.5.4.91 NAME 'maildrop2' SUP mail 
objectclass ( 2.16.840.1.113730.3.3.1
NAME 'mailUser'
DESC 'x-si.org user'
SUP top
STRUCTURAL
MUST ( uid $ mailowner $ mailacceptinggeneralid $ maildrop
$ maildrop1 $ maildrop2 $ homedir 
MAY ( cn $ mail 
)
#---- end here ----
And relevant parts od slapd.conf:
Od slapd.conf中相关部分:
#---- start here ----
# x-si.org
include /etc/openldap/schema/x-si.schema
database ldbm
suffix "dc=x-si,dc=org"
rootdn "cn=Manager,dc=x-si,dc=org"
# and last, read only access to all
access to *
by * read
#---- end here ----
Ldif file for mail user:
邮件用户的Ldif文件:
#---- start here ----
dn: cn=makalonca, dc=x-si, dc=org
cn: makalonca
uid: makalonca
mailowner: uid=makalonca, dc=x-si, dc=org
mailacceptinggeneralid: makalonca@x-si.org
mail: makalonca@x-si.org
forward: makalonca@x-si.org
maildrop1: makalonca@backend1.x-si.org
maildrop2: makalonca@backend2.x-si.org
homedir: mail-storage/makalonca/
userPassword: {crypt}agdxu.da.cI5o
mail: makalonca@x-si.org
mail: lonca@x-si.org
mail: hulahup@x-si.org
objectclass: top
objectclass: mailUser
#---- end here ----
Next thing is to populate ldap with this data. Use ldapadd utility to add entries to ldap database (man ldapadd is your friend).
下面就是用这些数据建立ldap,使用ldapadd工具添加ldap数据库的记录(用man ldapadd察看帮助)。
Perhaps quick explanation, why maildrop1 and maildrop2. maildrop1 is result_attribute for postfix on first backend server, while maildrop2 is result_attrribute on second backend server.
简单解释一下为什么有maildrop1和maildrop2。Maildrop1是第一个后端服务器postfix的result_attribute,maildrop2是第二个后端服务器的result_attribute。
Obviously, if you want to set up N backend servers, than you need all entries from maildrop1 to maildropN (where N is the count of your backend servers).
显然,如果需要建立N个后端服务器,就需要所有的记录,从maildrop1到maildropN,N是后端服务器的数量。
2. Postfix setup(postfix设置)
Install Postfix 1.1.4,1 (with PCRE and OpenLDAP support) on forwarder and both backends (http://x-si.org/postfix/). On backends we'll use postfix's virtual delivery agent to act as local_transport.
在转发器和后端安装postfix 1.1.4.1(需要PCRE和OpenLDAP支持),在后端我们用postfix的虚拟分发代理作为local_transport。
On forwarder we'll use PCRE with virtusertable. This will also solve one of the biggest problem - updating aliases in real-time.
在转发器我们用虚拟用户表的PCRE,这样可以解决最大的一个问题——及时更新aliases。
2.1 Forwarder setup (inbound traffic only)(转发器设置,只接收邮件)
Setup this box to accept mail for our domain x-si.org. No need to define home_mailbox, mailbox_command or mail_spool_directory, because all mail will be forwarded. Nothing will stay on this machine.
安装本系统接收x-si.org的邮件,无需定义home_mailbox、mailbox_command或mail_spool_directory,因为所有邮件将被转发,本机不保存任何邮件。
The only thing left to do is, to forward all mails for domain x-si.org to all, I repeat, all backend servers. Here's how:
剩下的就是将x-si.org的所有邮件转发到所有的后端服务器,操作如下:
/etc/postfix/main.cf:
#---- start here ----
virtual_maps = pcre:/etc/postfix/virtusertable
#---- end here ----
Note: Watch for pcre: (not hash.
And /etc/postfix/virtusertable:
#---- start here ----
/^(.+)@x-si\.org$/ $1@backend1.x-si.org, $1@backend2.x-si.org
#---- end here ----
(Thanks to Ralf Hildebrandt for this hack)
Now here's a bit of magic. That PCRE regexp will memorize part in parenthesis, to which we have access through $1 variable. In other words, every alias name will be written to all destination addresses.
这里有个技巧,PCRE regexp将记住圆括号中的部分,即$1变量,也就是说,所有的alias名将被写入所有的目的地址。
This is great if you have few thousand users. There's no need to update this table, nor running postmap after every update.
如果没有几千个用户,这样就足够了,没必要更新这个表,也不用每次更新后运行postmap。
I guess there's no need to mention there can be more than two destinations - backend servers. Neat, huh?
我想没有必要再说两个以上后端服务器的情况了。
About that destination addressess... For example john.doe@backend1.x-si.org. This is address to which mail will be forwarded and exactly this is the value of result_attribute in main.cf on backend1 machine (defined as maildrop1). This is a value which postfix expects to get from virtual_maps.
关于目的地址,例如john.doe@backend1.x-si.org,这是将被转发的地址也是后端1服务器(maildrop1)main.cf中定义的result_attribute,这是postfix希望从virtual_maps获取的值。
Our servers are not 100% reliable, so we need to hold mail in queue until backend gets up again. We'll use Postifx's Fast ETRN Service.
我们的服务器不是100%可靠,所以需要保存邮件队列,直到后端服务器重启,可以使用postfix的Fast ETRN Service。
2.2 Forwarder setup (inbound & outbound traffic)(转发器设置,接收/发送)
Main configuration is the same as for the inbound traffic. Difference is in using LDAP lookups instead of hashed tables.
主要的设置与接收设置一样,不同点在于使用LDAP查询,而不是hashed表。
Needed main.cf changes: 需要更新main.cf的部分:
#---- start here ----
# from
virtual_maps = pcre:/etc/postfix/virtusertable
# to
virtual_maps = ldap:ldapalias
# plus LDAP lookups:
ldapalias_server_host = ldap.x-si.org
ldapalias_server_port = 389
ldapalias_search_base = dc=x-si,dc=org
ldapalias_timeout = 30
ldapalias_query_filter = (mail=%s)
ldapalias_domain = hash:/usr/local/etc/postfix/ldapvirtualdomains
ldapalias_result_attribute = forward,maildrop1,maildrop2
#---- end here -----
File "/usr/local/etc/postfix/ldapvirtualdomains" contain domains, for which we're accepting mail for:
#---- start here -----
x-si.org OK
#---- end here ------
Note: run postmap /usr/local/etc/postfix/ldapvirtualdomains after altering the file.
注意:更改后需要运行postmap /usr/local/etc/postfix/ldapvirtualdomains。
Here we get few options, which we haven't had before (with inbound only setup). Mail sent to any of 'mail =' attributes, will result in mail being delivered to all 'result_attribute =' values; here we got forward, maildrop1 and maildrop2.
我们这里有些以前只做接收时没有用到的选项,将邮件发送到所有mail=的值,将发送邮件到所有result_attribute =的值,包括转发、maildrop1和maildrop2。
If forward field is empty (ie. contains a single space character) and is listed as result_attribute, mail will be delivered only to maildrop1 and maildrop2 values.
如果转发域空(如包含一个空字符),并且列入result_attribute,邮件将只发往maildrop1和maildrop2。
However, if forward is defined, mail will be forwarded to that address. Next, with forward value defined, empty (not defined) maildrop1 and maildrop2 attributes will result as mail being forwarded and not stored on local system. With defined maildrop1, maildrop2 and forward, mail will get forwarded and stored on local system.
如果定义了转发,邮件将被发往定义的地址,根据转发值的定义,maildrop1和maildrop2属性值为空(无定义)表示邮件被转发而不被本地存储。当定义了maildrop1、maildrop2和转发时,邮件将被转发并存储在本地。
I'm not really sure 'result_attribute = forward,maildrop1,maildrop2' is the right way to specify multiple return attributes. Perhaps multiple LDAP 'result_attribute =' with only one value each would be "more" right than this. Anyway, please sent comments.
我不确定'result_attribute = forward,maildrop1,maildrop2'是指定多个返回值的正确方法,或许多个LDAP的只有一个值的'result_attribute ='更好,请大家提意见。
2.3 Fast ETRN service
In main.cf add these: 在main.cf中添加:
#---- start here ----
fast_flush_domains = $relay_domains
transport_maps = hash:/etc/postfix/transport
#---- end here ----
Only domains, we relay for will be able to use ETRN service. In transport_maps we say:
只有转发域能够用ETRN service,在transport_maps中需要增加:
#---- start here ----
backend1.x-si.org smtp:[IP_of_backend1_machine]
backend2.x-si.org smtp:[IP_of_backend2_machine]
#---- end here ----
NOTE: run postmap on transport file.
注意:传送文件时运行postmap。
This way, forwarder will deliver all mail for backend1 to it's IP, without doing a DNS query. All forwarders should have all backends in transport_maps. In case of backend server failure, mail on all forwarders will stay queued util ETRN command is issued.
这样,转发器将发送所有到后端1的邮件至其IP,不需要DNS查询。所有转发器在transport_maps都有所有的后端服务器表。如果后端服务器失效,所有转发器上的邮件将继续排队直到ETRN命令发出。
2.4 Backend1 setup(后端1设置)
Add user and group "vmail" to your system. Here, vmail user has UID and GID 5000. This user vill be owner of directory structure for all LDAP mail users.
在系统中添加用户和组"vmail",vmail用户的UID和GID为5000。该用户是所有LDAP邮件用户的目录结构的拥有者
Edit main.cf, so it accepts mail for your domain (x-si.org in this case). Here's relevant part of main.cf that deals with ldap:
编辑main.cf,接收域中的邮件,下面是main.cf中与ldap相关的部分:
#---- start here ----
transport_maps = hash:/etc/postfix/transport
local_transport = virtual
virtual_maps = ldap:ldapalias
ldapalias_server_host = ldap.x-si.org
ldapalias_server_port = 389
ldapalias_search_base = dc=x-si,dc=org
ldapalias_timeout = 30
ldapalias_query_filter = (mail=%s)
ldapalias_domain = hash:/etc/postfix/ldapvirtualdomains
ldapalias_result_attribute = maildrop1
virtual_mailbox_base = /virtmail
virtual_mailbox_maps = ldap:ldapvirtual
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
ldapvirtual_server_host = ldap.x-si.org
ldapvirtual_server_port = 389
ldapvirtual_search_base = dc=x-si,dc=org
ldapvirtual_timeout = 30
ldapvirtual_query_filter = (mail=%s)
ldapvirtual_domain = hash:/etc/postfix/ldapvirtualdomains
ldapvirtual_result_attribute = homedir
#---- end here ----
/etc/postfix/transport contains:
#---- start here ----
x-si.org virtual
backend1.x-si.org virtual
#---- end here ----
/etc/postfix/ldapvirtualdomains:
#---- start here ----
x-si.org virtual
backend1.x-si.org virtual
#---- end here ----
Note: Don't forget to run postmap on transport and ldapvirtualdomains.
注意,不要忘记在传送和ldapvirtualdomains运行postmap。
ldapavirtual parameter will search LDAP server for email addres (mail=%s), when found, it returns homedir (result_attribute). This way postfix knows where to deploy email message.
Ldapavirtual参数将搜索LDAP服务器查找邮件地址(mail=%s),找到后,返回homedir (result_attribute),这样postfix就会知道向哪里发送信息。
If you look closely at homedir value in ldif file, you'll notice there's no leading slash (i.e. /) in the path. Also, the path ends with a slash.
如果仔细考察ldif文件的homedir值,就会发现路径前没有/斜线,路径结尾有/。
Leading slash is ommited because postfix's virtual_mailbox_base is prepended to path returned from LDAP query. Tailing slash means, postfix will store email messagess in Maildir format (every message in separate file). While this may lead to inode consumption, it's far easier to administrate and faster to load mail for clients.
路径前的斜线省略是因为postfix的virtual_mailbox_base是从LDAP查询返回的伪装路径,结尾的斜线表示postfix将用Maildir格式保存邮件(每个邮件是独立文件)。这种方式虽然消耗资源,但是易于管理,客户端可以快速加载邮件。
To do ETRN with forwarders, I use small perl script. This should be run right after machine comes up and postfix starts. You can get it here. Be sure you user right FQDN's .
在转发器运行ETRN,我用了一个小perl脚本,在机器启动和postfix启动时运行,可以从这里下载。
2.3 Backend2 setup(后端2设置)
Use same configuration as for backend1. In main.cf only change:
与后端1设置相同,更改main.cf中:
#---- start here ----
ldapalias_result_attribute = maildrop2
#---- end here ----
/etc/postfix/transport should also change to:
#---- start here ----
x-si.org virtual
backend2.x-si.org virtual
#---- end here ----
/etc/postfix/ldapvirtualdomains:
#---- start here ----
x-si.org virtual
backend2.x-si.org virtual
#---- end here ----
Note: Don't forget to run postmap on both files.
注意:不要忘记运行postmap。
3. Conclusion(结论)
Ok, this is it. Restart (or reload) postfix and telnet to forwarders address port 25. Send mail to user@x-si.org and watch the maillogs on both backends.
好了,重新启动postfix,telnet到转发器端口25,发送邮件给user@x-si.org,观察所有后端服务器的邮件日志文件。
Mail should arrive and all needed directories should be created.
邮件到达,同时创建所有需要的目录。
You can setup M backends this way. Because of running freevrrpd daemon, you can retrieve or add as many boxes as you like, service will still be up & running.
按照这个方法可以创建M个后端,运行freevrrpd daemon,可以找回或增加任意多的系统。
The only problem here is mail header. It shows, mail was delivered to backend1 or backend2, not to x-si.org. This can be altered with canonical_maps in postfix configuration, but to tell the truth, I didn't tried this yet.
唯一的问题是邮件头,将被显示是发送到后端1或后端2,而不是x-si.org。这个可以用postfix设置中的canonical_maps进行调整,但是我还没有试过。
In case one backend server crashes, freevrrpd daemon will take care of IP's and Fast ETRN Service will take care of queued mail delivery.
如果一个后端服务器崩溃,freevrrpd daemon将控制IP,而Fast ETRN Service控制邮件队列。
3.1 Mail hosting(邮件服务托管)
Using setup as described in 2.2 section, ISP can easy setup mail hosting.
利用2.2的设置,ISP可以建立邮件服务托管。
For specific domain, let say lamerz.si, one should add this domain into '/usr/local/etc/postfix/ldapvirtualdomains' and add another 'mail =' attribute for that domain (ie. lart@lamerz.si) on forwarders only. We don't need to change anything on backends for mail hosting.
对于某个域,比如lamerz.si,在'/usr/local/etc/postfix/ldapvirtualdomains'加入该域,在转发器增加一个'mail ='(比如lart@lamerz.si),不需要在后端进行任何修改。
Again, all mail destined to lart@lamerz.si will go to all attributes of 'result_attribute =' filed.
所有发往lart@lamerz.si的邮件将送到'result_attribute ='指定的值。
peijun.jiang 回复于:2003-05-15 09:22:40 |
这是让一位同事帮助翻译的,大家可以参考一下,希望对大家有帮助! |
unix菜鸟 回复于:2003-05-15 21:37:59 |
不错,可惜我没有那么多Server试。 |
startdd 回复于:2003-05-15 21:57:17 |
感觉很难配置!而且调试时间肯定很长,而且会遇到这样那样的问题!希望给份“中文”的安装指南! |
hzqbbc 回复于:2003-05-15 23:17:08 |
[quote:6c2f5c49e8="peijun.jiang"]ckend2_machine]
#---- end here ---- NOTE: run postmap on transport file. 注意:传送文件时运行postmap。 This way, forwarder will deliver all mail for backend1 to it's IP, without doing a DNS q..........[/quote:6c2f5c49e8] it's old 很早就看过这个了。不过做法是不错的。可惜翻译的就。。努力努力~ 我一直还是用mx的方法做backup server的。 |
peijun.jiang 回复于:2003-05-16 09:15:39 |
[quote:52ade92811="hzqbbc"]
it's old 很早就看过这个了。不过做法是不错的。可惜翻译的就。。努力努力~ 我一直还是用mx的方法做backup server的。[/quote:52ade92811] hzqbbc老大对postfix是最熟悉的,有时间你还是给我们教教postfix系统 和邮件服务器的HA系统! |
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/
领测软件测试网最新更新
关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073