用OpenBSD搭建一个邮件服务器

OpenBSD FAQ中文版、PF指南中文版、OpenBSD用户手册...
回复
头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

用OpenBSD搭建一个邮件服务器

帖子 leo » 2010-04-17 11:33

原文链接:http://www.kernel-panic.it/openbsd/mail/index.html
在此特别感谢原文作者!
译文仅供在JR社区学习讨论之用,谢绝修改、转发,多谢!
leo@jr

===================================================

在前面的文档里, 我们用CARP和PFSYNC协议构建了冗余的防火墙; 这只是我们的第一步,我们将逐步通过后续文档组建一个完全基于OpenBSD的小型私有网络系统。
目前我们已经提升了网络的防卫标准, 现在是需要考虑我们想提供些什么服务了的时候了。提供一个稳定和安全的email服务可能是多数系统管理员会最先考虑到的事情; 因此, 在后续的章节, 我们将建立一个基于开源软件以及注重安全的全功能邮件服务器。 下面是我们需要用到的软件:

OpenBSD
[INDENT]"默认安全" 的操作系统, "在很长的时间内默认安装情况下仅发现两个远程安全漏洞!";
[/INDENT]Postfix
[INDENT]一个MTA "由IBM最早研究的作为广泛应用的Sendmail程序的一个替代品" ,它的目标是 "快速、易于管理和安全";
[/INDENT]MySQL
[INDENT]"世界上应用最广泛的开源数据库";
[/INDENT]Courier-IMAP
[INDENT]一个支持 MySQL 和 maildirs 的"快速, 可扩展, 企业级IMAP服务器" ;
[/INDENT]Cyrus SASL
[INDENT]SASL协议的Cyrus实施方案;
[/INDENT]Amavisd-new
[INDENT]一个 "在mailer (MTA) 和 content checkers(antivirus and antispam)之间高性能的接口", 用Perl编写的,并为Postfix做了优化;
[/INDENT]SpamAssassin
[INDENT]一个基于Perl的 "垃圾邮件鉴别过滤程序", 使用了 "包含header和文字分析、贝叶斯过滤、DNS黑名单、合作的过滤数据库等大量机制";
[/INDENT]ClamAV
[INDENT]快速、易用的开源病毒扫描程序。
[/INDENT]这里假设你对OpenBSD很熟悉, 因为我们不涉及一些系统管理的话题,例如基本配置或如何安装packages/ports。

头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

回复: OpenBSD as a mail server

帖子 leo » 2011-04-25 20:15

2. 初步的安装步骤
在深入这些邮件处理软件的安装和配置以前, 我们先看一下要安装这些软件的操作系统。
和以往一样, 我之所以选择 OpenBSD 是倾情它已被证明的安全性、稳定性、易用性。 不用说, 对一个日常需要处理大量邮件通讯并必须面对spamer和恶意用户的系统来说,所有上述这些特性都是很重要的。

我们这里不涉及安装步骤, 它已经在 OpenBSD安装指南 里说的够详细了。这里只说一些注意事项:
  • 给硬盘分区时, 切记我们要用 virtual domains配置Postfix , 因而, 它需要将所有用户的邮件文件夹保存在一个单独的目录里 (/var/vmail)。因此, 我们推荐给这个文件系统分配一个专用的(大的)slice分区, 这是为了防止所有的关键文件系统被邮件填满, 这些系统应该是没有配额限制的。而且, 如果你选择将 MySQL 安装在这个邮件服务器自身上, 通常推荐你分配一个尽量靠前的slice给 /var/mysql, 这可使数据库引擎访问磁盘时速度快一些;
  • 我们需要安装的是在 OpenBSD FAQ里 标记为 "必需的" 那些系统组件, 也就是 bsd (内核), baseXX.tgz (基本系统), etcXX.tgz ( /etc 里的配置文件) 以及compXX.tgz (C编译器), 因为我们还要安装一些因为许可证的原因无法提供预编译包的 ports注意: 因为在一个公众可以访问的服务器上保留一个编译器绝对是一个安全隐患, 建议您完成相关软件安装后就立即删除这个编译器,或者在其它的机器上完成编译。
第一次重新启动系统后, 我们可以禁用一些由 inetd(8) 管理的默认网络服务:

代码: 全选

$ grep -v ^# /etc/inetd.conf
ident           stream  tcp     nowait  _identd /usr/libexec/identd     identd -el
ident           stream  tcp6    nowait  _identd /usr/libexec/identd     identd -el
127.0.0.1:comsat dgram  udp     wait    root    /usr/libexec/comsat     comsat
[::1]:comsat    dgram   udp6    wait    root    /usr/libexec/comsat     comsat
daytime         stream  tcp     nowait  root    internal
daytime         stream  tcp6    nowait  root    internal
time            stream  tcp     nowait  root    internal
time            stream  tcp6    nowait  root    internal
$
您只需在 /etc/inetd.conf 里注释掉这些项,然后重新启动 inetd(8):

代码: 全选

# pkill -HUP inetd
尽管 OpenBSD也考虑了在这些服务在开启时保证系统的安全以及邮件服务器应该位于防火墙的后面; 不过, 从安全的角度考虑,我倾向于最好禁用所有的这些服务 (包括 comsat(8), 因为系统上没有采用交互方式接收邮件的用户)。
要修改服务器的网络配置, 请参考 相应的文章 或者 OpenBSD FAQ的相关章节

头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

回复: OpenBSD as a mail server

帖子 leo » 2011-04-25 20:30

3. Postfix
Postfix 是一个 Wietse Venema 开发的MTA (邮件传输代理) ,做为广为应用的 Sendmail 程序的一个替代品; 它的目标是快速, 易于管理和安全。外表有明显的Sendmail风格, 但是程序内部则完全不同。Postfix还提供了极出色的 文档 以及大量的 howtos
我们的邮件服务器的要求很简单: 它最终的目的是要成为一个 canonical domains ,而且它仅中继来自内部网络(尽管我们也会考虑中继那些来自不可信网络的邮件,这里的“不可信”的网络是指 SMTP authentication)的邮件。 Canonical domains 包括主机名 (本例中, "mail.kernel-panic.it") 和运行Postfix主机的IP地址 (172.16.240.150) , 和主机名的父域 ("kernel-panic.it")。

Canonical domains方案通常是采用Postfix local domain address class , 很遗憾, 对我来说其中有一个很大的缺陷: 它需要每个e-mail帐号对应一个系统内Unix帐号 。 我希望正相反:
  1. 保持Unix和e-mail帐号各自独立且
  2. 所有的mailboxes有序地保存在一个目录里。
因此, 我们将使用Postfix Virtual Domain Hosting, 它可以在同一台服务器上托管多个Internet域名, 但我们仍旧可以实现上面所说的功能。

3.1 配置
在本章节里, 我们将将Postfix配置为独立运行(standalone), 也就是没有后端的数据库。然后在 下一章 里, 等一切就绪, 我们再把Postfix挂到一个MySQL数据库上; 那时我们就可以集中存储访问所需的 Postfix 和 Courier-IMAP 的配置信息。



这是一份需要安装的packages清单:
  • mysql-client-x.x.x.tgz
  • pcre-x.x.tgz
  • postfix-x.x.x-mysql.tgz
注意: 如果你计划使用 SMTP authentication, 你就需要从ports编译Postfix, 因为没有同时包含MySQL和SASL支持的预编译package:

代码: 全选

