2022/12/29(木)メールサーバの中規模改修と基礎知識(7)~ postfix

Postfix-logo.png

postfix は、sendmail の代替を目指す、電子メール送受信プログラムです。
記事公開日時点では、3.7.3 が最新バージョンです。

Postfix のインストール

機能説明等は不要と思いますので、早速インストール手順を示してみます。
インストール作業は、全て root ユーザで行います。
Postfix をインストールする場合、FreeBSD13 では、下記のモジュールが事前に必要です。(但し、2022/12/24 現在)
これらの多くは、Ports や Package でインストールしても、管理上特段問題にはなりません。
 ・perl5-5.36.0 	 (Ports から カテゴリ:lang)
 ・ca_root_nss-3.86	 (Ports から カテゴリ:security)
 ・autoconf-2.71	 (Ports から カテゴリ:devel)
 ・libltdl-2.4.7	 (Ports から カテゴリ:devel)
 ・libtool-2.4.7	 (Ports から カテゴリ:devel)
 ・pcre2-10.40		 (Ports から カテゴリ:devel)
 ・OpenLDAP 2.6.3 以上	 (これはソースコードからの構築を強く推奨)
 ・dovecot 2.3.19.1 以上 (本記事シリーズでソースコードから構築)
 ・gmake-4.3_2		 (Ports から カテゴリ:devel)
 ・icu-72.1,1		 (Ports から カテゴリ:devel)
上記をインストール出来ていたら、先ず、運用時における Postfix 自体が意図しているセキュリティポリシーに合わせるため、ここで専用のユーザを予めvipw や useradd コマンドで作っておきます。
vipw の場合は、編集画面で、下記の行を追加しておきます:
postfix::2000:2000::0:0:postfix:nonexistent:/usr/sbin/nologin
vipw でユーザ追加した場合は、/etc/group ファイルに下記の行を追加しておきます:
postdrop:*:65001:
更に、/etc/group ファイル内の該当行を下記のように変更しておきます:
mailuser:*:3000:opendkim,milter-manager,postfix
ユーザID、グループIDは、上記例にこだわる必要はありませんが、当然のことながら、ユーザID・グループIDが他と重複しないように注意です。
更に vipw でユーザ追加した場合は、つまらないセキュリティホールを作らないために、下記コマンドも一応実行しておきます:
# passwd postfix
今度は以下の手順に沿ってインストール作業を行います。Postfix のインストールは configure を使わない独特で且つ汎用的に対応できる形態になっています。
# cp postfix-3.7.3.tar.gz /usr/local/src	 
# cd /usr/local/src	 
# tar xvzf postfix-3.7.3.tar.gz	 
# cd postfix-3.7.3	 
 	 
# setenv CPPFLAGS '-I/usr/local/include -I/usr/include' 	(configure が上手くライブラリを探せないため)
# setenv LDFLAGS '-L/usr/local/lib -L/usr/lib'			(configure が上手くライブラリを探せないため)
# unsetenv LD_LIBRARY_PATH' 	 (3.7.x からは、LD_LIBRARY_PATH が設定されているとコンパイルを受け付けない)

※画面上では、説明のために改行していますが、 make の部分は、改行せずに、半角スペースで区切って、一気に入力。
# make -f Makefile.init makefiles 			 (OS等を自動識別してコンパイル)
 'CCARGS=-DHAS_LDAP -DUSE_TLS -DUSE_SASL_AUTH 		 (LDAP,SSL,SASL認証をサポートする指示)
     -DDEF_SASL_SERVER=\"dovecot\" 		 (dovecot SASL を使用する指示 ※2.3.x 以降で必須)
     -DDEF_COMMAND_DIR=\"/usr/local/sbin\" 	 (postfix 各種実行プログラムの格納ディレクトリ)
     -DDEF_CONFIG_DIR=\"/usr/local/etc/postfix\" 	 (postfix 各種設定ファイル格納ディレクトリ)
     -DDEF_DAEMON_DIR=\"/usr/local/libexec/postfix\" (postfix 各種デーモンプログラムの格納ディレクトリ)
     -I/usr/local/include	 
     -I/usr/include/openssl' 			 (openssl のヘッダファイル)
 'AUXLIBS=-L/usr/lib -lssl -lcrypto 			 (SSL ライブラリのある場所)
      -L/usr/local/lib -lldap -llber -licudata -licui18n -licuio -licutest -licutu -licuuc'
  							 (LDAP・icu ライブラリのある場所)
postfix の場合、いわゆる「メール送信」だけを行う Null Client な構成だと、上記 make コマンドに与えるパラメータが異なってくるのですが、今回は、普通のメールサーバの構築を行うため、提示のオプションになります。

続いて、
# make
で、エラーが出ないで終了したことを確認したら、
# make install
で、インストールを実施します。CUIインタフェースですが、対話形式のインストーラとなっています。
[ ] 内で示す文字列は、デフォルト値または、識別している値です。
変更しない場合は、そのままリターンキー押下、変更する場合に設定値を入力してリターンキー押下で次の項目に進みます。
※下記のように設問に対応する。(設問順序は、必ずしもこの順番にはなりません)
Please specify the prefix for installed file names. This is useful
if you are building ready-to-install packages for distribution to
other machines.
install_root: [/]

