Postfix--邮件传输代理

Dovecot—pop3imap服务器,并提供SASL认证

Mysql-用于存储虚拟域和虚拟用户

AmaVis-用来扫描邮件中的垃圾邮件、病毒及附件

Squirremail-实现Webmail,用户可以修改密码

 

为了实现虚拟域和虚拟用户,我们使用了MySQL数据库来存储这些信息。POP3IMAP手心的支持,我们使用Dovecot来实现,使用AMaVisdSpamAssassinClamAVailable,我们可以实现垃圾邮件和病毒过滤,在默认情况下,磁盘限额功能没有编译进Postfix,如果需要这个功能的话需要打补丁,最后将介绍使用SquirrelMail。通过它用户登陆到Web页面使用信箱。

虚拟域和虚拟用户的好处,真实系统用户的真实域大得多。在系统中创建真实域和真实用户,操作复杂、管理麻烦、更重要的是还涉及安全问题。

 

实验环境,服务器地址192.168.1.10,主机名ubox.mytest.com

9.1  安装所有相关软件

 

9.1.1  安装服务器软件

$ sudo apt-get install postfix-mysql mysql-server dovecot-pop3d dovecot-imapd amav isd-new libclass-dbi-mysql-perl

 

New password for the MySQL "root" user: <-- 输入密码

Repeat password for the MySQL "root" user: <-- 再次输入密码

Create directories for web-based administration? <-- 选择No

General type of mail configuration: <-- 选择Internet Site