# cd /usr/ports/mail/postfix/snapshot
# env FLAVOR="mysql sasl2" make install
安装将创建一个 /etc/postfix 目录, 包含了所有的配置文件。Postfix的配置文件在 /etc/postfix/main.cf ,有多达数百个配置参数, 不过,别担心: 对绝大多数参数来说, 默认配置就是最好的选择 (参 postconf(5) ,里面有全部的配置参数清单、及其描述和默认值),而且我们仅修改了其中很少的一部分:
文件 /etc/postfix/main.cf

代码: 全选

# Directory containing all the post* commands
command_directory = /usr/local/sbin
# Directory containing all the Postfix daemon programs
daemon_directory = /usr/local/libexec/postfix
# Location of the Postfix queue and root directory of chrooted Postfix daemons
queue_directory = /var/spool/postfix
 
# Full pathnames of various Postfix commands
sendmail_path = /usr/local/sbin/sendmail
newaliases_path = /usr/local/sbin/newaliases
mailq_path = /usr/local/sbin/mailq
 
# Directories containing documentation
html_directory = /usr/local/share/doc/postfix/html
manpage_directory = /usr/local/man
readme_directory = /usr/local/share/doc/postfix/readme
 
# The owner of the Postfix queue and of most Postfix daemon processes
mail_owner = _postfix
# The group for mail submission and queue management commands
setgid_group = _postdrop
 
# The myhostname parameter specifies the internet hostname of this mail system. It is
# used as default for many other configuration parameters (default = system's FQDN)
myhostname = mail.kernel-panic.it
 
# The internet domain name of this mail system. Used as default for many other
# configuration parameters (default = $myhostname minus the first component)
mydomain = kernel-panic.it
 
# The domain name that locally-posted mail appears to come from, and that locally posted
# mail is delivered to. As you can see, a parameter value may refer to other parameters
myorigin = $myhostname
 
# Network interface addresses that this mail system receives mail on
inet_interfaces = all
 
# Network interface addresses that this mail system receives mail on by way of a
# proxy or NAT unit
proxy_interfaces = router.kernel-panic.it
 
# List of domains that this machine considers itself the final destination for.
# Virtual domains must not be specified here
mydestination = $myhostname, localhost.$mydomain, localhost
 
# List of "trusted" SMTP clients allowed to relay mail through Postfix.
mynetworks = 127.0.0.0/8, 172.16.0.0/24, 172.16.240.0/24
 
# What destination (sub)domains this system will relay mail to
relay_domains = $mydestination
 
# The default host to send mail to when no entry is matched in the optional
# transport(5) table. Square brackets turn off MX lookups
relayhost = [smtp.isp.com]
 
# List of alias databases used by the local delivery agent
alias_maps = hash:/etc/postfix/aliases
 
# Alias database(s) built with "newaliases" or "sendmail -bi". This is a separate
# configuration parameter, because alias_maps may specify tables that are not
# necessarily all under control by Postfix
alias_database = hash:/etc/postfix/aliases
 
# SMTP greeting banner
smtpd_banner = $myhostname ESMTP $mail_name
 
# Postfix is final destination for the specified list of "virtual" domains
virtual_mailbox_domains = kernel-panic.it
 
# Virtual mailboxes base directory
virtual_mailbox_base = /var/vmail
 
# Optional lookup tables with all valid addresses in the domains that match
# $virtual_mailbox_domains.
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
 
# The minimum user ID value accepted by the virtual(8) delivery agent
virtual_minimum_uid = 2000
 
# User ID that the virtual(8) delivery agent uses while writing to the recipient's mailbox
virtual_uid_maps = static:2000
 
# Group ID that the virtual(8) delivery agent uses while writing to the recipient's mailbox
virtual_gid_maps = static:2000
 
# Optional lookup tables that alias specific mail addresses or domains to other local or
# remote address
virtual_alias_maps = hash:/etc/postfix/virtual
我们详细说一下上面的一些配置参数。
我们原先的一个想法就是避免为每个e-mail帐号创建一个对应的Unix帐号。我们可以通过配置Postfix,让其写入mailboxes时使用 uid 2000 和and gid 2000 (请参看上面的 virtual_uid_maps 和 virtual_gid_maps 配置参数)。现在我们只需创建一个 uid 2000 和and gid 2000 的用户:

代码: 全选

# useradd -d /var/vmail -g =uid -u 2000 -s /sbin/nologin \
> -c "Virtual Mailboxes Owner" -m vmail
我们原先的另一个想法是将所有的 mailboxes 整合进一个单独的目录; 这可以通过将 virtual_mailbox_base 参数设置为某个指定的目录来实现 (在我们配置里是 /var/vmail)。实际, this parameter is a prefix that the virtual(8) agent prepends to all pathname results from virtual_mailbox_maps table lookups.
在我们的配置里, 参数 virtual_mailbox_maps parameter 指向文件 /etc/postfix/vmailbox , 包含了虚拟域名(virtual_mailbox_domains参数)里所有有效的地址清单以及到相应的 mailboxes 或者 maildirs (每个mailbox是一个包含了所有emails的单个文件; 相反,每个 maildir 是一个具有特殊结构的目录, 里面的每份emails 都保存为单独的文件) 的路径:
文件 /etc/postfix/vmailbox

代码: 全选

info@kernel-panic.it          kernel-panic.it/info/
d.mazzocchio@kernel-panic.it  kernel-panic.it/d.mazzocchio/
[...]
请注意结尾处的“/”: 它们告诉 Postfix 路径名称指向一个 maildir ,而不是指向一个 mailbox 文件, 而且 maildirs 是我们唯一的选项, 因为 Courier-IMAP 不支持 mailbox 文件。
这里的 virtual_alias_maps 参数允许设置为特定的邮件地址别名或者其它的本地或者远程地址。它的值是到一个文件的路径名 (本例中 /etc/postfix/virtual) ,这个文件包含了别名的映射:
文件 /etc/postfix/virtual

代码: 全选

root@kernel-panic.it        root@localhost.kernel-panic.it
postmaster@kernel-panic.it    postmaster@localhost.kernel-panic.it
abuse@kernel-panic.it        postmaster@localhost.kernel-panic.it
[...]
最后, 这里的 /etc/postfix/aliases 文件包含了一些地址,Postfix将使用这些地址把邮件重定向到本地接收人(看 aliases(5))。因为很多帐号指向root的email地址, 你需要经常检查root的email,或者将所有的邮件转发到另一个帐号。例如:
文件/etc/postfix/aliases

代码: 全选

root: d.mazzocchio@kernel-panic.it
MAILER-DAEMON: postmaster
postmaster: root
bin: root
[...]
现在我们只需更新Postfix的lookup tables:

代码: 全选

# /usr/local/sbin/postmap /etc/postfix/vmailbox
# /usr/local/sbin/postmap /etc/postfix/virtual
# /usr/local/sbin/newaliases
替换掉 Sendmail:

代码: 全选

# /usr/local/sbin/postfix-enable
old /etc/mailer.conf saved as /etc/mailer.conf.pre-postfix
postfix /etc/mailer.conf enabled
 
NOTE: do not forget to add sendmail_flags="-bd" to
      /etc/rc.conf.local to startup postfix correctly.
 
NOTE: do not forget to add "-a /var/spool/postfix/dev/log" to
      syslogd_flags in /etc/rc.conf.local and restart syslogd.
 
NOTE: do not forget to remove the "sendmail clientmqueue runner"
      from root's crontab.
#
然后根据上述提示操作, 只要在root的crontab里,注释掉 "sendmail clientmqueue runner" 这句:

代码: 全选

# sendmail clientmqueue runner
#*/30 * * * * /usr/sbin/sendmail -L sm-msp-queue -Ac -q
然后在 /etc/rc.conf.local(8) 文件里增加一些变量。
文件 /etc/rc.conf.local

