Postfix

MTA(メール中継エージェント)の一つ。コンフィグレベルでSendmailと互換性がある。
転送先がSMTPをサポートしていれば、フィルタリング、ウイルスチェック、リバースプロキシへ転送する事も可能。

構築環境

今回検証した環境はこちら

構築

1. ディレクトリ構成
普通は"/var/spool"以下にメールデータを格納するのだが、
今回はちょっと特殊な構成な点と、色々なミドルウェアとの連携をしているので、
メールデータディレクトリのみデフォルトから変更している。

メールデータディレクトリ:/var/hostname/spool/*
Postfixのコンフィグディレクトリ:/etc/postfix/*
Postfixのシステムコンフィグファイル:/etc/sysconfig/postfix

今回はこのディレクトリ構成でMTA(Postfix)の構築を行う

2. インストール
ソースからmakeするのが筋なのだろうが、面倒だったのでyastでインストール。
zypperとかyumとかapt-getでも同様に行ける。

# yast
    [Software] -> [Software Management] -> [Search Phrase] -> "postfix"を入力。
    実際にインストールするのは、"postfix","postfix-devel","postfix-mysql"の三つ。


設定

・説明
Postfixのメインコンフィグを書き換えていく。
存在しないコンフィグファイルがあった場合は新規作成をする。

基本的にデフォルトのパラメータやディレクトリ構成を使用する事とする。
しかし、ユーザ情報はMySQLで管理する構成なので、
PostfixからMySQLへのアクセスを行う設定ファイルを追加作成する。
設定例としてMySQLはlocalhostに構築済みかつ、MySQL用のパラメータを以下とする。

・MySQLユーザ名:postfix-mysql-user
・MySQLパスワード:postfix-mysql-pass
・MySQLのDB名:postfix-user-db


あと、現状のPostfixコンフィグの何処を書き換えたかうろ覚えなので、
変更した設定ファイル内容を全て列挙する。

1). 下記の書き換え項目に挙っていない所は全てコメントアウトする。
2). 書き換えに上がっていない設定ファイルはデフォルトのまま使用する。


/etc/postfix/main.cf

##
## 基本設定
##
## マニュアル [http://www.postfix-jp.info/trans-2.2/jhtml/postconf.5.html]
##

# Postfixのキューディレクトリ。キューディレクトリはデフォルトを使用する
queue_directory = /var/spool/postfix

# Postfixの管理コマンド
command_directory = /usr/sbin

# Postfixのサポート、デーモンの各プログラムがあるディレクトリ
daemon_directory = /usr/lib/postfix

# Postfixが書き込むディレクトリ。所有ユーザが$mail_ownerの値になっている必要がある
data_directory = /var/lib/postfix

# Postfixデーモンの実行ユーザ
mail_owner = postfix

# MTAのホスト名。FQDNで書く必要がある
myhostname = mail.hoge.org

# MTAのドメイン名。$myhostnameからホスト部分を取った値になる
mydomain = hoge.org

# Postfixから送信したメールが、何処のメールサーバ(FQDN)から送信された物かの記述を指定する
myorigin = $myhostname

# メールを受け取るNICのアドレス。allを指定すると全てから受け取る
inet_interfaces = all

# メール配送をされるドメインのリスト。今回はバーチャルドメインを利用するので"空白"を指定する
mydestination =

# 受信者アドレスがローカルIPで、受信者条件に合致しない時に応答するコード
unknown_local_recipient_reject_code = 550

# $mynetworksパラメータのデフォルト値を生成する方法。普通はhostかsubnetを指定する
mynetworks_style = subnet

# 信頼されたネットワーク。MTAのサーバ自体(127.0.0.1/32)と、LANの値(192.168.0.0/24)を指定する
mynetworks = 192.168.0.0/24, 127.0.0.1/32

# Postfixがメールをリレーしようとする配送先MTAドメイン
relay_domains = $mydestination

# Postfixの認証(ユーザのログイン)で使用されるエイリアスデータベース
alias_maps = hash:/etc/aliases

# newaliasesコマンドで更新されるエイリアスデータベース
alias_database = hash:/etc/aliases

# メールの保存ディレクトリ名と保存形式。今回はMailDir形式(一つのメールに一つのファイル)で保存を行う
# 下記だと各ユーザの"mail"というディレクトリの中にメール毎にファイルを生成し保存する事になる
home_mailbox = mail/

# メールの配送に使用するコマンド。つまり、Postfixの受信したメールの次の行き先をコマンドレベルで指定する
# 今回は、procmailでの振り分けを行うのでprocmailのバイナリ(コマンド)を指定する
mailbox_command = /usr/bin/procmail

# SMTPのリターンコードが220の時に付随するテキスト。unknownにしないとPostfixのバージョンが漏れる
smtpd_banner = $myhostname ESMTP unknown

# リモートクライアントかサーバが$debug_peer_listパラメータにマッチした場合の冗長ログレベル
debug_peer_level = 2

# デーモンが"-D"オプションで呼ばれた時に実行される外部コマンド
debugger_command =
     PATH=/bin:/usr/bin:/usr/local/bin
     ddd $daemon_directory/$process_name $process_id & sleep 5

# Sendmail互換機能。Postfixキューにメールを投げるのに使用される
sendmail_path = /usr/sbin/sendmail

# Sendmail互換機能。localのエイリアスDBを再構築する際に使用
newaliases_path = /usr/bin/newaliases

# Sendmail互換機能。Postfixのメールキューをリストアップする
mailq_path = /usr/bin/mailq

# Postfixコマンド、Postfixディレクトリを所有するグループ
# このパラメータを変更した場合、"postfix set-permissions"コマンドを実行する必要がある
setgid_group = maildrop

# Postfixのドキュメント(HTML)ファイルのディレクトリ
html_directory = /usr/share/doc/packages/postfix-doc/html

# Postfixのマニュアルがインストールされたディレクトリ
manpage_directory = /usr/share/man

# Postfixの設定例があるディレクトリ
sample_directory = /usr/share/doc/packages/postfix-doc/samples

# PostfixのREADMEファイルのディレクトリ
readme_directory = /usr/share/doc/packages/postfix-doc/README_FILES

# Postfixが待ち受けるプロトコル。ipv4=IPv4,ipv6=IPv6,all=IPv4+IPv6
inet_protocols = ipv4



##
## [独自追加部分] - SASL設定
##

# PostfixのSASL認証を有効にする
smtpd_sasl_auth_enable = yes

# Receivedヘッダーに認証ユーザ名を表示する
smtpd_sasl_authenticated_header = yes

# DovecotのSASL認証を利用する
smtpd_sasl_type = dovecot

# DovecotのSASL認証用デーモンのソケットを指定
smtpd_sasl_path = private/auth

# SASL認証のレルム(realm)の指定
smtpd_sasl_local_domain = $myhostname

# クライアントに許可(提供)する認証方法
#   noplaintext  : 平分パスワードを非許可
#   noactive     : "non-dictionary active"攻撃に脆弱な認証を非許可
#   nodictionary : "passive dictionary"攻撃に脆弱な認証を非許可
#   noanonymous  : 匿名ログインを非許可
#   mutual_auth  : 相互認証を提供する方法のみ許可
smtpd_sasl_security_options = noanonymous

# SMTPクライアントがSMTPセッションで"HELO"or"EHLO"コマンドで情報を要求する
smtpd_helo_required = yes

# PostfixがSMTP"RCPT TO"コマンドの際に適用するアクセス制限。詳細はPostfixのマニュアルを読むこと
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

# 古いバージョンのSMTP"AUTH"コマンドとの相互運用性を有効にする
broken_sasl_auth_clients = yes

# PostfixでTLSを有効にする。Postfix2.3以降だと"smtpd_tls_security_level"の使用を推奨している
smtpd_use_tls = yes

# Postfixで暗号化されていないSASL認証を受け付けない。"smtpd_use_tls = yes"になっている事が必要
smtpd_tls_auth_only = yes

# PEMフォーマットのSMTP(Postfix)サーバ用RSA証明書ファイル
smtpd_tls_cert_file = /etc/pki/tls/mail.hoge.crt

# PEMフォーマットのSMTP(Postfix)サーバ用RSA秘密鍵ファイル
smtpd_tls_key_file = /etc/pki/tls/mail.hoge.key

# PostfixのTLSセッションキャッシュを含むファイルの名前。btreeやsdbmを指定する。dbmは非推奨
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache

# 擬似乱数生成用のソースファイル。デバイスファイルを指定する際には、先頭に"dev:"を付ける
tls_random_source = dev:/dev/urandom

# SMTPの"SMTP VRFY"コマンドを無効化する
disable_vrfy_command = yes



##
## [独自追加部分] - バーチャルドメイン設定
##
## 先頭に"mysql:"と付いている箇所はMySQLのDB値を取得する事を意味する
##

# $mydestinationでリストアップされたドメインへの配送先。下記だとバーチャルドメインを指定
local_transport = virtual

# $virtual_mailbox_domainsでリストアップされたドメインで、最終配送時のデフォルトメール配送(Next-Hop)先
virtual_transport = procmail

# 特定メールアドレス、ドメインのエイリアスファイルを指定
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf

# 指定されたバーチャルエイリアスドメインの最終配送先
# $virtual_alias_maps内に受信者アドレスが存在しない場合、受信を拒否する
virtual_alias_domains = $virtual_alias_maps

# バーチャルドメインのトップレベルメールスプールディレクトリを指定
# $virtual_mailbox_mapsテーブル検索結果の全てのPATHの先頭に付けるプレフィックスと同じ意味
virtual_mailbox_base = /var/hoge/mail-spool

# $virtual_mailbox_domainsに対応する有効なアドレスのオプション検索テーブル
# $virtual_mailbox_baseの値がこのPATHの前に付けられるので注意
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf

# 指定ファイル内から受信者アドレスの検索を行い、存在しない受信者宛のメールは拒否をする
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf

# メールの最大サイズ(Byte換算)。0だと無制限
message_size_limit = 10485760

# MTAサーバでのQuota制限に引っかかった場合、エラーメールを返送する
virtual_overquota_bounce = yes

# 受信メールボックスのみを制限する
virtual_mailbox_limit_inbox = yes

# バーチャルドメイン毎の最大メールボックスを記述したエイリアスファイルを指定
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf

# $virtual_mailbox_limit_mapsの値で、最大メールボックスの設定値を上書きする
virtual_mailbox_limit_override = yes

# PostfixのユーザIDの最小値を指定する。この値以下のユーザ(UID)での配送は全て拒否する
virtual_minimum_uid = 5000

# 用意したユーザIDを指定する。5000以降にしておくとシステムと被る事が少ないので良
virtual_uid_maps = static:5000

# 用意したグループIDを指定する。5000以降にしておくとシステムと被る事が少ないので良
virtual_gid_maps = static:5000

# キューに入った後にフィルタリング処理を行うMTAの名前とポートを指定する
# Postfixのコンフィグ(master.cf)に書いた値を指定する。他のMTAサーバ(IPアドレス違い)を指定する事も可能
# 今回はウイルスチェックを通す為、amavisの待機ポートを指定する
content_filter = amavis:[localhost]:10026

# 受信者確認、アドレス書き換えの処理を指定する
#   no_unknows_recipient_checks : 知らない受信者でも拒否をしない
#                                 外部コンテンツフィルタの"後"に処理される
#   no_address_mappings         : バーチャルエイリアスマップ拡張、自動BCC受信者を無効にする
#                                 外部コンテンツフィルタの"前"に処理される
#   no_header_body_check        : ヘッダー・ボディチェックを無効にする
#                                 外部コンテンツフィルタの"後"に処理される
receive_override_options = no_address_mappings


/etc/postfix/mysql_virtual_alias_maps.cf

user = postfix-mysql-user
password = postfix-mysql-pass
hosts = localhost
dbname = postfix-user-db
table = alias
select_field = goto
where_field = address


/etc/postfix/mysql_virtual_domains_maps.cf

user = postfix-mysql-user
password = postfix-mysql-pass
hosts = localhost
dbname = postfix-user-db
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'


/etc/postfix/mysql_virtual_mailbox_limit_maps.cf

user = postfix-mysql-user
password = postfix-mysql-pass
hosts = localhost
dbname = postfix-user-db
table = mailbox
select_field = quota
where_field = username
additional_conditions = and active = '1'


/etc/postfix/mysql_virtual_mailbox_maps.cf

user = postfix-mysql-user
password = postfix-mysql-pass
hosts = localhost
dbname = postfix-user-db
table = mailbox
select_field = maildir
where_field = username
additional_conditions = and active = '1'


/etc/postfix/vquota

# 該当メールアドレスのバーチャルクォータを指定
# ドメインのオーナーアドレスとかは下記みたいに個別指定にした方が良
hoge-owner@mail.hoge.org 524288000
# ドメイン全体でのバーチャルドメインクォータを指定
# 『個別メールクォータ容量≦ドメイン全体でのクォータ容量』になるようにする
@mail.hoge.org 524288000