System mail name: <-- 输入DNS全名(ubox.mytest.com

SSL certificate required <-- 选择Ok

Web server to reconfigure automatically: <-- 选择apache2

libclass-dbi-mysql-perl提供了Perl DBI模块,AmaVis就可以访问数据库了。

AmaVis只是一个“接口”,要实现病毒和垃圾邮件过滤,需要安装的软件如下

反病毒软件(比如clamav

反垃圾邮件软件(比如SpamAssassin

接口软件(比如AmaVis

前两种成为“内容过滤软件”。接口软件的作用是在邮件服务器和内容过滤软件之间加起桥梁。

9.1.2          安装内容过滤软件

$ sudo apt-get install SpamAssassin clamav-daemon razor pyzor cpio arj zoo nomarch lzop cabextract pax lha unrar

SpamAssassin是基于文本分析的垃圾邮件管理程序,而razorpyzor则是CS架构的垃圾邮件过滤程序。这种CS架构的过滤程序,其服务器成为“编录服务器”,维护着一个垃圾邮件信息库(类似于病毒库),并且会不断的更新;当客户端收到一个垃圾邮件时,会自动将该邮件的20SHA编码发给最近的“编录服务器”。总多的“编录服务器”会相互同步,以确保最新的编录数据库。当客户端收到一封邮件时,会自动去“编录服务器”核对其SHA编码,以检查其是否是垃圾邮件。

9.1.3          安装其他软件

安装squirrelmail以便提供Webmail界面,squirrelmail-locales提供了多语言界面翻译,php5-imap软件包则为访问IMAP提供了可能

$ sudo apt-get install squirrelmail squirrelmail-locales php5-imap

下面的软件包以便创建SSL证书

$ sudo apt-get install openssl

Phpmyadmin提供管理数据库,telnet可以连接到并测试服务器,mutt可以让我们在控制台中读取邮件,mailx带了一个mail命令可以让我们在命令行上发邮件,

$ sudo apt-get install phpmyadmin  telnet mutt mailx

9.2  Postfix准备数据库

 

9.2.1  创建数据库maildb

$ mysql -uroot -p

创建数据库

mysql> create database maildb;

创建用户并赋予相应权限

mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON maildb.* TO 'mailadmin'@'localhost' IDENTIFIED BY 'mailadminPassword';

mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON maildb.* TO 'mailadmin'@'localhost. localdomain' IDENTIFIED BY 'mailadminPassword';

mysql> FLUSH PRIVILEGES;

9.2.2  为数据库maildb创建数据表

mysql> use maildb;

1. 创建虚拟域表virtual_domains

virtual_domains表用来存放虚拟域

mysql> CREATE TABLE `virtual_domains` (

id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

name VARCHAR(50) NOT NULL

) TYPE=MyISAM;

插入测试数据

mysql> INSERT INTO virtual_domains (name)

VALUES  ('mytest.com'),

         ('dongyouji.cn');

2. 创建虚拟用户表virtual_users

virtual_users表用来存放邮件用户信息(包括用户名,密码[MD5加密],磁盘限额大小[单位为字节]

表带有DELETE CASCADE(级联删除)

mysql> CREATE TABLE `virtual_users` (

id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,

domain_id INT(11) NOT NULL,

user VARCHAR(40) NOT NULL,

password VARCHAR(32) NOT NULL,

quota INT(10) DEFAULT '102400',

CONSTRAINT UNIQUE_EMAIL UNIQUE (domain_id,user),

FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE

) TYPE=MyISAM;

插入测试数据

mysql> INSERT INTO virtual_users (domain_id, user, password, quota)

VALUES  (1, 'bajie', MD5('bajiePassword'), 10240),

         (1, 'wukong', MD5('wukongPassword'), 102400),

         (2, 'tangseng', MD5('tangsengPassword'), 1048576),

         (1, 'spams', MD5('spamsPassword'), 1024);

3.创建别名表virtual_aliases

virtual_aliases用来实现邮件转发。该表存储信箱的“源”地址和“目的”地址

mysql> CREATE TABLE `virtual_aliases` (

id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,

domain_id INT(11) NOT NULL,

source VARCHAR(40) NOT NULL,

destination VARCHAR(80) NOT NULL,

FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE

) TYPE=MyISAM;

插入测试数据

 

mysql> INSERT INTO virtual_aliases (domain_id, source, destination)

VALUES (2, 'tangseng', 'tang.sanzang@gmail.com'),

          (1, 'bajie', 'bajie@mytest.com'),

          (1, 'bajie', 'zhu_bajie@yahoo.com'),

          (1, '', 'spams@mytest.com');

最后的@mytest.com其实就是一个垃圾信箱,匹配本域所有。这种方法可以用于垃圾邮件分析等(比如将发件人的E-mail地址或IP地址写入黑名单,然后将邮件丢弃)

9.2.3          为数据库maildb创建视图

数据库表设计的很巧妙,但是给我们带来的是不直观。因为在浏览virtual_users时一眼看不出哪个用户属于哪个域的,而且,每次要用到username@domain.com格式的邮件时,都需要使用Join来进行“联合查询”。如下

mysql> SELECT CONCAT(virtual_users.user, '@', virtual_domains.name) AS email, vir tual_users.password

FROM virtual_users

LEFT JOIN virtual_domains ON virtual_users.domain_id=virtual_domains.id;

 

+-----------------------+----------------------------------+

| email                    | password                              |

+-----------------------+----------------------------------+

| bajie@mytest.com       | 00e28675230f4c9b16666098941e5d6d |

| wukong@mytest.com      | 407dbf9a4ca5a9906332ff0ea9c330fb |

| tangseng@dongyouji.cn | 3dbc34bca13af30ed7aa2769ee468b40 |

| spams@mytest.com       | 946bfb68686ed81aa5b0c58bb2633175 |

+-----------------------+----------------------------------+

1. 创建用户视图view_users

创建视图,该视图有两个字段即emailpassword

mysql> CREATE VIEW view_users AS

SELECT CONCAT(u.user, '@', virtual_domains.name) AS email, u.password

FROM virtual_users u

LEFT JOIN virtual_domains ON u.domain_id=virtual_domains.id;

下面直接Select语句就可以

mysql> SELECT * FROM view_users WHERE email LIKE 'bajie%';

+------------------+----------------------------------+

| email              | password                              |

+------------------+----------------------------------+

| bajie@mytest.com | 00e28675230f4c9b16666098941e5d6d |

+------------------+----------------------------------+

2. 创建别名视图view_virtual_aliases

为了选取别名的方便,也创建一个view_virtual_aliases视图

mysql> CREATE VIEW view_aliases AS

SELECT CONCAT(virtual_aliases.source, '@', virtual_domains.name) AS email, destin ation

FROM virtual_aliases

LEFT JOIN virtual_domains ON virtual_aliases.domain_id=virtual_domains.id;

 

mysql>  SELECT * FROM view_aliases;

+---------------------+------------------------+

| email                  | destination              |

+---------------------+------------------------+

| tangseng@mytest.com | tang.sanzang@gmail.com |

| bajie@mytest.com     | bajie@mytest.com        |

| bajie@mytest.com     | zhu_bajie@yahoo.com    |

| @mytest.com           | spams@mytest.com        |

+---------------------+------------------------+

9.3  配置Postfix

 

9.3.1  PostfixMySQL的关联配置

domains.cfmailbox-maps.cfalias-maps.cfemail2email.cfPostfixMySQL的配置映射关系的4个文件。我们将这几个文件放在/etc/postfix/mysql/目录下。

$ sudo mkdir /etc/postfix/mysql/

1.虚拟域virtual_mailbox_domains配置

$ sudo nano /etc/postfix/mysql/domains.cf

内容如下

user = mailadmin

password = mailadminPassword

hosts = 127.0.0.1

dbname = maildb

query = SELECT 1 FROM virtual_domains WHERE name='%s'

这样Postfix需要查看是否存在mytest.com域时,上面配置中的'%s'会被替换成‘mytest.com’,如果找到返回1,其实只要能查询到正确的结果,返回上面值无所谓

将其写入Postfix配置文件(postconf –e的好处是不需要重新启动服务器,并将配置信息直接写入/etc/postfix/main.cf配置文件)

$ sudo postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mysql/domains.cf

测试

$ postmap -q mytest.com mysql:/etc/postfix/mysql/domains.cf

1

 

3. 信箱映射virtual_mailbox_maps配置

Postfix配置中的virtual_mailbox_domains也就是关于虚拟域配置,下面来配置virtual_mailbox_maps也就是虚拟用户的配置。

创建文件,Postfix可以从数据库中找到邮件地址别名(转发)的资料

$ sudo nano /etc/postfix/mysql/mailbox-maps.cf

 

user = mailadmin

password = mailadminPassword

hosts = 127.0.0.1

dbname = maildb

query = SELECT 1 FROM view_users WHERE email='%s'

测试

$ postmap -q bajie@mytest.com mysql:/etc/postfix/mysql/mailbox-maps.cf

1

写入Postfix配置文件

$ sudo postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mysql/mailbox- maps.cf

配置virtual_mailbox_maps,他本来应该是一种映射关系,这种映射关系表现为左边(LHS)是email地址,右边(RHS)是信箱在磁盘上所存放的位置,但是在数据库virual_users表及view_users视图中,只有LHSEmail地址,没有RHS的信箱存储路径。因为如果使用Postfix内置的“虚拟分发代理”(Virtual Delivery Agent)来存储收到的邮件,那么这种映射关系必须在数据库中得到体现,以便Postfix能够查询到。不过这里使用的是Dovecot的“本地分发代理”(Local Delivery Agent,简称LDA)来进行邮件分发存储,所以Postfix不必知道邮箱保存在什么位置,只需要知道某个Email地址是否属于某个用户即可。不需要配置RHSmailbox地址。

尽管如此,我们还是需要创建目录,用来存放mailbox。建议将其创建在/var/mail/virtual中。要自爱硬盘上创建目录就设计到用户权限问题。处于安全考虑,创建一个用户和组,将mailbox赋予这个用户,下面创建的用户id和组id可以不同,只要是没有使用的。

$ sudo groupadd -g 5000 vmail

$ sudo useradd -g vmail -u 5000 vmail -d /var/mail/virtual -m

上面得命令创建了用户和组的同时,也创建了/var/mail/virtual目录,并设定了权限。用户的mailbox将存储在/var/mail/virtual/$DOMAIN/$USER目录下。在邮件到达的时候,postfix会自动创建目录。

将上诉UIDGID信息写入Postfix的配置文件,以便Postfix有权限操作这个目录。

$ sudo postconf -e virtual_uid_maps=static:5000

$ sudo postconf -e virtual_gid_maps=static:5000

4. 别名映射virtual_alias_maps配置(一

利用前面创建的view_aliases别名视图,让Postfix将信件可以从一个Email地址转发到另一个Email地址

$ sudo nano /etc/postfix/mysql/alias-maps.cf

 

user = mailadmin

password = mailadminPassword

hosts = 127.0.0.1

dbname = maildb

query = SELECT destination FROM view_aliases WHERE email='%s'

测试

$ postmap -q bajie@mytest.com mysql:/etc/postfix/mysql/alias-maps.cf

bajie@mytest.com,zhu_bajie@yahoo.com

写入配置文件

$ sudo postconf -e virtual_alias_maps=mysql:/etc/postfix/mysql/alias-maps.cf

5. 别名映射virtual_alias_maps配置(二:实验

virtual_alias_maps的优先级高于virtual_mailbox_maps

Postfix在接受邮件时,先去搜索virtual_alias_maps,看看是否需要转发,需要转发就转发,不需要转发才会去搜索virtual_mailbox_maps

在该实验中,我们将设置catchall垃圾邮箱,把所有发给@test.com未知账号的email转发给caoyaodian@gmail.com(请替换成自己真是的邮件地址)

$ mysql maildb -u root -p

为减少视觉障碍,将virtual_aliases清空

mysql> DELETE FROM `virtual_aliases`;

重新添加新数据

mysql> INSERT INTO virtual_aliases (domain_id, source, destination)

VALUES (1, '', 'caoyaodian@gmail.com');

mysql> exit

       只添加了最后的垃圾邮件

 

下面的测试,向 bajie@mytest.com 发邮件

$ mail bajie@mytest.com

Subject: hi bajie, this is wukong       <-- 输入邮件主题

ni ge bi ma wen!                            <-- 输入正文

.                                       <-- 输入“.”结束正文

Cc:                                     <-- “抄送”地址,可以留空,直接回车

发送后查看日志

$ sudo tail /var/log/mail.log

 

Dec  7 23:16:36 mail postfix/smtp[8990]: 5304F42BA5: to=<caoyaodian@gmail.com>, orig_to=<bajie@mytest.com>, relay=gmail-smtp-in.l.google.com[209.85.143.114]:25, delay=32, delays=0.28/0.09/0.47/31, dsn=2.0.0, status=sent (250 2.0.0 OK 1228709789 i6si27692tid.5)

如果转发到163126或者yeah.net等信箱,可能就直接被当做垃圾邮件挡掉(status=bounced

Dec  7 23:22:45 mail postfix/smtp[9005]: 9656542BA7: to=<hiweed@126.com>, orig_to= <bajie@mytest.com>, relay=126.mxmail.netease.com[220.181.15.135]:25, delay=0.42, delays=0.06/0.01/0.27/0.08, dsn=5.0.0, status=bounced (host 126.mxmail.netease.co m[220.181.15.135] said: 550 MI:SPF mx5,I8mowLC7KBAUoTxJxeflWQ--.47417S2 1228710164 http://mail.163.com/help/help_spam_16.htm?ip=1020372198&hostid=mx5&time=1228710164 (in reply to MAIL FROM command))

但是至少说明被转发了!!

查看/var/mail/virtual/目录下根本没bajie的邮件

$ ls /var/mail/virtual/

清空关于转发的数据库设置

$ sudo postconf -e virtual_alias_maps=

再次测试

$ mail bajie@mytest.com

Subject: hi bajie, test 2               <-- 输入邮件主题

Bajie, ni ge bi ma wen!                 <-- 输入正文

Test 2, Hehe.

.                                       <-- 输入“.”结束正文

Cc:                                     <-- “抄送”地址,可以留空,直接回车

查看日志

Dec  8 00:19:31 mail postfix/qmgr[8873]: 0AE9542BA7: from=<root@ubox.mytest. com>, size=302, nrcpt=1 (queue active)

Dec  8 00:19:32 mail postfix/pipe[9067]: 0AE9542BA7: to=<bajie@mytest.com>, relay= dovecot, delay=1.6, delays=0.67/0.65/0/0.31, dsn=2.0.0, status=sent (delivered via dovecot service)

用过mutt来阅读邮件

$ sudo mutt -f /var/mail/virtual/mytest.com/bajie/Maildir

 

1. 别名映射virtual_alias_maps配置(三:“自己给自己”

由于在转寄表中有一行关于垃圾邮件的记录,所以我们必须将所有用户的email地址也填在转寄表中才可以,用户才能收到邮件。

文章整理来自于《Ubuntu Server最佳方案》书籍

由于字数限制,笔记可能无法全部上传,关于具体细节的信息,请下载笔记