代码: 全选

# Specify a location where syslogd(8) should place an additional log socket
# for Postfix
syslogd_flags="-a /var/spool/postfix/dev/log"
 
# Make Postfix start in background and process queued messages every 30 min
sendmail_flags="-bd"
现在我们可以修改一些权限,然后重新启动相关进程 (或者图简单,直接reboot):

代码: 全选

# chgrp _postdrop /usr/local/sbin/postqueue /usr/local/sbin/postdrop
# chmod 2755 /usr/local/sbin/postqueue /usr/local/sbin/postdrop
# pkill syslogd
# syslogd -a /var/empty/dev/log -a /var/spool/postfix/dev/log
# pkill sendmail
# /usr/local/sbin/sendmail -bd
postfix/postfix-script: starting the Postfix mail system
然后,测试一下我们艰辛劳动的成果!

代码: 全选

# telnet mail.kernel-panic.it 25
Trying 172.16.240.150...
Connected to mail.kernel-panic.it.
Escape character is '^]'.
220 mail.kernel-panic.it ESMTP Postfix
HELO somedomain.org
250 mail.kernel-panic.it
mail from: someone@somedomain.org
250 Ok
rcpt to: d.mazzocchio@kernel-panic.it
250 Ok
data
354 End data with <CR><LF>.<CR><LF>
From: someone@somedomain.org
To: d.mazzocchio@kernel-panic.it
Subject: Test mail
 
It works!
.
250 Ok: queued as 548D7286
quit
221 Bye
Connection closed by foreign host.
# tail /var/log/maillog
Dec 16 15:26:35 mail postfix/smtpd[29212]: connect from ws1.lan.kernel-panic.it[172.16.0.15]
Dec 16 15:26:53 mail postfix/smtpd[29212]: 57076222: client=ws1.lan.kernel-panic.it[172.16.0.15]
Dec 16 15:27:02 mail postfix/cleanup[13428]: 57076222: message-id=<20070210142653.57076222@mail.kernel-panic.it>
Dec 16 15:27:02 mail postfix/qmgr[26776]: 57076222: from=<someone@somedomain.org>, size=392, nrcpt=1 (queue active)
Dec 16 15:27:02 mail postfix/virtual[14381]: 57076222: to=<d.mazzocchio@kernel-panic.it>, relay=virtual, delay=15,
delays=15/0.28/0/0.03, dsn=2.0.0, status=sent (delivered to maildir)
Dec 16 15:27:02 mail postfix/qmgr[26776]: 57076222: removed
Dec 16 15:27:06 mail postfix/smtpd[29212]: disconnect from ws1.lan.kernel-panic.it[172.16.0.15]
# cat /var/vmail/kernel-panic.it/d.mazzocchio/new/1118146014.V3I9448M811660.mail.kernel-panic.it
Return-Path: <someone@somedomain.org>
X-Original-To: d.mazzocchio@kernel-panic.it
Delivered-To: d.mazzocchio@kernel-panic.it
Received: from somedomain.org (ws1.lan.kernel-panic.it [172.16.0.15])
    by mail.kernel-panic.it (Postfix) with SMTP id 57076222
    for <d.mazzocchio@kernel-panic.it> Sat, 16 Dec 2007 15:26:47 +0100 (CET)
From: someone@somedomain.org
To: d.mazzocchio@kernel-panic.it
Subject: Test mail
Message-Id: <20070210142653.57076222@mail.kernel-panic.it>
Date: Sat, 16 Dec 2007 15:26:47 +0100 (CET)
 
It works!
#

头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

回复: OpenBSD as a mail server

帖子 leo » 2011-04-25 20:48

4. MySQL
如果Postfix工作正常, 我们就可以进行下一步安装 MySQL 的工作。MySQL是世界上最流行的开源数据库, 集性能、稳定性、易用性于一身。它可确保数据的快速访问以及让我们统一配置需访问的 PostfixCourier-IMAP


下面是我们需要安装的一些 packages :
  • p5-Net-Daemon-x.xx.tgz
  • p5-PlRPC-x.xxxx.tgz
  • p5-DBI-x.xx.tgz
  • p5-DBD-mysql-x.xxxx.tgz
  • mysql-server-x.x.xx.tgz
安装结束后, 你可以在 /usr/local/share/mysql 目录里看到不同环境配置文件; 选择一个适合自己的将其拷贝为 /etc/my.cnf 。例如:

代码: 全选

# cp /usr/local/share/mysql/my-small.cnf /etc/my.cnf

4.1 有关socket的抉择
因为chroot的原因有时候为Mysql的socket文件选择一个好的位置很难, chroot环境需要从 "简化的" 文件系统里访问它。不过 Postfix 则更甚: 它的处理步骤大多数被chroot在 /var/spool/postfix 目录, 还有一些则不是! 结果是默认情况下部分 Postfix 的处理要在 /var/run/mysql/ 目录里寻找这个 socket 文件, 而其余的会在 /var/spool/postfix/var/run/mysql/ 目录内查找!


不管怎么说, 还是很多的可能性:
  1. 如果数据库运行在远程服务器上, 我们无需为 socket 文件费心! 我们一会儿将看一下怎样配置可以让 PostfixCourier-IMAP 连接一个远程的数据库;
  2. 如果你想尽量保持默认配置, 你可以在数据库启动前创建一个符号链接到chroot环境里的 socket 文件:

    代码: 全选

    # mkdir -p /var/spool/postfix/var/run/mysql/
    # ln -f /var/run/mysql/mysql.sock /var/spool/postfix/var/run/mysql/mysql.sock
    记住,将上述命令添加到 /etc/rc.local(8) 脚本, 这样可以自动地在启动时创建这个链接。
  3. 你可以将这个 socket 放到 Postfix 的chroot环境里 (通过在/etc/my.cnf文件里将[mysqld]小段里的变量 socket 指向scoket所在的路径, 例如, /var/spool/postfix/mysql/mysql.sock), 而让 Postfix 有可能选择两个明显不同的路径: /var/spool/postfix/mysql/mysql.sock, 是非chroot处理时用的, 而 /mysql/mysql.sock 是为chroot处理时准备的;
  4. 最后, 你可以不再考虑这些 socket 文件而通过 loopback 网络接口连接。
那... 选择哪个方案呢? 经过略加思考, 我选择了后者, 它可能更简单一些。因此, 我去掉了 /etc/my.cnf 文件里 "skip networking" 前面的注释符,然后将下面这行添加到 [mysqld] 小段:
文件 /etc/my.cnf

代码: 全选

bind-address = 127.0.0.1
这样可以防止 MySQL 监听连接外部的网络接口。

4.2 配置
首要的是我们需要安装默认的数据库, 更换 MySQL 的root密码 (别用我例子里的!):

代码: 全选

# /usr/local/bin/mysql_install_db
[ ... ]
# mysqld_safe &
[ ... ]
# /usr/local/bin/mysql_secure_installation
[ ... ]
Enter current password for root (enter for none): <Enter>
OK, successfully used password, moving on...
[ ... ]
Set root password? [Y/n] Y
New password: root
Re-enter new password: root
Password updated successfully!
[ ... ]
Remove anonymous users? [Y/n] Y
 ... Success!
[ ... ]
Disallow root login remotely? [Y/n] Y
 ... Success!
[ ... ]
Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!
[ ... ]
Reload privilege tables now? [Y/n] Y
 ... Success!
[ ... ]
#
然后配置MySQL岁系统随启动:
文件 /etc/rc.local

代码: 全选