Please specify a directory for scratch files while installing
Postfix. You must have write permission in this directory.
tempdir: [/usr/local/src/postfix-3.7.3] /tmp

Please specify the destination directory for installed Postfix
configuration files.
config_directory: [/usr/local/etc/postfix]

Please specify the destination directory for installed Postfix
administrative commands. This directory should be in the command
search path of adminstrative users.
command_directory: [/usr/local/sbin]

Please specify the destination directory for installed Postfix
daemon programs. This directory should not be in the command search
path of any users.
daemon_directory: [/usr/local/libexec/postfix]

Please specify the final destination directory for Postfix-writable
data files such as caches or random numbers. This directory should
not be shared with non-Postfix software.
data_directory: [/var/lib/postfix] /var/tmp/postfix

Please specify the destination directory for the Postfix HTML files.
Specify "no" if you do not want to install these files.
html_directory: [no]

Please specify the owner of the Postfix queue. Specify an account
with numerical user ID and group ID values that are not used by any
other accounts on the system.
mail_owner: [postfix]

Please specify the full destination pathname for the installed
Postfix mailq command. This is the Sendmail-compatible mail queue
listing command.
mailq_path: [/usr/bin/mailq] /usr/local/libexec/postfix/mailq

Please specify the destination directory for the Postfix on-line
manual pages. You can no longer specify "no" here.
manpage_directory: [/usr/local/man]

Please specify the full destination pathname for the installed
Postfix newaliases command. This is the Sendmail-compatible command
to build alias databases for the Postfix local delivery agent.
newaliases_path: [/usr/bin/newaliases] /usr/local/libexec/postfix/newaliases

Please specify the destination directory for Postfix queues.
queue_directory: [/var/spool/postfix]

Please specify the destination directory for the Postfix README
files. Specify "no" if you do not want to install these files.
readme_directory: [no] /usr/local/etc/postfix/docs

Please specify the full destination pathname for the installed
Postfix sendmail command. This is the Sendmail-compatible mail
posting interface.
sendmail_path: [/usr/sbin/sendmail] /usr/local/libexec/postfix/sendmail

Please specify the group for mail submission and for queue management
commands. Specify a group name with a numerical group ID that is
not shared with other accounts, not even with the Postfix mail_owner
account. You can no longer specify "no" here.
setgid_group: [postdrop]

Please specify the final destination directory for Postfix
shared-library files.
shlib_directory: [no] 

