postfixをちゃんと理解したい
過去の記事でdovecotやroundcubeの設定をフリーOSのDebianにしたので、なんとなくpostfixについても確認しておいた方がよさそうだということで、postfixの基本的な設定から、SASLを使ったPAM経由のSMTP認証、メールリレーの設定までを覚書として記しています。
まずはインストールです。インストール途中でどの機能としてインストールするか聞いてきますが、ここでは「設定なし」を選びました。
$ su ... # apt update ... # apt install postfix ...
初期設定
いつだったか筆者がpostfixの設定が必要になった際、一番最初に設定するmyorigin、mydomain、myhostnameの区別がつかず、もうこのアプリは「わからない」でいいやと、サンプル設定をうのみにしてしまいました。それが原因でいまもわからないままなので、それらを含めて初期設定で必要な項目をここでいったん整理します。
postfixの設定は筆者の環境(Debian10.4)では、/etc/postfix/main.cfにありります。インストール時の選択により存在しない場合もあります。その際は/usr/share/postfix/main.cf.distか、/etc/postfix/main.cf.protoからコピーして作成することになります。
稼働させるには次の項目の設定が必要です。
- mail_owner
postfixデーモンを起動するユーザーとなります。通常はpostfixを設定すればいいです。
- myhostname
ホスト名、すなわちpostfixがインストールされているサーバーの名前です。ホスト名+ドメインとなるのが一般的です(host.sample.jp等)
- mydomain
ローカルに設定してあるドメイン名です(sample.jp等)。
- myorigin
外部に公表するメールドメインです。このドメインを使ってメールは送信されます。$mydomainとして、先に設定したmydomainと同値をセットするのが一般的です。
- inet_interfaces
メールを受け付けるネットワークインターフェースを指定します。ここでは特に制限しないのでallを指定します。
- mydestination
SMTPサーバーはメールを受け取った際、それが自分で管理するドメインなら内部に送信(保存)し、そうでなければ転送します。
SMTPサーバーであるpostfixはmydestinationに設定したドメインとメールの宛先を照合することで、保存するか転送するかを決めます。
「=$mydomain」としておけばいいですが、自分宛にメールが送られた際の時のために、「$myhostname, localhost.$mydomain, localhost」も設定しておきます。
この設定は,(半角コンマ)で区切ることで複数設定が可能です。
- local_recipient_maps
登録のないユーザーへのメール受信を拒否する設定です。今回は設定しません。すべてのユーザーを受け付ける場合は空白にしておきます。
- mynetworks_style
メールの送信を受け付ける範囲の設定方法を指定します。「subnet」を指定するとサブネット単位で依頼を受け付けます。次のmynetworksで詳細を記載します。
- mynetworks
メールの送信を受け付けるネットワークを設定する項目です。
「127.0.0.0/8」としてローカルホストを設定したり、「192.168.1.0/24」を設定してローカルネットワークを設定したりすることができます。
また、「192.168.1.18/32」と、サブネットマスク値を32にすることでホストを指定することもできます。
この設定は,(半角コンマ)で区切ることで複数設定が可能です。
- relay_domains
postfixがmynetworks(_sytle)で設定された範囲以外からメールを受け取った場合に、転送を許可するドメインを設定します。デフォルト値は$mydestinationとなっています。これは外部からくるメールは自分の管理するアドレスのみ受け取るという設定になります。これを空白にすると、外部からのメールは受信できません(メールはローカル間のみとなります)。他、ドメインを指定して転送を許可することもできます。
この設定は,(半角コンマ)で区切ることで複数設定が可能です。
- alias_map
メール用のアカウントとdebianのローカルユーザーを結びつけるデータを「データ形式:場所」形で指定します。hash:/etc/aliasesとします。
- alias_database
alias_mapデータベースを出力するコマンド(newaliases)を実行した際に出力する形式と場所を指定します。特に意図した管理をしないならalias_mapと同値でいいと思います。
- home_mailbox
サーバー管轄のメールの保存場所を設定します。ユーザーのhomeディレクトリにある、指定したファイルまたはディレクトリに保存されます。ファイルを指定した場合はmbox形式、ディレクトリを指定した場合(最後に/を入れる)は、Maildir形式で保存されます。
例えば「sample/mdir/」とした場合、/home/[ユーザー名]/sample/mdirにMaildir形式でメールが保存されます。Maildir形式の保存にはnew、cur、tmpサブディレクトリが必要です。
ユーザーホームとは関係のない場所に保存したい場合はこちらではなくmail_spool_directoryの項目に記述します。
- smtpd_banner
サーバーにアクセスしてきた際に表示するメッセージです。ここに表示される値にSMTPアプリ名や、バージョンを入れると、悪意のあるユーザーへ脆弱性発見の為の手がかりを与えてしまいます。なので「ESMTP」等、簡潔なメッセージにします。
- sendmail_path
メール送信時に使うコマンドを指定します。/usr/sbin/postfixが一般的です。ちなみにここにsendmailへのパスを入れることも可能です。
- newaliases_path
前述のalias_mapを作成する際のコマンドです。/usr/bin/newaliasesが一般的です。どこにあるか不明な場合は「find / -name newaliases」で検索してみましょう。
- mailq_path
メールキューの表示コマンドであるmailqへのパスを指定します。/usr/bin/mailqが一般的です。
- setgid_group
postfixディレクトリを所有するグループです。デフォルト値はpostdropです。値を変更した場合は「post-install set-permissions」を実行してください。
- html_directory
ドキュメントページの指定です。コメントアウトします。
- manpage_directory
ドキュメントページの指定です。コメントアウトします。
- sample_directory
ドキュメントページの指定です。コメントアウトします。
- readme_directory
ドキュメントページの指定です。コメントアウトします。
- inet_protocols
postfixを稼働させるIPのプロトコルです。デフォルトでは「IPv4」が設定されています。
各設定で、hash:から始まるファイルへパスがありましたが、これは、hash形式のデータベースファイルが使われていることをpostfixに明示するものです。
hashの他にもbtreeやmysql(postfix-mysqlのインストールが必要です)などが指定できます。mysqlとした場合、検索値を、MySQLデータベースから検索するようになり、その際ファイルパスが示すファイルはMySQLへの接続設定や検索のためのクエリが書き込まれたものになります。
どの場合も基本的には、postfixから渡されたキーに対して、適切な値を返す構造となっています。
テスト稼働
main.cfを作成し、設定したらpostfixを再起動させます。newaliasesコマンドも一度実行しておきましょう。データベースに名前のエントリーがなくても、OSに登録されているユーザー名にはメールが届きますが、データベース自体がないとエラーになり配信できません(キューには残ります)。
$ su ... # systemctl restart postfix
無事起動できたらテストメールを送ってみます。
合わせて別のPCからメールを送ることもできるか試してみましょう。WindowsのコマンドラインやTera term等からtelnetで設定したサーバーの25番ポートに接続します。
ちなみにTera termで23番以外のポート番号でTelnetを使用するには「Setup」「Terminal」から、「Local echo」にチェックを入れ、「New-Line(改行コード)」を「CR+LF」にします。
220 ESMTP ※ HELO test@sample.domain.jp 250 mailsv.sample.domain.jp ※ MAIL FROM: <sender@sample.domain.jp> 250 2.1.0 Ok ※ RCPT TO: <receiver@sample.domain.jp> 250 2.1.5 Ok ※ DATA 354 End data with <CR><LF>.<CR><LF> ※ メールの本文を入力します .(半角ピリオド)のみで行を変えると メッセージの終わりとみなされます。 Hello! receiver. This is test message. . 250 2.0.0 Ok: queued as 13B3A7799AB ※ QUIT
※はサーバーからのレスポンスメッセージです。
SMTPにおけるユーザー認証
SMTPサーバーの仕様はセキュリティリスクが低かった時代につくられたもので、デフォルトではユーザー認証をしません。
pofstfixではCyrus SASLライブラリと連携することによりSMTP認証を実現しています。このライブラリでは単独でユーザー名やパスワードを設定・管理できますがdovecotの設定ではPAM認証を使っていたので、この記事ではpostfixもそれに合わせます。
SASLライブラリからPAMを指定する形になりますのでまずライブラリのインストールをします。
設定をしていきます。設定はわすれないうちにメモしよう:debian postfix + dovecot + sasl(PAM)のページを参考にさせていただきました。ありがとうございます。
またDebianのPAM認証については別に記事がございますので合わせて読んでいただければ幸いです。
まず、postfixのmain.cfに次の項目を加えます。
- smtpd_sasl_auth_enable
「smtpd_sasl_auth_enable=yes」とすることで、SMTP認証を有効にさせます。
- smtpd_sasl_security_options
「smtpd_sasl_security_options = noanonymous」とすることで匿名のログインを禁止します。
- smtpd_recipient_restrictions
「smtpd_recipient_restrictions=」以降アクセス制限リストを,で区切って設定します。左から右へ順に判定していきます。次のように記述しておきます。
- permit_mynetworks
自分の管轄あてのメールなら許可
- permit_sasl_authenticated
saslで認証されたユーザーならどこ宛てのメールでも許可
- reject_unauth_destination
宛先が$relay_domains などのリストに含まれていなかったら拒否します。詳しくはpostfixのドキュメントを参照してください
- permit_mynetworks
- smtpd_sasl_local_domain
sasl認証の際のレムル名です。「=$myhostname」としないと認証時にエラーになるようです。
- smtpd_sasl_application_name
デフォルトで「smtpd」となっています。変更した場合は次で設定するファイルsmtpd.confの名前も変える必要があります。
saslの認証方法を設定します。/etc/postfix/sasl/smtpd.confというファイルを作成して次のように記述します。
pwcheck_method: saslauthd mech_list: plain login
salsauthdを使った、plainもしくはlogin認証としています。
次にsaslの設定に移ります。/etc/default/saslauthdの次の記述を確認します。
- START
システム起動時に、saslを起動させるかの設定ですので「yes」とします。
- MECHANISMS
sasldb(sasl独自のデータベースで認証)等になっていたら、pamに変更します。
- OPTIONS
chroot環境では「-c -m /var/spool/postfix/var/run/saslauthd」そうでない場合は「-c -m /var/run/saslauthd」を指定するようにと記述されています。
chrootはセキュリティのための技術で、指定したディレクトリをルートディレクトリとし、それより上にはアクセスできないようにする仕組みです。postfixでは/etc/postfix/master.cfでchrootの有無を設定できます。何も変更していなければ、おそらく/var/spool/postfixをルートにするchroot環境になっています。
chroot環境ではデフォルトでディレクトリが存在しませんので/var/spool/postfix/var/run/を作成します。
postfixを稼働させるユーザー(ここではpostfix)をsaslグループに加えます。
PAM認証にsmtpを加えます。これはdovecotと同期させるためにシンボリックリンクにします。PAM認証で用いられる名称はsmtpdでなく、smtpです。
# cd /etc/pam.d/ # ln -s dovecot smtp
この状態でpostfixとsaslauthdを再起動します。
再びtelnetでアクセスしてみます。
認証時は文字の送受信がBase64エンコードに代わります。テストをする際、ユーザー名とパスワードをBase64エンコードするには下のツールをご利用ください。
Base64エンコードツール
220 ESMTP ※ EHLO test@sample.domain.jp 250 mailsv.sample.domain.jp ※ EHLOとするとサーバーの拡張機能が列挙されます... ... AUTH LOGIN ここ以降文字はBase64エンコードになります 334 VXNlcm5hbWU6 ※ Base64形式でユーザー名を入力 334 UGFzc3dvcmQ6 ※ Base64形式でパスワードを入力 以降文字のエンコードは元に戻ります。 ...
※はサーバーからのレスポンスメッセージです。
メールリレー設定
SMTPサーバーは通常、宛先アドレスのドメイン名から宛先を自ら解決して、そのドメインを管理するSMTPサーバーにメールを届けます。
しかし、セキュリティが強化されている近代のインターネットでは正体不明なSMTPサーバーからのメールを受け付けてくれるSMTPサーバーは少ないです。
そこで自サーバーの身元を知っているプロバイダのメールサーバー等に再転送を依頼するのが常となります。今度はその設定をしていきます。
先のmain.cfの設定に次の項目を付け加えます。maruko2 Note.:Postfix でメールリレーの設定 (SMTP クライアント + SMTP Auth)を参考にさせていただきました。ありがとうございます。
- relayhost
ここに転送先のメールサーバーのアドレスを記載すると、そこへメールを転送するようになります。この時アドレスを[]で囲むとDNSのMX検索を行いません。なので宛先のメールサーバーのアドレスが判明している場合には[]で囲みます。
たとえばgmailのSMTPに587番ポートを使って転送する場合は「[smtp.gmail.com]:587」といった形で記入します。
- smtp_sasl_auth_enable
先にはsmtpd_sasl_auth_enableを設定しましたが、この設定では"d"はつきません。
これをyesにすることで転送先との間でSMTP認証をします。
- smtp_sasl_password_maps
転送先との間で認証に使うユーザー名とパスワードを設定するファイルと、そのファイル形式を指定します。先のalias_mapと記述方式はやテキストデータからの変換をしないといけないところまでは一緒ですが、変換の際のコマンドが変わります。
設定の記述は
smtp_sasl_password_maps=hash:/etc/postfix/sample_map
という風になります。
また外部に用意するmapファイルの記述形式は次のようになります。
[smtp.gmail.com]:587 user@gmail.com:password記述の後、「/sbin/postmap /etc/postfix/sample_map」として変換します。
この変換は、postfixにテーブルの新設や更新を伝えて新にマップを作るために行われます。このコマンドを実行するとファイル名の後ろに.dbがついたファイル(ここではsample_map.db)が作成され、プログラムではこのファイルの中身が用いられます。
ちなみに、postmapは hash:/path/to/file という形式で引き数を与えることで変換形式を指定する事ができます。他には巨大なデータに適したbtreeを指定できたりします。省略した時はデフォルトとして指定してある形式となりますが、これはpostconf -d で出力されるリスト内の default_database_type の項目で確認できます。
- smtp_sasl_security_options
「noanonymous」を付け匿名でのログインを禁止します
- smtp_tls_security_level
「 may 」を指定することで、サーバー側がTLSに対応していたらそれを利用します。デフォルト値は may でしたが、 近年のセキュリティ水準を考慮すると「 encrypt 」(TLS非対応ならエラーとする) にした方がいいかもしれません。少なくとも暗号化対応のサーバーに平文で接続されていないかのチェックは必要だと思います。筆者の失敗例を挙げると、証明書の設定ミスのせいでずっと平文接続ををしていました。
- smtp_tls_CAfile
TLS接続の際に利用される転送先サーバーのCA証明書のパスを設定します。GoogleだとGlobalSignのものになると思います。
- smtp_tls_CApath
通常は、先のCAfileではなく、CApathの方が設定されていると思います。こちらは証明書ディレクトリを指定する方法です。
Debianでは/etc/ssl/certs ディレクトリの中に証明書が入っています。もしこの中に証明書が無かったら、追加する必要があります。ここに直接証明書を入れることも可能ですが、システムが自動で管理するディレクトリとなっているので、通常は /usr/local/share/ca-certificates/ に証明書を配置して、update-ca-certificatesコマンドを実行して、/etc/ssl/certsディレクトリへ反映させます。
ちなみに転送設定の時もローカルのSMTP認証は有効にできます。
その他
その他のpostfixにおいて使うことがあるだろう設定やコマンドを最後に書いておきます。
- ログレベルの調整
postfix は全体を通してのログレベルの調整項目がないようです。デバッグログの出力時は対象の接続元を指定する必要があります。そのための main.cf のエントリーは debug_peer_listとなります。これにネットワークを指定することで、全体を対象とすることもできます(例: debug_peer_list=192.168.1.0/24)。また、ログの粒度は debug_peer_level で数値でセットします。通常は0で、大きくなるほど明細化されます。
- /sbin/postqueue -p
メールキューを確認するコマンドです。
- /sbin/postsuper -d
メールキューを削除するコマンドです。-dのあとにpostqueueで確認したIDを指定するか、ALLで全件の削除になります。
- メール送受信時の最大サイズ
postfixのmain.confで「message_size_limit」にバイト単位でサイズを入れることで送受信時のメール最大サイズを指定できます。また同様の指定で「mailbox_size_limit」に値を設けるとメールボックスの最大サイズを指定できます。
- ユーザー名を検索されるのを防ぐ
postfixのmain.confでdisable_vrfy_commandにyesを設定することでユーザー名の検索されるのを防ぐことができます。対外的なサーバーの場合は設定しておきましょう。