if [ -x /usr/local/bin/mysqld_safe ]; then
    echo -n ' MySQL'
    /usr/local/bin/mysqld_safe >/dev/null 2>&1 &
fi
下面, 我们将把 Postfix 挂到数据库上。尤其是我们要修改 /etc/postfix/main.cf 文件里的一些参数:
文件/etc/postfix/main.cf

代码: 全选

virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailboxes.cf
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
我们 一会儿 看一下那些文件的内容, 不过,首先我们先创建数据库。表不需要有任何特殊的结构, 因为我们会告诉 Postfix 哪些 queries 用来提取数据。所以, 这些可能的方案里实际上只有一个可用: 你完全可以按照自己的习惯和需要修改。
注意: Postfix 获取maildirs完整路径名的方法是通过合并 virtual_mailbox_base 和 virtual_mailbox_maps 这两个参数的变量值, 而 Courier-IMAP 获取它是通过合并变量 MYSQL_HOME_FIELD 和 MYSQL_MAILDIR_FIELD 参数的变量值。结果是, 我们将在 users table 里(home and maildir)分别创建两个 fields ,然后将这些变量指向它们,目的是为了让 Postfix 和 Courier-IMAP 各自处理。

代码: 全选

# mysql -u root -p
password: root
mysql> CREATE DATABASE mail;
Query OK, 1 row affected (0.01 sec)
 
mysql> use mail
Database changed
mysql> CREATE TABLE domains (
    ->        id       INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    ->        domain   VARCHAR(255) NOT NULL UNIQUE);
Query OK, 0 rows affected (0.02 sec)
 
mysql> CREATE TABLE users (
    ->        id       INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    ->        login    VARCHAR(255) NOT NULL UNIQUE,
    ->        name     VARCHAR(255) NOT NULL,
    ->        password CHAR(13) NOT NULL,
    ->        uid      SMALLINT NOT NULL DEFAULT 2000,
    ->        gid      SMALLINT NOT NULL DEFAULT 2000,
    ->        home     VARCHAR(255) NOT NULL DEFAULT '/var/vmail',
    ->        maildir  VARCHAR(255) NOT NULL,
    ->        quota    VARCHAR(10)  NOT NULL DEFAULT '10000000S');
Query OK, 0 rows affected (0.01 sec)
 
mysql> CREATE TABLE alias_maps (
    ->        id       INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    ->        account  VARCHAR(255) NOT NULL UNIQUE,
    ->        alias    VARCHAR(255) NOT NULL);
Query OK, 0 rows affected (0.00 sec)
 
mysql> GRANT SELECT ON mail.* to 'vmail'@'localhost' IDENTIFIED BY 'vmail';
Query OK, 0 rows affected (0.01 sec)
 
mysql> INSERT INTO domains (domain) VALUES ('kernel-panic.it');
Query OK, 1 row affected (0.01 sec)
 
mysql> INSERT INTO users (login, name, password, maildir)
    -> VALUES ('d.mazzocchio@kernel-panic.it', 'Daniele Mazzocchio', ENCRYPT('danix'),
    ->         'kernel-panic.it/d.mazzocchio/');
Query OK, 1 row affected (0.01 sec)
 
mysql> INSERT INTO alias_maps (account, alias)
    -> VALUES ('postmaster@kernel-panic.it', 'postmaster@localhost.kernel-panic.it');
Query OK, 1 row affected (0.00 sec)
 
mysql> INSERT INTO alias_maps (account, alias)
    -> VALUES ('root@kernel-panic.it', 'root@localhost.kernel-panic.it');
Query OK, 1 row affected (0.00 sec)
现在我们粗看一下这个新的 Postfix 配置文件, 它包含了为MySQL做的设定。
文件 /etc/postfix/mysql_virtual_domains.cf

代码: 全选

user = vmail
password = vmail
 
# solution 1:
# hosts = db_server_name
# Solution 2: skip this parameter
# Solution 3 (this file is required only by chrooted processes):
# hosts = unix:/mysql/mysql.sock
# Solution 4:
hosts = 127.0.0.1
 
dbname = mail
query = SELECT domain FROM domains WHERE domain='%s'
文件 /etc/postfix/mysql_virtual_alias_maps.cf

代码: 全选

user = vmail
password = vmail
 
# solution 1:
# hosts = db_server_name
# Solution 2: skip this parameter
# Solution 3 (this file is required only by chrooted processes):
# hosts = unix:/mysql/mysql.sock
# Solution 4:
hosts = 127.0.0.1
 
dbname = mail
query = SELECT alias FROM alias_maps WHERE account='%s'
文件 /etc/postfix/mysql_virtual_mailboxes.cf

代码: 全选

user = vmail
password = vmail
 
# solution 1:
# hosts = db_server_name
# Solution 2: skip this parameter
# Solution 3 (this file is required by both chrooted and non-chrooted processes):
# hosts = unix:/mysql/mysql.sock unix:/var/spool/postfix/mysql/mysql.sock
# Solution 4:
hosts = 127.0.0.1
 
dbname = mail
query = SELECT maildir FROM users WHERE login='%s'
That's all: now we can reload Postfix configuration:

代码: 全选

# postfix reload
postfix/postfix-script: refreshing the Postfix mail system
然后 测试 一下我们的工作; 所有都应该和以前运行得一样!

头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

回复: OpenBSD as a mail server

帖子 leo » 2011-04-25 20:58

5. Courier-IMAP
现在我们的服务器可以发送和接受email了,这对用户来讲可能很有用! 为此, 我们要安装 Courier-IMAP, 一个快速、可调整、使用 Maildirs 的企业级 IMAP 服务器。这是与 Courier mail server 一同出品的 IMAP 服务器, 但是可配置为独立于前者运行、并与其它邮件服务器(例如 Postfix)协同工作的 IMAP 服务器。, such as.

5.1 安装和配置

需要安装下列packages:
  • tcl-x.x.x.tgz
  • expect-x.x.x-no_tk.tgz
  • libltdl-x.x.x.tgz
  • courier-authlib-x.x.tgz
  • libiconv-x.x.tgz
  • gettext-x.x.x.tgz
  • libidn-x.x.tgz
  • gdbm-x.x.x.tgz
  • courier-imap-x.x.x.tgz
  • courier-authlib-mysql-x.x.x.tgz
一旦你安装好上述所有的packages, 你会发现有一个全新的包含 Courier IMAP 配置文件的目录 /etc/courier/ 。我们看一下每个配置文件。
配置文件 /etc/courier/authdaemonrc 设置几个认证(the resident authentication daemon)的可选参数 ; 幸运的是, 我们仅需编辑里面的 authmodulelist 参数, 它指定了一个认证模块清单; 将其设置为 authmysql 可以允许基于 MySQL 的认证:
文件/etc/courier/authdaemonrc

代码: 全选

[ ... ]
authmodulelist="authmysql"
[ ... ]
配置文件 /etc/courier/authmysqlrc 包含了 authmysql 数据库的连接参数; 下面是一个简单的配置文件:
文件 /etc/courier/authmysqlrc

代码: 全选