Please specify the final destination directory for non-executable
files that are shared among multiple Postfix instances, such as
postfix-files, dynamicmaps.cf, as well as the multi-instance template
files main.cf.proto and master.cf.proto.
meta_directory: [/usr/local//etc/postfix] 
もし間違えたら、修正手段は容易されていないので、Ctrl+C で中断し再度
# make install
を行います。

次に、FreeBSD に特化した設定内容として、 /etc/mail/mailer.conf の設定変更を行います。
このファイルの内容を下記のように変更します:
# $FreeBSD: src/etc/mail/mailer.conf,v 1.3 2002/04/05 04:25:12 gshapiro Exp $
#
# Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail
#
sendmail    /usr/local/libexec/postfix/sendmail
send-mail    /usr/local/libexec/postfix/sendmail
mailq      /usr/local/libexec/postfix/sendmail
newaliases   /usr/local/libexec/postfix/sendmail
hoststat    /usr/local/libexec/postfix/sendmail
# purgestat   /usr/local/libexec/senamail/sendmail

Postfix の設定

○ サーバ証明書の取得とセットアップ
Let's Encrypt の certbot を使用する前提でここに手順を記述しています。
※ 操作するサーバ上で Webサーバが稼動している場合は、必ず一旦停止させること。
 
# certbot certonly --standalone --agree-tos -m user@example.com -d smtp.example.com
# certbot certonly --standalone --agree-tos -m user@example.com -d smtp.example.net
 
# cd /usr/local/etc/postfix
# vi tls_sni.map
tls_sni.map は、上記例をもとにすると、下記内容のように記述します:
※複数行の表示になっているが、
1ドメイン=1行で [対象ドメイン名] [秘密鍵ファイル名] [CA・公開鍵結合ファイル名] の順に、
半角スペースで区切って入力してください。
smtp.example.com /usr/local/etc/letsencrypt/live/smtp.example.com/privkey.pem /usr/local/etc/letsencrypt/live/smtp.example.com/fullchain.pem
smtp.example.net /usr/local/etc/letsencrypt/live/smtp.example.net/privkey.pem /usr/local/etc/letsencrypt/live/smtp.example.net/fullchain.pem 
tls_sni.map の編集を行ったら、
# postmap -F hash:/usr/local/etc/postfix/tls_sni.map
で、 Postfix で処理できるデータベース形式に変換しておきます(tls_sni.map.db が新たに生成されます)。

○ main.cf の設定変更
次に、/usr/local/etc/postfix/main.cf を下記の要領で編集します:
# cd /usr/local/etc/postfix
# cp main.cf main.cf.org
# vi main.cf
※ 最低限の変更部分のみ抜粋:
compatibility_level = 3.6                #挙動の設定
inet_protocols  = all                  #IPv4,IPv6 両方使用
inet_interfaces = all
unknown_address_reject_code = 550

tls_server_sni_maps = hash:/usr/local/etc/postfix/tls_sni.map     #TLS対象ホスト名
smtpd_tls_CApath = /etc/ssl/carts                   #接続相手先のCAルート証明書情報
smtpd_tls_chain_files =
 /usr/local/etc/letsencrypt/live/pmx1.admin-plus.net/privkey.pem,
 /usr/local/etc/letsencrypt/live/pmx1.admin-plus.net/fullchain.pem  #デフォルト適用の証明書情報

smtpd_tls_received_header = yes
smtpd_tls_session_cache_database = hash:/var/tmp/postfix/smtpd_scache #キャッシュデータベース
smtpd_tls_loglevel = 1                         #ログレベルの設定(必要に応じ 1 ~ 3 )
smtpd_tls_security_level = may                     #TLSサポートレベルの設定
smtpd_sasl_auth_enable = yes                      #SASL による SMTP-AUTHサポート
smtpd_sasl_type = dovecot                       #SASL認証機構の指定
smtpd_sasl_path = private/auth                     #SASL認証ソケットの指定

smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_relay_restrictions =
 permit_mynetworks,
 permit_sasl_authenticated,
 defer_unauth_destination
smtpd_recipient_restrictions =
 permit_mynetworks,
 permit_sasl_authenticated,
 reject_unauth_destination

smtp_tls_CApath = /etc/ssl/carts                    #接続クライアントのCAルート証明書情報
smtp_tls_session_cache_database = hash:/var/tmp/postfix/smtp_scache  #キャッシュデータベース
smtp_tls_security_level = may                     #TLSサポートレベルの設定
smtp_tls_loglevel = 1                         #ログレベルの設定(必要に応じ 1 ~ 3 )

milter_protocol = 6                          #milterプロトコルパージョンを6にする
milter_default_action = accept                     #milter接続失敗時のアクション
milter_mail_macros = {auth_author} {auth_type} {auth_authen}      #milter呼び出し時のパラメータ設定
smtpd_milters = unix:/var/run/milter-manager/milter-manager.sock    #SMTPD 時の milter 呼び出しアクション
non_smtpd_milters = unix:/var/run/milter-manager/milter-manager.sock  #SMTPD 以外の milter 呼び出しアクション

virtual_mailbox_maps = ldap:/usr/local/etc/postfix/ldap-mailbox.cf   #バーチャルユーザ情報
virtual_transport = dovecot                      #バーチャルユーザ配送 LDA指定
dovecot_destination_recipient_limit = 1                #同時配送数(複数メールの同時処理無し設定)
○ master.cf の設定変更
次に、/usr/local/etc/postfix/master.cf を下記の要領で編集します:
# cp master.cf master.cf.org
# vi master.cf
※ 最低限の変更部分のみ抜粋:
smtp    inet n  -  n  -   -  smtpd
smtps    inet n  -  n  -   -  smtpd
   -o smtpd_tls_wrappermode=yes
   -o smtpd_sasl_auth_enable=yes
   -o smtpd_sasl_type=dovecot
   -o smtpd_sasl_path=private/auth
   -o smtpd_sender_restrictions=reject_unknown_sender_domain
   -o smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
   -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
   -o smtpd_tls_security_level=may

submission inet n  -  n  -   -  smtpd
   -o smtpd_tls_wrappermode=yes
   -o smtpd_sasl_auth_enable=yes
   -o smtpd_sasl_type=dovecot
   -o smtpd_sasl_path=private/auth
   -o smtpd_sender_restrictions=reject_unknown_sender_domain
   -o smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
   -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
   -o smtpd_tls_security_level=may

tlsmgr   unix -  -  n  1000? 1  tlsmgr
dovecot   unix -  n  n  -   -  pipe
 flags=DRhu user=vmail argv=/usr/local/libexec/dovecot/deliver -f {$sender} -d ${recipient}
master.cf のこの設定で、smtp(port 25)、smtps(port 465)、submission(port 587) の待ち受けを可能にします。

最後に、aliases の設定をします。
# cd /etc/mail
# vi /etc/mail/aliases
aliases の該当行を下記のように変更しておきましょう:
root:	me@example.com
     ↓
root:	user@example.jp
要するに、実在し、受信できる電子メーるアドレスにします。
無断で他人のメールアドレスを記述したり、存在しないメールアドレスを記述してはいけません。
これを変更したら
# newaliases
として、データベースを更新しておきます。aliases.db が直近の時刻に変更されていることを ls -al コマンドなどで確認しておいてください。

Postfix の設定は以上です。