PostfixとDovecotによるメールサーバの構築 その2

郵便ポスト

前回はメールサーバを構築するためにDNSでMXレコードなどの設定をしたことを紹介しました。

今回は実際にメールサーバのソフトウェアを導入していきます。

まずはPostfixです。Postfixはメールを配送するソフトウェア(MTA)です。単純にメール送信担当のソフトだと思えば良いと思います。ちゃんと設定すれば、Postfixは、自ホスト宛のメールはローカルに保存し、外部宛のメールはその宛先でメール配送を担当するホストにメールを引き渡してくれます。

今回の環境

念のため今回メールサーバを構築する環境を再掲しておきます。

  • VPS: お名前.com VPS
  • OS: Debian GNU/Linux Jessie 64bit
  • IPアドレス: a.b.c.d
  • ホスト名: example.comとexample.net
    (ホスト名とIPアドレスは説明のための仮の名前とアドレスです。)

お名前.com VPSだと提供されるIPアドレスは1個です。しかし私はドメイン名を二つ持っているので、それぞれのドメイン名でメールを受信したいと思っています。

また、今回の環境ではホスト名=ドメイン名となってしまっています。

Postfixのインストール

PostfixはDebianに入っているのでapt-getでインストールすることができます。

# apt-get update
# apt-get install Postfix
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
提案パッケージ:
Postfix-mysql Postfix-pgsql Postfix-ldap Postfix-pcre sasl2-bin dovecot-common resolvconf Postfix-cdb ufw
Postfix-doc
以下のパッケージは「削除」されます:
exim4 exim4-base exim4-config exim4-daemon-light
以下のパッケージが新たにインストールされます:
Postfix
アップグレード: 0 個、新規インストール: 1 個、削除: 4 個、保留: 0 個。
1,371 kB のアーカイブを取得する必要があります。
この操作後に 2,354 kB のディスク容量が解放されます。
続行しますか? [Y/n]

「Y」を押すとインストールが始まるのですが、インストール中に2つ質問が出てきます。

まずはメールサーバの設定形式です。ここは「インターネットサイト」を選択しておきます。なお、メールの配送を肩代わりしてくれるサーバを別途お持ちの場合は、スマートホスト付きインターネットを選ぶとよいかもしれません。

SnapCrab_NoName_2015-5-30_1-35-54_No-00

次はメール名の入力です。ここはメールのドメイン名「example.com」を入力します。今回は別ドメインexample.netも処理したいのですが、それは後ほど行います。

SnapCrab_NoName_2015-5-30_1-39-30_No-00

これでしばらく待てばインストールが完了します。

SMTP-Authの準備

SMTPを安全に運用するには許されたユーザのみ送信をできるSMTP-AUTHを導入した方がよいです。

この「許されたユーザかどうか」という判定を行う機構としてSASL認証機構というものがあります。Postfixはこれに対応しているらしいので導入しておきます。

apt-get install sasl2-bin libsasl2-modules

sasl認証機構を担当するsaslauthdの設定ファイルは/etc/default/saslauthdです。この設定ファイルのSTARTとOPTIONSの行を書き換えます。下記は/etc/default/saslauthdの内容(有効な行をピックアップしたもの)です。

START=yes
DESC="SASL Authentication Daemon"
NAME="saslauthd"
MECHANISMS="pam"
MECH_OPTIONS=""
THREADS=5
OPTIONS="-c -m /var/spool/Postfix/var/run/saslauthd"

ハイライトとなっている1行目と7行目が今回変更した部分です。

1行目ではsaslauthdが自動起動するように変更しています。

7行目ではPostfixがchroot環境で動いている場合にsaslauthdと通信できるように設定しています。

これが終わったら次の2つのコマンドを実行します。Postfixがsaslauthdを利用できるようになるおまじないと思ってください。

dpkg-statoverride --add root sasl 750 /var/spool/Postfix/var/run/saslauthd
adduser Postfix sasl

最後にsaslauthdとPostfixを再起動します。

service saslauthd restart
service postfix restart

Postfixの設定

これで準備が整ったのでPostfixの設定をしていきます。

メールボックス形式の設定