MYSQL_SERVER         127.0.0.1
MYSQL_USERNAME       vmail
MYSQL_PASSWORD       vmail
# If you connect through the socket:
#MYSQL_SOCKET         /path/to/mysql.sock
#MYSQL_PORT           0
MYSQL_PORT           3306
MYSQL_OPT            0
MYSQL_DATABASE       mail
MYSQL_USER_TABLE     users
MYSQL_CRYPT_PWFIELD  password
MYSQL_DEFAULT_DOMAIN kernel-panic.it
MYSQL_UID_FIELD      uid
MYSQL_GID_FIELD      gid
MYSQL_LOGIN_FIELD    login
MYSQL_HOME_FIELD     home
MYSQL_NAME_FIELD     name
MYSQL_MAILDIR_FIELD  maildir
MYSQL_QUOTA_FIELD    quota
# MYSQL_WHERE_CLAUSE    field=value AND field=value...
下面是为IMAPS协议创建 SSL 认证。想简单一些, 可以使用 Courier-IMAP 自带的脚本 mkimapdcert(8), 这个脚本在从 /etc/courier/imapd.cnf 配置文件中读取完所有的所需信息后可以创建认证。因此, 你需要先定制一下这个 /etc/courier/imapd.cnf 配置文件 (特别是要注意这里的 common name (CN) 参数, 它必须与用户要连接的服务器名称相匹配),然后运行 mkimapdcert(8):

代码: 全选

# /usr/local/sbin/mkimapdcert
[ ... ]
现在我们只需启动这个进程:

代码: 全选

# mkdir -p /var/run/courier{,-auth}/
# /usr/local/sbin/authdaemond start
# /usr/local/libexec/imapd.rc start
# /usr/local/libexec/imapd-ssl.rc start
配置 Courier-IMAP 随系统启动:
文件 /etc/rc.local

代码: 全选

echo -n ' Courier-IMAP'
/bin/mkdir -p /var/run/courier{,-auth}/
[ -x /usr/local/sbin/authdaemond ] && /usr/local/sbin/authdaemond start
[ -x /usr/local/libexec/imapd.rc ] && /usr/local/libexec/imapd.rc start
[ -x /usr/local/libexec/imapd-ssl.rc ] && /usr/local/libexec/imapd-ssl.rc start
...然后是测试我们的工作! 我建议使用一个简单的 Python 脚本, 只是为了省事:
文件 IMAP_test.py

代码: 全选

#!/usr/bin/env python
 
import imaplib
 
# Constants
IMAP_SRV = "mail.kernel-panic.it"
USER     = "d.mazzocchio@kernel-panic.it"
PASSWD   = "danix"
 
# Connect to server
imap_srv = imaplib.IMAP4(IMAP_SRV)
imap_srv.login(USER, PASSWD)
 
# Select the INBOX folder
imap_srv.select()
 
# Retrieve message list
msg_nums = imap_srv.search(None, 'ALL')[1]
 
# Print all messages
for num in msg_nums[0].split():
    msg = imap_srv.fetch(num, '(RFC822)')[1]
    print 'Message %s\n%s\n' % (num, msg[0][1])
 
# Disconnect from server
imap_srv.close()
imap_srv.logout()

5.2 添加 POP3 访问
最理想的是为email用户提供 IMAP 和 POP3 这两种可选择的远程访问方式; 不过, POP3 用户更倾向于更少的磁盘、带宽占用,而且这样可以节省服务器的资源。


为我们的服务器添加 POP3 支持很简单; 首先, 我们需要安装相应的 package:
  • courier-pop3-x.x.x.tgz
接下来, 需要运行 mkpop3dcert(8) 来是通过SSL(这也只需 mkimapdcert(8), SSL 参数从配置文件 /etc/courier/pop3d.cnf 来读取)为POP3生成 SSL 认证, 然后是启动这个程序:

代码: 全选

# /usr/local/sbin/mkpop3dcert
[ ... ]
# /usr/local/libexec/pop3d.rc start
# /usr/local/libexec/pop3d-ssl.rc start
将下面的几行加入 /etc/rc.local(8) 以便 POP3 服务器随系统启动:
文件 /etc/rc.local

代码: 全选

[ -x /usr/local/libexec/pop3d.rc ] && /usr/local/libexec/pop3d.rc start
[ -x /usr/local/libexec/pop3d-ssl.rc ] && /usr/local/libexec/pop3d-ssl.rc start
最后, 我们简单测试一下以确保没有问题:

代码: 全选

# telnet mail.kernel-panic.it 110
Trying 172.16.240.150...
Connected to mail.kernel-panic.it.
Escape character is '^]'.
+OK Hello there.
user d.mazzocchio@kernel-panic.it
+OK Password required.
pass danix
+OK logged in.
list
1 2531
[ ... ]
quit
+OK Bye-bye.
Connection closed by foreign host.
#

5.3 管理磁盘空间
为了防止文件系统 /var/vmail 过载,可以通过 Quotas 可以指定 maildirs 所占用的最大磁盘空间。最好的选择肯定是使用操作系统内置的 quota support, 不过我们不能用这个方案, 因为我们只有一个对 maildirs 进行写操作。因为, 我们必须依赖邮件软件对 maildirs 进行磁盘配额限制。
Courier-IMAP 内置 quota 功能, 但这只能解决一半的问题: 事实上, Postfix 也必须能拒绝接收超过磁盘配置限额的用户邮件。要实现这个目的, 我们要依赖 deliverquota(8) 程序, 它投递邮件时会考虑软件对 maildirs 的配额限制。
首先是用 maildirmake(1) 为每个 maildir 指定一个限额。例如:

代码: 全选

# /usr/local/bin/maildirmake -q 10000000S /var/vmail/kernel-panic.it/d.mazzocchio
# chown vmail /var/vmail/kernel-panic.it/d.mazzocchio/maildirsize
上述命令为 /var/vmail/kernel-panic.it/d.mazzocchio maildir 指定了一个 (大约) 10MB的限额。注意: maildirmake(1) 也允许你创建并初始化 maildirs 以便让用户访问它们; 否则, 一个用户的 maildir 创建后将会受到其第一封邮件。
下面是在 /etc/postfix/master.cf(5) 里定义一个特殊的 Postfix 进程以便通过 deliverquota(8)来投递:
文件 /etc/postfix/master.cf

代码: 全选

[ ... ]
qdeliver  unix  -       n       n       -       -       pipe
  flags=uh user=vmail argv=/usr/local/bin/deliverquota -c -w 90 /var/vmail/${domain}/${user}
and tell Postfix to use this daemon for final delivery to virtual domains, by setting the value of the virtual_transport parameter in /etc/postfix/main.cf:
文件 /etc/postfix/main.cf

代码: 全选

virtual_transport = qdeliver
如果所有的信息投递完毕时maildir已经使用了90% (-w 90)的空间,deliverquota(8) 会在 maildir 里放置一个警告信息。信息内容完全来自文件 /etc/courier/quotawarnmsg 。
请注意, Giovanni Bechis曾报告说:当其中有一个帐号的名称与alias本身一样时, deliverquota(8) 无法正确地将email投递给一个 映射到多个用户帐号的 alias , 除非你在 /etc/postfix/main.cf 里设置如下的参数:
文件 /etc/postfix/main.cf

代码: 全选

qdeliver_destination_concurrency_limit = 1
qdeliver_destination_recipient_limit = 1

Note: setting these parameters to "1" disables parallel deliveries to the same recipient.

头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

回复: OpenBSD as a mail server

帖子 leo » 2011-04-25 21:11

6. 内容过滤
我们已经有了一个全功能邮件服务器了, 它可以发送和接收 email 以及提供远程访问用户邮箱的功能。不过, 如果你不想让服务器成为免疫的病毒搬运工、或者淹死在垃圾信息的海洋里(leo:这个比喻很好,可惜我翻译的不够俏皮), 我们需要安装所有的内容过滤工具。
尽管 Postfix 本身支持多种 内容检查机制, 但是它自己的 文档 也鼓励使用外部的过滤器以及标准的协议,因为这允许你根据自身目的选择最好的MTA和内容检查软件。 因此, 因为我们将依靠第三方软件来进行内容过滤; 特别是我们使用 SpamAssassin 过滤垃圾信息(spam), ClamAV 检查 emails 病毒以及两者兼顾的 Amavisd-new 。 下面是整个构架的大致视图:
图片

