Postfix & Dovecot

MTAとしてPostfixを、IMAPサーバーとしてDovecotを利用します。(POPサーバーは使っていません。)
IMAP接続はローカル接続用にIMAP(143)と通常用のIMAPS(993)、他のメールサーバとのやりとり用にSMTP(25)、メールクライアントとの通信用にsubmission(587)のSTARTTLSに対応します。
パラメータや設定の詳細は、Postfixの公式ドキュメント(http://www.postfix.org/documentation.html)やDovecotの公式ドキュメント(http://wiki2.dovecot.org/)を読んでみるのがお勧めです。

※メールを送受信しないサーバーの場合の設定は、下の方に別途書いています。

インストール

  1. maildirを作成するコマンドがMaildropと一緒についてくるので、インストールだけは一緒に行います。(設定については別途記載します。)
    # apt install postfix postfix-doc maildrop dovecot-imapd
  2. メールサーバ設定形式は、「インターネットサイト」を選択します。
    ※さくらのVPSの場合は(無料お試し期間でなければ)OP25 blockが解除されています。
  3. メール名はデフォルトでサーバーのFQDNを入れてくれます。
    cronなど、システムの状態を自動的にメールで送信する場合などに指定されるドメイン名として使われます。

ユーザーディレクトリの作成

Postfixの設定に先立って、各ユーザーがメールを受け取るためのディレクトリを作成します。

  1. パーミッションの問題もあるので、それぞれのユーザーでログインしてhomeにディレクトリを作成してください。
    $ maildirmake ~/Maildir
  2. なお、新しく作るユーザー向けのスケルトンを修正しておくことで、新規ユーザー作成時は自動的にMaildirが作成されるようにします。
    # maildirmake /etc/skel/Maildir

デフォルトでは/var/mailにメールが保存されるのですが、これでMaildir形式にする準備ができました。
なお、通常現段階では/var/mailには何もファイルはないはずですが、もし何らかの理由ですでにメールが届けられてしまっている場合は、mb2mdをインストールして既存のメールをMaildirに変換してください。

aliasesの設定

Postfixのインストール時にaliasの設定が足りないという警告が出ているので、まずはそれを設定します。

  1. /etc/aliasesを編集し、root宛のメールを、通常利用するユーザーへ転送します。
    # See man 5 aliases for format
    admin:         root
    mailer-daemon: root
    postmaster:    root
    webmaster:     root
    root:          xxx
    最初からpostmasterだけは入っていたので、それ以外に必要になりそうなものを追加し、root宛のメールはまとめて通常利用するユーザーに転送しました。
  2. aliasを修正したら、有効化が必要です。
    # newaliases

Dovecotの設定

通常のIMAP(143)でSTARTTLSを使うか、もしくはIMAPS(995)を使うように設定します。また、メールボックスの種類と場所も指定します。
※ログイン方法の設定などは触っていませんが、デフォルト設定がセキュリティ強化側になっているので、そのままにしています。

  1. /etc/dovecot/conf.d/10-ssl.confで、sslを有効化します。
    # SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
    #ssl = no
    ssl = yes
    
    # PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
    # dropping root privileges, so keep the key file unreadable by anyone but
    # root. Included doc/mkcert.sh can be used to easily generate self-signed
    # certificate, just make sure to update the domains in dovecot-openssl.cnf
    ssl_cert = </etc/ssl/certs/ssl-cert-snakeoil.pem
    ssl_key = </etc/ssl/private/ssl-cert-snakeoil.key
  2. /etc/dovecot/conf.d/10-mail.confで、Maildir形式を指定します。
    # See doc/wiki/Variables.txt for full list. Some examples:
    #
    #   mail_location = maildir:~/Maildir
    #   mail_location = mbox:~/mail:INBOX=/var/mail/%u
    #   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
    #
    # <doc/wiki/MailLocation.txt>
    #
    mail_location = maildir:~/Maildir
  3. 設定反映のため、Dovecotを再起動します。
    # service dovecot restart

Dovecotは、doveadmというコマンドでメールボックスやメールの操作ができます。「一定の時期より前に受け取ったメール」などをまとめて処理ができるようになるので、cronでメールを操作したい場合などに便利です。
詳細はDovecot Wikiを参照してください。

Postfixの設定

Postfixの設定ファイルは主に/etc/postfix/main.cfになります。また、/etc/postfix/master.cfというファイルもありますが、こちらはPostfixのインタフェース設定になります。
設定を誤ってスパマーの踏み台になってしまわないようご注意ください。

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

上記のaliasesはあくまでユーザー名しか定義していません。そのため、例えばこのサーバーがexample.jpとexample.comの両方のメールを扱おうとすると、user1@example.jpとuser1@example.comのアドレスが同一人物のものとして同じメールボックスに配送されてしまいます。
今回は、メールアドレス単位で転送設定を行えるバーチャルドメインを利用します。

  1. /etc/postfix/main.cfを編集します。
    # See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
    # information on enabling SSL in the smtp client.
    
    smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
    myhostname = mail.example.jp
    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases
    myorigin = /etc/mailname
    mydestination = $myhostname, localhost
    virtual_alias_domains = example.jp, aaa.example.jp, bbb.example.jp, example.com
    virtual_alias_maps = texthash:/etc/postfix/virtual_users
    relayhost =
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    mailbox_size_limit = 0
    recipient_delimiter = +
    inet_interfaces = all
    inet_protocols = all
    # allow_min_user = yes
    html_directory = /usr/share/doc/postfix/html
    home_mailbox = Maildir/
  2. virtual_alias_mapsの設定をします。これは、単純に「user1@aaa.example.jpに来たメールは user1@mail.example.jpに転送する」という設定を書いていくだけです。この時、転送先のメールアドレスはmydestination に定義したドメインのものになります。
    admin@example.jp           xxx@mail.example.jp
    info@example.jp            xxx@mail.example.jp
    postmaster@example.com     xxx@mail.example.jp
    例えば、上記の場合定義された3つのアドレスはすべて同一のユーザーに送付されることを意味します。また、空白行は無視されます。
    なお、通常はhashを指定しているためこの後db化が必要ですが、私の場合設定するメールアドレスは大した数でもないのでtexthashを指定してプレーンテキストをそのまま読むようにしています。
  3. Postfixに設定を反映します。
    # service postfix reload

SASL(SMTP認証)設定

今の所、mynetworksにある範囲(要するにlocalhost)からしか外部へのメール送信は受け付けない設定になっています。これを、SMTP認証を通った場合は送信可能にします。なお、パスワードが平文で流れるのを防止するため、SASL認証はtlsの場合のみ利用可能とします。
設定はdovecotのサイトの説明を参考にしています:http://wiki2.dovecot.org/HowTo/PostfixAndDovecotSASL

  1. /etc/dovecot/conf.d/10-master.confの該当部分がコメントアウトされているので有効化します。
      # Postfix smtp-auth
      unix_listener /var/spool/postfix/private/auth {
        mode = 0666
      }
  2. /etc/postfix/main.cfにDovecotのSASLを使用するための設定を追加します。
    # SASL
    smtpd_sasl_type = dovecot
    smtpd_sasl_path = private/auth
    smtpd_sasl_auth_enable = yes
    smtpd_tls_auth_only = yes
    
    設定後は、Postfixを再起動して該当のソケットを作ります。
  3. 自分のメーラーなどから接続テストを行い、STARTTLS後のSMTP認証のみメールが送信できれば成功です。
    しかし、たいがいのプロバイダだとOP25Bの制限に引っかかってテストできないでしょうから、telnetにて通常のSMTPのままの場合には認証できないかどうか確認だけすることになるでしょう。
    $ telnet localhost 25
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    220 mail.example.jp ESMTP Postfix (Debian/GNU)
    ehlo localhost ←これは自分で入力
    250-mail.example.jp
    250-PIPELINING
    250-SIZE 10240000
    250-VRFY
    250-ETRN
    250-STARTTLS
    250-ENHANCEDSTATUSCODES
    250-8BITMIME
    250 DSN
    quit ←これは自分で入力
    このように、250-AUTH...というのが含まれている行がないことを確認してください。設定が終わっていれば、submission(ポート587)でも同様になるはずです。

submission port(587)の設定

ほとんどのプロバイダはOP25B(Outbound Port 25 Blocking)を設定しているため、今のままではそもそもSMTPに接続できません。そのため、submission port(587)を使います。
以前はSMTPS(465)もあったのですが、これは今となっては(まだまだ使われていますが)廃止のため有効化はしません。

  1. /etc/postfix/master.cfを修正して、submissionポートを開きます。
    # ==========================================================================
    # service type  private unpriv  chroot  wakeup  maxproc command + args
    #               (yes)   (yes)   (yes)   (never) (100)
    # ==========================================================================
    (中略)
    submission inet n       -       y       -       -       smtpd
      -o syslog_name=postfix/submission
      -o smtpd_tls_security_level=encrypt
      -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
    smtpd_tls_security_level=encryptとsmtpd_sasl_auth_enable=yesはここに書かなくても見た目 の動きは同じになるのですが、設定ファイルを見た時にどうなっているのか後でわかりにくくなるので明示的に入れています。
  2. Postfixに設定を反映します。
    # service postfix restart
  3. submission+STARTTLSでのメール送信をテストします。
  4. すでに正式なサーバー証明書を入手している場合は、/etc/postfix/main.cfの該当部分を修正してください。
    # TLS parameters
    smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
    smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
    smtpd_use_tls=yes
    smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
    smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

メールを使わないサーバー

特にメールサーバーにするつもりはなくても、cronやその他諸々のシステムからローカルで配送されてくるメールはあります。しかし、サーバーが複数台あっ た場合、1台ずつアクセスして確認するのは面倒なので、全てのメールをメインをメールサーバー(自分のメールボックスがあるサーバー)へ送るよう設定します。

  1. インストールは通常通りです。
    # apt install postfix postfix-doc
  2. メールサーバ設定形式は、「サテライトシステム」を選択します。
  3. メール名はデフォルトでサーバーのFQDNを入れてくれます。ここをlocalhostなどにしてしまわないように注意してください。
  4. リレーホストのアドレスは、普段使っているメールサーバーのアドレスを入力してください。この際、サーバー名はDNSのMXに指定しているサーバー名 を指定するか、[]でくくってMXでなくAレコードを引くように指定してください。
  5. /etc/postfix/main.cfで、mydestinationを空欄にします。これで、自分が受け取るべきメールはなく、全て relayhostに転送するようになります。
    myhostname = nomail.example.net
    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases
    myorigin = /etc/mailname
    mydestination =
    relayhost = relay.example.net
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    mailbox_size_limit = 0
    recipient_delimiter = +
    inet_interfaces = loopback-only
  6. relayhostに指定された側でも/etc/postfix/main.cfを修正します。
    転送されてきたメールはmydestinationではなくvirtual_aliasのほうで受け取るようにします。また、全メールを転送するよう指定 したサーバーのIPアドレスをmynetworksに追加します。
    myhostname = relay.example.net
    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases
    myorigin = /etc/mailname
    mydestination = relay.example.net, localhost
    virtual_alias_domains = example.net, nomail.example.net
    virtual_alias_maps = hash:/etc/postfix/virtual_users
    relayhost =
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.0.2.4
  7. virtual_alias_mapsに、以下のcatch-all指定を追加し、そのドメイン名の全メールを受け取るようにします。
    こうすることで、root宛のメールだろうがpostmaster宛のメールだろうがユーザー名を管理することなく受け取れます。
    @nomail.example.net usual@relay.example.net
    catch-allはuser-unknownで返すべきSPAMまで受け取ってしまうのであまり使いませんが、そもそもこのドメインはDNSでもMXを 指定しないので、外部からメールが届くことはありません。もし、何らかの理由でメールが外部から届くことを想定している場合は、適宜別の方法を使ってくだ さい。

以上でシステムからrootなどに送られるメールも全て転送され、普段使っているメールボックスに届くようになります。
なお、ここでは転送元のIPをmynetworksに加えることで対応していますが、逆に転送元が転送先へアクセスする際、SMTP-AUTHを使うように設定することも可能です。


目次へ戻る