デフォルトだとメールの配送にprocmailというソフトを使うことになっており、メールはmbox形式で格納されます。しかし現在の主流はMaildir形式となっています。

mbox形式をMaildir形式に変更するには/etc/postfix/main.cfファイルを次のように変更します。

  • mailbox_commandで始まる行をコメントアウト(行頭に#を挿入)
  • 「home_mailbox = Maildir/」という行を挿入

次に既存のユーザ用のMaildirディレクトリを作成します。rootではなく各ユーザで次のコマンドを実行します。

mkdir ~/Maildir
chmod 700 ~/Maildir

最後に今後作成するユーザに自動的にMaildirディレクトリができるようにしておきます。これはrootで実行してください。

mkdir /etc/skel/Maildir
chmod 700 /etc/skel/Maildir

バーチャルドメインの設定

今回は一つのIPアドレスのサーバで二つのドメイン(example.comとexample.net)のメールを処理します。Postfixのバーチャルドメイン機能を使うとこれが実現できます。

まずは、/etc/postfix./virtualというファイルを作成し、どのメールアドレスにメールが来たら、このVPS(Linux)上のどのアカウントに配送するかを記述します。

例として、次のような状況を考えます。

  • VPS(Linux)上のアカウントはfooとbuzの二つ
  • メールアドレスはfoo@example.com, bar@example.com, buz@example.net, qux@example.netの4つを使えるようにする。
  • foo@example.comとbar@example.com宛のメールはアカウントfooに配送する
  • buz@example.netとqux@example.net宛のメールはアカウントbuzに配送する

この時、/etc/postfix/virtualの記述は次のようになります。

example.com anything
foo@example.com foo
bar@example.com foo

example.net anything
buz@example.net buz
qux@example.net buz

この形式はわかりやすいと思います。

ドメイン(例: example.com)を書いてスペースを空けて「anything」と記述すし、後はメールアドレスと配送先のアカウント名のペアを記述すればよいだけです。

メールアドレスの名前(@の左側)が実在するアカウントでなくても良い点に注意してください。このためさまざまなアカウントを作って実際は一人のユーザが受信するなんてことも可能です。

メールの配送先のユーザ(ここではfoo、buz)が存在していない場合にはadduserコマンドでユーザを作成し、パスワードを設定しておきます。このユーザがメール送受信専用のユーザ(SSHでログインしたりしないユーザ)の場合は次のようにユーザを作成すると、万が一パスワードなどがばれたときにも被害を抑えることができます。

useradd -m -s /usr/sbin/nologin 作成するユーザ名
passwd 作成するユーザ名

そして/etc/postfix/main.cfに下記の2行を付け加えることで、Postfixがexample.net宛のメールも処理できるようにします(example.com宛のメールについてはmydestinationに書いてあるので、virtual_alias_domainsには記載不要)。

virtual_alias_domains = example.net
virtual_alias_maps = hash:/etc/postfix/virtual

最後に作成したvirtualファイルをDB化して、Postfixを再起動します。

postmap /etc/postfix/virtual
service postfix reload

SMTP-Authの設定

次はSMTP-Authの設定です。準備はできているので、Postfixがsaslを使うようにします。このためには下記の行を/etc/postfix/main.cfに追記します。

smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_path = smtpd
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

さらに/etc/postfix/sasl/smtpd.confというファイルを作り、次のような内容とします。

pwcheck_method: saslauthd
mech_list: plain login

最後に変更を反映します。

service postfix reload

なお、この部分の記載は下記のサイトをかなり参考にさせていただきました。SMTP=Authの設定の確認方法とかもあるので、チェックすることをお勧めします。

SSL/TLSの設定

次にSSL/TSLの設定です。これにより通信内容を暗号化することができます。

まずはmain.cfの設定です。

実はDebianでPostfixをインストールするとデフォルトでSSL/TLSが有効になっています。証明書がsnakeoilという怪しい証明書ですが、このPostfixを使うのは自分だけなのでとりあえず気にしないものとします。ここでは、脆弱性のあるSSLv3とSSLv2を無効にして、TLSを強制使用するために下記の行を追記します。

smtp_tls_protocols            = !SSLv2, !SSLv3
smtp_tls_mandatory_protocols  = !SSLv2, !SSLv3
smtpd_tls_protocols           = !SSLv2, !SSLv3
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_enforce_tls             = yes

さらに、後述のmaster.cfの設定で必要になるので、下記の行も追記しておきます(これで正しいのか自信がないですが・・・)。

mua_client_restrictions = permit_mynetworks,permit_sasl_authenticated,reject
mua_helo_restrictions   = permit_mynetworks,permit_sasl_authenticated,reject
mua_sender_restrictions = permit_mynetworks,permit_sasl_authenticated,reject

次にmaster.cfの設定です。

こちらはmaster.cfにサンプルの記述があるのですがコメントアウトされていまので、行頭の「#」を外していきます。下記が「#」を外して有効にした行です。

smtps     inet  n       -       -       -       -       smtpd
-o syslog_name=Postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=$mua_client_restrictions
-o smtpd_helo_restrictions=$mua_helo_restrictions
-o smtpd_sender_restrictions=$mua_sender_restrictions
-o smtpd_recipient_restrictions=
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING

最後に変更を反映します。

service postfix reload

サブミッションポートの設定

サブミッションポートは通常のポート25の代替としてつかうポートですが、送信にはSMTPSを使うのでこの設定は不要です。

サブミッションポートを使いたい場合はmaster.cfのsubmissionで始まる行とその後続行の先頭の「#」を外してから、Postfixを再起動すればOKです。

iptablesの設定

iptablesでファイヤウォールを構築している場合は、ポートを開ける必要があります。

Postfixが外部から受け付けるのは25(SMTP)と465(SMTPS)なので、次の2行を/etc/iptables/rules.v4に記載します。

-A INPUT -d サーバのIPアドレス/32 -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT
-A INPUT -d サーバのIPアドレス/32 -p tcp -m state --state NEW -m tcp --dport 465 -j ACCEPT

なお記載する位置も重要です。よくわからなければWebサーバ(ポート80)を許可している行のすぐ後に記載すればよいでしょう。

最後に変更を反映します。

service netfilter-persistent reload

動作確認

動作確認は下記の4点になります。

  • このPostfixを設置したホスト内でメールが送信できること
  • このPostfixを設置したホストから外部にメールが送信できること
  • このPostfixを設置したホストへ外部からメールを直接送信できること
  • このPostfixを設置したホストを介して外部にメールが送信できること
  • このPostfixを設置したホストへ外部からメールを他のメールサーバ経由で送信できること

すべてログ(/var/log/syslog)を開きながら動作を確認していきます。ログの確認は下記のコマンドで行います。

tail -f /var/log/syslog | grep Postfix

ホスト内でのメール送信確認

これはPostfixを設置したホストにSSHで接続して行います。mailコマンドで既存のユーザにメールを送信してみましょう。メールの本文は「.」(ドット)だけ入力して改行すると入力終了になります。

mail 送信先のユーザ名(メールアドレス)
Subject: メールのタイトル
メールの本文
.
Cc:

これで/var/log/syslogに次のようなログが出ればOKです。ポイントは「status=sent」になっているところです。

May 30 16:58:07 ホスト名 Postfix/pickup[1444]: ABCDEFG: uid=送信元ユーザID from=< 送信元ユーザ名>
May 30 16:58:07 ホスト名 Postfix/cleanup[11070]: ABCDEFG: message-id=<20150530075807.ABCDEFG@送信元ドメイン名>
May 30 16:58:07 ホスト名 Postfix/qmgr[1443]: ABCDEFG: from=< 送信元ユーザ名@送信元ドメイン名>, size=311, nrcpt=1 (queue active)
May 30 16:58:07 ホスト名 Postfix/local[11072]: 3ABCDEFG: to=< 送信先ユーザ名@送信元ドメイン名>, orig_to=, relay=local, delay=0.02, delays=0.01/0/0/0, dsn=2.0.0, status=sent (delivered to maildir)
May 30 16:58:07 ホスト名 Postfix/qmgr[1443]: ABCDEFG: removed

送信先のユーザ名をドメイン付(ユーザ名@ドメイン名)にしたり、/etc/postfix/virtualで指定したアドレスにしたりして複数のパターンをテストしておきます。特にバーチャルドメインで指定した2個目以降のドメインについても忘れずにチェックしておきます。

外部へのメール送信確認

こちらも同様にmailコマンドでテストを行います。宛先のメールアドレスを自分のプロバイダのメールアドレスやGMailのアドレスにしてメールを送信してみます。

これで/var/log/syslogに次のようなログが出て、送信先にメールがちゃんと届いていればOKです。4行目でエラーが出ていますがどうもIPv6で接続しに行って失敗しているようです。すぐにIPv4に切り替えているのでとりあえず問題ないとしておきます。

May 30 17:15:09 ホスト名 Postfix/pickup[1444]: ABCDEFG: uid=送信元ユーザID from=< 送信元ユーザ名>
May 30 17:15:09 ホスト名 Postfix/cleanup[18531]: ABCDEFG: message-id=<20150530081509.ABCDEFG@送信元ドメイン名>
May 30 17:15:09 ホスト名 Postfix/qmgr[1443]: ABCDEFG: from=< 送信元ユーザ名@送信元ドメイン名>, size=373, nrcpt=1 (queue active)
May 30 17:15:09 ホスト名 Postfix/smtp[18533]: connect to gmail-smtp-in.l.google.com[2404:6800:4008:c01::1b]:25: Network is unreachable
May 30 17:15:12 ホスト名 Postfix/smtp[18533]: ABCDEFG: to=, relay=gmail-smtp-in.l.google.com[173.194.72.26]:25, delay=3.1, delays=0.02/0.01/0.69/2.4, dsn=2.0.0, status=sent (250 2.0.0 OK 1432973712 kd9si12039320pbc.109 - gsmtp)
May 30 17:15:12 ホスト名 Postfix/qmgr[1443]: ABCDEFG: removed

外部からの直接メール送信

このテストをするためにはWindows等のメールソフトで、このサーバを使ってメールを送信するようなアカウントを作成する必要があります。詳しい設定は省略しますが送信サーバの設定は次のようにしておきます。

  • サーバ名: Postfixを設定したサーバのホスト名(FQDN)
  • ポート番号: 465
  • 接続の保護: SSL/TLS
  • 認証方式: 通常のパスワード認証
  • ユーザ名: Postfixを設定したサーバ上に存在するアカウント
  • パスワード: ユーザ名に指定したアカウントのパスワード(メールソフトによっては初回送信時に入力する)

メールソフトがThunderbirdの場合は、「ツール」→「アカウント設定」→「送信(SMTP)サーバ(ウィンドウの左側一番下)」→「追加」で送信サーバの設定を作成して、テストで使用するアカウントでこのメールサーバを使用するようにしておきます。

テストメールを送信するときに次のような証明書の警告が出る可能性があります。これは証明書にSnakenailという怪しい証明書を使っているからです。特に気にしなくてもよいので承認をしておきます。

証明書の警告

そして、このサイトのアカウントやetc/Postfix/virtualで指定したメールアドレスにメールを送ってみます。これで/var/log/syslogに次のようなログが出て、送信先にメールがちゃんと届いていればOKです。

May 30 17:55:16 ホスト名 Postfix/smtps/smtpd[3374]: connect from テストしているPCのホスト名[テストしているPCのIPアドレス]
May 30 17:55:17 ホスト名 Postfix/smtps/smtpd[3374]: ABCDEFG: client=テストしているPCのホスト名[テストしているPCのIPアドレス], sasl_method=PLAIN, sasl_username=メールソフトで設定したアカウント
May 30 17:55:17 ホスト名 Postfix/cleanup[3379]: ABCDEFG: message-id=< メッセージID>
May 30 17:55:17 ホスト名 Postfix/qmgr[3109]: ABCDEFG: from=< 送信元のメールアドレス>, size=637, nrcpt=1 (queue active)
May 30 17:55:17 ホスト名 Postfix/local[3380]: ABCDEFG: to=< 送信先のメールアドレス>, relay=local, delay=0.06, delays=0.05/0/0/0, dsn=2.0.0, status=sent (delivered to maildir)
May 30 17:55:17 ホスト名 Postfix/qmgr[3109]: ABCDEFG: removed

外部から外部へのメールの送信

「外部からの直接メール送信」と同じ手順で宛先のメールアドレスをGmail等他のメールアドレスにしてみます。これで/var/log/syslogに次のようなログが出て、送信先にメールがちゃんと届いていればOKです。なお5行目のエラーはIPv6によるものなので無視しておきます。

May 30 18:09:01 ホスト名 Postfix/smtps/smtpd[9421]: connect from テストしているPCのホスト名[テストしているPCのIPアドレス]
May 30 18:09:02 ホスト名 Postfix/smtps/smtpd[9421]: 091527FC1C: client=テストしているPCのホスト名[テストしているPCのIPアドレス], sasl_method=PLAIN, sasl_username=メールソフトで設定したアカウント
May 30 18:09:02 ホスト名 Postfix/cleanup[9437]: 091527FC1C: message-id=< メッセージID>
May 30 18:09:02 ホスト名 Postfix/qmgr[3109]: 091527FC1C: from=< 送信元のメールアドレス>, size=645, nrcpt=1 (queue active)
May 30 18:09:02 ホスト名 Postfix/smtp[9438]: connect to gmail-smtp-in.l.google.com[2404:6800:4008:c01::1b]:25: Network is unreachable
May 30 18:09:02 ホスト名 Postfix/smtps/smtpd[9421]: disconnect from 139.151.156.59.ap.dti.ne.jp[59.156.151.139]
May 30 18:09:04 ホスト名 Postfix/smtp[9438]: 091527FC1C: to=< 送信先のメールアドレス>, relay=gmail-smtp-in.l.google.com[173.194.72.27]:25, delay=2.5, delays=0.04/0.01/0.82/1.7, dsn=2.0.0, status=sent (250 2.0.0 OK 1432976944 ms6si12244125pdb.76 - gsmtp)
May 30 18:09:04 ホスト名 Postfix/qmgr[3109]: 091527FC1C: removed

他のメールサーバからの送信

最後に他のメールサーバからメールを受け取れるかどうかを確認します。

これは普通にいつも使っているメールアドレスやGmailからこのホストのメールアドレス宛にメールを送信すればOKです。下記はGmailからメールを送信した例です。

May 30 18:22:57 ホスト名 Postfix/smtpd[15519]: connect from mail-wi0-f182.google.com[209.85.212.182]
May 30 18:22:58 ホスト名 Postfix/smtpd[15519]: E634C83454: client=mail-wi0-f182.google.com[209.85.212.182]
May 30 18:22:59 ホスト名 Postfix/cleanup[15539]: E634C83454: message-id=< メッセージID>
May 30 18:22:59 ホスト名 Postfix/qmgr[14564]: E634C83454: from=< 送信元のメールアドレス>, size=2569, nrcpt=1 (queue active)
May 30 18:22:59 ホスト名 Postfix/local[15540]: E634C83454: to=< 送信先のメールアドレス, relay=local, delay=0.51, delays=0.5/0.01/0/0, dsn=2.0.0, status=sent (delivered to maildir)
May 30 18:22:59 ホスト名 Postfix/qmgr[14564]: E634C83454: removed
May 30 18:22:59 ホスト名 Postfix/smtpd[15519]: disconnect from mail-wi0-f182.google.com[209.85.212.182]

不正中継のチェック

念のためSPAMメールの踏み台にされないように不正中継のチェックを行います。

これにはhttp://www.rbl.jp/svcheck.phpで行うのが簡単です。このURLにアクセスしてホスト名のところにメールサーバのホスト名かIPアドレスを入れて「Check」ボタンを押すだけでチェックしてくれます。

「no relays accepted」と表示されるのを確認しましょう。

まとめ

今回はPostfixを使ってメールの送信ができるようにしました。

結構長くなってしまいましたが、一つずつ何やっているのか理解しながら進めた方が、トラブルが発生したときに対応しやすいと思います。設定にミスがあるとSPAMの踏み台になったりするので慎重に進めましょう。

次回はメールを受信するためにDovecotを導入します。