6.1 SpamAssassin
SpamAssassin 是一个成熟的、广为开发的开源项目,它可以为邮件服务器提供spam过滤。SpamAssassin使用包括header和内容分析、贝叶斯过滤、DNS黑名单以及协作过滤数据库等各种机制。



有不少要安装的:
  • p5-Socket6-x.x.tgz
  • p5-IO-INET6-x.x.tgz
  • p5-HTML-Tagset-x.x.tgz
  • p5-HTML-Parser-x.x.tgz
  • p5-Net-IP-x.x.tgz
  • p5-Digest-SHA1-x.x.tgz
  • p5-Digest-HMAC-x.x.tgz
  • p5-Net-DNS-x.x.tgz
  • p5-URI-x.x.tgz
  • p5-Net-SSLeay-x.x.tgz
  • p5-IO-Socket-SSL-x.x.tgz
  • libghttp-x.x.x.tgz
  • p5-HTTP-GHTTP-x.x.tgz
  • p5-libwww-x.x.tgz
  • curl-x.x.x.tgz
  • gnupg-x.x.x.tgz
  • re2c-x.x.x.tgz
  • p5-Crypt-OpenSSL-Random-x.x.tgz
  • p5-Crypt-OpenSSL-Bignum-x.x.tgz
  • p5-Crypt-OpenSSL-RSA-x.x.tgz
  • p5-Time-TimeDate-x.x.tgz
  • p5-Mail-Tools-x.x.tgz
  • p5-Mail-DKIM-x.x.tgz
  • p5-NetAddr-IP-x.x.tgz
  • p5-Mail-SpamAssassin-x.x.x.tgz
完成安装后, 你会发现SpamAssassin的主配置文件 (local.cf) 在一个全新的 /etc/mail/spamassassin 目录里。配置段落的内容很复杂也不在本文的讨论氛围内; 不过, 你可以在它的用户手册上了解所有细节 (Mail::SpamAssassin::Conf).
与Postfix类似, 尽管SpamAssassin有很多的配置参数, 不过, 多数情况下, 可以使用默认值,只需修改极少一部分参数:
文件 /etc/mail/spamassassin/local.cf

代码: 全选

rewrite_header    Subject    ***** SPAM *****
report_safe    1
lock_method    flock
required_score    8.0

6.2 ClamAV
ClamAV 是一个基于Unix的开源 (GPL) 的反病毒工具包; 我们主要是为了把它整合进邮件服务器 (也就是附件扫描). 所有处理病毒的任务由下列三个进程来完成:

freshclam
[INDENT]它可以自动连接到ClamAV的 镜像站点 更新病毒定义; 它的配置文件是 /etc/freshclam.conf;
[/INDENT]clamd
[INDENT]一个灵活的、可伸缩的多线程病毒处理进程; 它的配置文件是 /etc/clamd.conf;
[/INDENT]clamscan
[INDENT]一个命令行的病毒扫描程序。
[/INDENT]
所需的packages为:
  • arc-x.x.tgz
  • lha-x.x.x.tgz
  • unzip-x.x.tgz
  • zoo-x.x.x.tgz
  • unarj-x.x (from the ports)
  • unrar-x.x (from the ports)
  • clamav-x.x.tgz
配置文件 freshclam.conf 仅需设置少量的参数:
文件 /etc/freshclam.conf

代码: 全选

DatabaseDirectory    /var/db/clamav
DatabaseOwner        _clamav
DNSDatabaseInfo        current.cvd.clamav.net
DatabaseMirror        db.it.clamav.net
DatabaseMirror        database.clamav.net
MaxAttempts        3
checks            24
现在你可以通过运行 freshclam 命令来更新病毒定义数据库。请确认你已经安装了最新版本的ClamAV, 否则你可能会看到如下所示的低级别functionality level的警告信息:

代码: 全选

# freshclam
ClamAV update process started at Tue Dec 18 00:35:25 2007
WARNING: Your ClamAV installation is OUTDATED!
WARNING: Local version: 0.90.3 Recommended version: 0.92
DON'T PANIC! Read http://www.clamav.net/support/faq
Downloading main.cvd [100%]
main.cvd updated (version: 45, sigs: 169676, f-level: 21, builder: sven)
WARNING: Your ClamAV installation is OUTDATED!
WARNING: Current functionality level = 16, recommended = 21
DON'T PANIC! Read http://www.clamav.net/support/faq
Downloading daily.cvd [100%]
daily.cvd updated (version: 5160, sigs: 8698, f-level: 21, builder: sven)
WARNING: Your ClamAV installation is OUTDATED!
WARNING: Current functionality level = 16, recommended = 21
DON'T PANIC! Read http://www.clamav.net/support/faq
Database updated (178374 signatures) from db.it.clamav.net (IP: 193.206.139.37)
#
这里的低级别的 "functionality level" 意味着你可能不能使用全部的病毒定义,因此可能无法检测出最新的病毒。为了自动更新数据库, 我们只需在crontab进行设置,让freshclam每小时运行一次 (可能无需这样频繁, 这样做的目的是可以避开网络网络峰值导致的更新失败):

代码: 全选

16 * * * * /usr/local/bin/freshclam >/dev/null 2>&1
Also the /etc/clamd.conf configuration file needs editing only very few parameters:
文件 /etc/clamd.conf

代码: 全选

DatabaseDirectory    /var/db/clamav
LocalSocket        /var/clamav/clamd.sock
User            _clamav
[...]
现在我们可以运行 clamd:

代码: 全选

# touch /var/log/clamd.log
# chown _clamav /var/log/clamd.log
# clamd
然后将下面的内容加入 /etc/rc.local(8) 使其随系统启动:
文件/etc/rc.local

代码: 全选

if [ -x /usr/local/sbin/clamd ]; then
    echo -n ' clamd'
    [ -S /var/clamav/clamd.sock ] && rm -f /var/clamav/clamd.sock
    /usr/local/sbin/clamd >/dev/null 2>&1
fi

6.3 Amavisd-new
Amavisd-new 是一个mailer (MTA)和内容检查程序之间的高性能接口。我们将其绑定到loopback网络接口的10024端口, Postfix将用这个loopback网络接口转发所有的进站 e-mails。如果邮件成功地通过了各项检查, 它将被转发回Postfix, 监听端口是本地的10025; 否则, 邮件可能被删除或者隔离,然后管理员以及接收人可以注意到。



下面是所需的packages:
  • cabextract-x.x.tgz
  • freeze-x.x (from the ports)
  • lzop-x.x.tgz
  • lzo-x.x.tgz
  • p5-Archive-Zip-x.x.tgz
  • ripole-x.x.x.tgz
  • p5-Convert-BinHex-x.x.tgz
  • p5-IO-stringy-x.x.tgz
  • p5-Mail-Tools-x.x.tgz
  • p5-Time-TimeDate-x.x.tgz
  • p5-MIME-tools-x.x.tgz
  • p5-Convert-TNEF-x.x.tgz
  • p5-Convert-UUlib-x.x.tgz
  • rpm2cpio-x.x.tgz
  • p5-Net-Server-x.x.tgz
  • p5-Unix-Syslog-x.x.tgz
  • amavisd-new-x.x.x.tgz
安装过程会创建一个 called _vscan 用户及组; 不过, 让Amavisd-new 与 ClamAV 配合的最简单的方式是以同一个用户(_clamav)的身份来一起运行这两个程序。配置文件是 /etc/amavisd.conf, 它实际上是一个perl脚本 (所以请注意每行结尾处的分号!); 下面是你可能想调整的选项:
文件 /etc/amavisd.conf

代码: 全选

# COMMONLY ADJUSTED SETTINGS:
 
$max_servers = 2;
$daemon_user  = '_clamav';     # Run under the same user as ClamAV
$daemon_group = '_clamav';     # Run under the same group as ClamAV
 
$mydomain = 'kernel-panic.it';
 
$MYHOME   = '/var/amavisd';
$TEMPBASE = "$MYHOME/tmp";   # Working directory, needs to be created manually
$ENV{TMPDIR} = $TEMPBASE;
$QUARANTINEDIR = '/var/clamav/quarantine';
 
[...]
 
# Leave only ClamAV uncommented
@av_scanners = (
  ['ClamAV-clamd',
    \&ask_daemon, ["CONTSCAN {}\n", "/var/clamav/clamd.sock"],
    qr/\bOK$/, qr/\bFOUND$/,
    qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
);
 
[...]
 
# Leave only ClamAV uncommented
@av_scanners_backup = (
  ['ClamAV-clamscan', 'clamscan',
    "--stdout --disable-summary -r --tempdir=$TEMPBASE {}", [0], [1],
    qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
);
 
1;
手动创建 Amavisd-new的工作目录 (/var/amavisd/tmp)后, 我们可以用debug模式(也就是in foreground)启动进程, 检查一下有无错误:

代码: 全选

# mkdir /var/amavisd/tmp
# chown -R _clamav:_clamav /var/amavisd/
# /usr/local/sbin/amavisd debug
Dec 18 22:07:11 mail.kernel-panic.it /usr/local/sbin/amavisd[24429]: starting.
/usr/local/sbin/amavisd at mail.kernel-panic.it amavisd-new-2.3.2 (20050629), Unicode aware
Dec 18 22:07:11 mail.kernel-panic.it /usr/local/sbin/amavisd[24429]: user=,
EUID: 0 (0);  group=, EGID: 0 31 20 5 4 3 2 0 (0 31 20 5 4 3 2 0)
Dec 18 22:07:11 mail.kernel-panic.it /usr/local/sbin/amavisd[24429]: Perl version               5.008008
[...]
现在将 Amavisd-new 配置为随系统启动:
文件 /etc/rc.local

代码: 全选

if [ -x /usr/local/sbin/amavisd ]; then
    echo -n ' amavisd'
    /usr/local/sbin/amavisd >/dev/null 2>&1
fi
最后的步骤是更新 Postfix 配置 以确保Postfix和Amavisd-new的衔接完好。要完成这个任务, 我们必须在 /etc/postfix/master.cf(5) 配置文件里添加两个服务: 一个是将所有的进站 emails 转发给 Amavid-new, 而另一个是将 emails 再次发回:
文件 /etc/postfix/master.cf

代码: 全选

smtp-amavis unix -    -    -    -    2  smtp
    -o smtp_data_done_timeout=1200
    -o smtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20
 
127.0.0.1:10025 inet n    -    -    -    -  smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o relay_recipient_maps=
    -o smtpd_restriction_classes=
    -o smtpd_delay_reject=no
    -o smtpd_client_restrictions=permit_mynetworks,reject
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o mynetworks_style=host
    -o mynetworks=127.0.0.0/8
    -o strict_rfc821_envelopes=yes
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
最后我们要告诉Postfix开始转发所有的它从amavisd-new接收的emails,这些邮件均经过了内容检查,还要通知Postfix重新载入配置文件。

代码: 全选

# postconf -e 'content_filter=smtp-amavis:[127.0.0.1]:10024'
# postfix reload
postfix/postfix-script: refreshing the Postfix mail system

头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

回复: OpenBSD as a mail server

帖子 leo » 2011-04-25 21:58

7. Postfix高级配置
Postfix提供了很多不在本文探讨范围内的吸引人的特性; 我们只测试一部分与Postfix运行环境安全相关的特性。

7.1 启用TLS
在Postfix里启用 TLS 支持可以允许你加密 SMTP 会话和 SASL认证 交换以及可以选择远程客户端和/或服务器的认证方式。不过, 别忘了, 一旦启用 TLS 支持, 你同时也开启了成千上万的行的OpenSSL库代码。这里假设Wietse写OpenSSL代码时就像为自己写代码那样仔细, 每一千行代码会给 Postfix[TLS] 带来一个额外的BUG。 因此, 如果你觉得你无需这些特性, 请自行跳过这段。
TLS 依赖公共密钥证书来进行认证,所以需要你先设置一个 basic Public Key Infrastructure (PKI) 来管理数字证书。 作为准备步骤, 我们先创建用以保存证书的目录:

代码: 全选

# install -m 700 -d /etc/postfix/ssl/private
The first step in setting up the PKI is the creation of the root CA certificate (/etc/ssl/ca.crt) and private key (/etc/ssl/private/ca.key) using openssl(1):

代码: 全选

# openssl req -days 3650 -nodes -new -x509 -keyout /etc/ssl/private/ca.key \
> -out /etc/ssl/ca.crt
[ ... ]
Country Name (2 letter code) []: IT
State or Province Name (full name) []: Italy
Locality Name (eg, city) []: Milan
 
Organization Name (eg, company) []: Kernel Panic Inc.
Organizational Unit Name (eg, section) []: Postfix CA
Common Name (eg, fully qualified host name) []: ca.lan.kernel-panic.it
Email Address []: <enter>
#
接下来的步骤是为邮件服务器创建private key (/etc/postfix/ssl/private/server.key) 和 请求签署的证书Certificate Signing Request (/etc/postfix/ssl/private/server.csr) :

代码: 全选

# openssl req -days 3650 -nodes -new -keyout /etc/postfix/ssl/private/server.key \
> -out /etc/postfix/ssl/private/server.csr
[ ... ]
Country Name (2 letter code) []: IT
State or Province Name (full name) []: Italy
Locality Name (eg, city) []: Milan
 
Organization Name (eg, company) []: Kernel Panic Inc.
Organizational Unit Name (eg, section) []: Postfix Server
Common Name (eg, fully qualified host name) []: mail.kernel-panic.it
Email Address []: <enter>
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <enter>
An optional company name []: <enter>
 
#
最后, CA将依据签署请求生成签署的证书:

代码: 全选

# openssl x509 -req -days 3650 -in /etc/postfix/ssl/private/server.csr \
> -out /etc/postfix/ssl/server.crt -CA /etc/ssl/ca.crt \
> -CAkey /etc/ssl/private/ca.key -CAcreateserial
 
Signature ok
subject=/C=IT/ST=Italy/L=Milan/O=Kernel Panic Inc./OU=Postfix Server/CN=mail.kernel-panic.it
Getting CA Private Key
#
如果你想让邮件服务器认证 SMTP 客户端, 你可以重复最后两部来生成任意数目的客户端证书。要在Postfix里真正开启TLS支持, 我们需要在配置文件 /etc/postfix/main.cf 里加入一些参数:
文件 /etc/postfix/main.cf

代码: 全选

# Enable (optional) TLS encryption
smtpd_tls_security_level = may
# Enable logging of TLS handshake and certificate information
smtpd_tls_loglevel = 1
 
# TLS certificates
smtpd_tls_cert_file = /etc/postfix/ssl/server.crt
smtpd_tls_key_file = /etc/postfix/ssl/private/server.key
smtpd_tls_CAfile = /etc/ssl/ca.crt
 
# External entropy source for the pseudo random number generator pool.
# Specify /dev/arandom when /dev/urandom gives timeout errors.
tls_random_source = dev:/dev/urandom
然后在 /etc/postfix/master.cf(5) 去掉smtps service前面的注释符:
文件 /etc/postfix/master.cf

代码: 全选

smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
最后, 我们重新加载Postfix的配置文件以应用修改:

代码: 全选

# postfix reload
postfix/postfix-script: refreshing the Postfix mail system


7.2 基于SASL的SMTP认证
配置Postfix 时, 我们已经限制了将邮件中继到限制一定数量的信任网络, 也就是公司内部的LANs。但是有时, 比如这个中继策略并可能不适合你们公司的需要: 一个典型的例子是需要让手机用户 (比如销售人员) 在Internet上从任何地方发送信息。在这种情况下, 最佳的解决方式是允许中继那些真正使用SMTP认证的合法用户 (同时仍旧阻止 UCE 软件) 的信息, 这里所说的SMTP认证是指SASL protocol (定义在 [RFC4954] 里)。不过, 启用SASL认证这也有一些缺点: 它会让我们无法chroot smtpd(8) 进程, 因为 Cyrus SASL 库包含很多的代码, Postfix的安全等级会和其它使用 Cyrus SASL library (see [SASL])的邮件系统一样了。所以, 如果你无需此特性,请跳过这一段。
要在Postfix里启用 SASL 认证, 我们必须在配置文件 /etc/postfix/main.cf 里添加一些参数:
文件 /etc/postfix/main.cf

代码: 全选

# Enable SASL authentication in the Postfix SMTP server
smtpd_sasl_auth_enable = yes
 
# Only accept mail from trusted networks, authenticated clients or mail with
# a 'RCPT TO' address that Postfix is forwarder or final destination for
smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated 
  reject_unauth_destination
 
# Enable inter-operability with old SMTP clients
broken_sasl_auth_clients = yes
 
# Name of the Postfix SMTP server's local SASL authentication realm
smtpd_sasl_local_domain = $mydomain
SASL 的配置参数必须包含在一个名为 smtpd.conf 的文件里, 它位于 /usr/local/lib/sasl2 。 SASL library 会依赖 Courier's authdaemond 进程,因为 authentication backend (MySQL的backend仅支持明文储存密码):
文件 /usr/local/lib/sasl2/smtpd.conf

代码: 全选

pwcheck_method: authdaemond
authdaemond_path: /var/run/courier-auth/socket
mech_list: PLAIN LOGIN
接下来, 我们需要编辑文件 /etc/postfix/master.cf(5) 以使 smtpd(8) 运行在非chrooted环境 (只需在进程的 chroot 那输入一个 “n”):
文件 /etc/postfix/master.cf

代码: 全选

smtp inet n - n - - smtpd
[ ... ]

然后重新加载Postfix配置。

代码: 全选

# postfix reload
postfix/postfix-script: refreshing the Postfix mail system

最后, 我们可以做一个简单的运行测试以确保所有程序工作正常。发送的认证信息是基于64位编码的字符串 "\0username\0password", 这里的 "\0" 是一个空字节。

代码: 全选

$ perl -MMIME::Base64 -e 'print encode_base64("\0d.mazzocchio\@kernel-panic.it\0danix");'
AGQubWF6em9jY2hpb0BrZXJuZWwtcGFuaWMuaXQAZGFuaXg=
$ telnet mail.kernel-panic.it 25
Trying 172.16.240.150...
Connected to mail.kernel-panic.it.
Escape character is '^]'.
220 mail.kernel-panic.it ESMTP Postfix
EHLO somedomain.org
250-mail.kernel-panic.it
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN AGQubWF6em9jY2hpb0BrZXJuZWwtcGFuaWMuaXQAZGFuaXg=
235 2.0.0 Authentication successful
quit
221 2.0.0 Bye
Connection closed by foreign host.
$

头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

回复: OpenBSD as a mail server

帖子 leo » 2011-04-25 21:59

8. SquirrelMail
除了 IMAPPOP3, 多数用户仍旧希望有基于web的邮箱访问方式。因此, 我们将安装l SquirrelMail, 一个用PHP编写的基于标准的webmail package, 它内置了对 IMAP 和 SMTP 协议的支持。这个程序编写时仅可能地考虑了各种浏览器的兼容性,而且所需条件很低; SquirrelMail的 安装配置 很简单,并且提供了很多的 插件 ,这些插件可以让管理员更深入地定制其外观和用户感受。
另一款极好的替代软件是 RoundCube, 也可以从OpenBSD的ports and packages找到。
请注意,webmail软件并非必须装在mail主机上: 事实上, 如果你有一个独立的web服务器, 最好的方式是将该软件安装在那里。

8.1 初始步骤


需要的packages是:
  • libxml-x.x.x.tgz
  • php5-core-x.x.x.tgz
  • php5-mbstring-x.x.x.tgz
如果你的系统尚未安装 PHP , 别忘了启用(leo:此处原文如此,意思应该是安装后别忘了启用)它, 同时还有 mbstring 模块:

代码: 全选

# ln -s /var/www/conf/modules.sample/php5.conf /var/www/conf/modules
# ln -fs /var/www/conf/php5.sample/mbstring.ini /var/www/conf/php5/mbstring.ini
你还需要在apache的配置文件里去掉下列行的注释符, /var/www/conf/httpd.conf:

代码: 全选

AddType application/x-httpd-php .php
and restart Apache:

代码: 全选

# apachectl restart
/usr/sbin/apachectl restart: httpd restarted

8.2 安装和配置
现在我们先 下载 SquirrelMail, 在apache的chroot环境里extract它,并为其起新建一个目录以及一个好名字:

代码: 全选

# tar -zxvf squirrelmail-x.x.x.tar.gz -C /var/www/htdocs
# mv /var/www/htdocs/squirrelmail-x.x.x /var/www/htdocs/webmail




下面, 我们需要创建三个目录:
  • 数据目录 (/var/www/squirrelmail/data), 包含了用户参考文档,而且属于 Apache的www用户;
  • 附件目录 (/var/www/squirrelmail/attachments), email附件将上传到这里并且仅能被root用户读取, 但是www用户有写权限;
  • 临时目录,将储存会话数据 (/var/www/tmp), 必须只能被www用户访问。

代码: 全选

# install -d -o www -g www  /var/www/squirrelmail/data
# install -d -g www -m 730 /var/www/squirrelmail/attachments
# install -d -o www -g www -m 700 /var/www/tmp

更多的配置可以通过一个带菜单的Perl脚本来完成, /var/www/htdocs/webmail/config/conf.pl。一些你肯定需要定制的参数是:
Organization Preferences -> Organization Name
[INDENT]The organization name, which will appear here and there in the web pages.
[/INDENT]Server Settings -> Domain
[INDENT]The domain name.
[/INDENT]General Options -> Data Directory
[INDENT]The pathname to the directory in which user preferences will be stored (in our case /squirrelmail/data/).
[/INDENT]General Options -> Attachment Directory
[INDENT]The pathname to the directory in which attachments will be temporarily stored (in our case /squirrelmail/attachments/).
[/INDENT]Set pre-defined settings for specific IMAP servers -> courier
[INDENT]Enable the predefined settings optimized for Courier-IMAP.
[/INDENT]

头像
leo
帖子: 2465
注册时间: 2010-01-21 3:27

回复: OpenBSD as a mail server

帖子 leo » 2011-04-25 21:59

9. Appendix
Special thanks to TomazZ for his detailed notes on configuring TLS in Postfix.

9.1 References
9.2 Bibliography

回复

在线用户

正浏览此版面之用户: 没有注册用户 和 41 访客