#author("2020-04-14T17:28:20+09:00","default:narushima","narushima")
#author("2020-04-16T13:04:52+09:00","default:narushima","narushima")
#contents

*Postfixとは [#mf23c98a]

**インストール [#fe59f1d0]


***yumから [#q48cc765]
 # yum install postfix
※バージョンがかなり古いのでおすすめしない。

***ソースコードから [#web09809]

ソースからのコンパイルの場合、Barkrey-DB のヘッダーファイルの位置がエラーになる場合がある。そこでリンクを1つ作っておく。

 # yum install compat-db
 # ln -s /usr/include/db4.7.25 /usr/include/db
 # ln -s /usr/lib64/db4.7.25 /usr/lib64/db

 # wget http://mirror.postfix.jp/postfix-release/official/postfix-2.11.3.tar.gz
 # tar zxvf postfix-2.11.3.tar.gz
 # cd postfix-2.11.3

コンパイルの前にコンパイルコマンドを作成しておくと良い。

 # touch compile.sh
 # chmod +x compile.sh
 # vi compile.sh
   #!/bin/sh
   make -f Makefile.init makefiles \
   CCARGS='-DHAS_MYSQL \
   -I/usr/local/mysql/include \
   -DDEF_CONFIG_DIR=\"/usr/local/postfix/etc\" \
   -DDEF_COMMAND_DIR=\"/usr/local/postfix/sbin\" \
   -DDEF_DAEMON_DIR=\"/usr/local/postfix/libexec\" \
   -DDEF_MAILQ_PATH=\"/usr/local/postfix/mailq\" \
   -DDEF_HTML_DIR=\"/usr/local/postfix/html\" \
   -DDEF_MANPAGE_DIR=\"/usr/local/man\" \
   -DDEF_NEWALIAS_PATH=\"/usr/local/postfix/newaliases\" \
   -DDEF_QUEUE_DIR=\"/usr/local/postfix/spool\" \
   -DDEF_README_DIR=\"/usr/local/postfix/readme\" \
   -DDEF_SENDMAIL_PATH=\"/usr/local/postfix/sbin/sendmail\" \
   ' \
   AUXLIBS='-L/usr/local/mysql/lib -L/usr/lib64/db -lmysqlclient -lz -lm'

その後コンパイル。

 # ./compile.sh
 # make
 # make install

この際に、data_dir のみ /usr/local/postfix/data に変更。それ以外はリターンのみでOK.

***デーモンユーザーの作成 [#p9e3c796]

存在しない場合のみ。

 # cd /usr/local/postfix
 # mkdir home
 # groupadd postfix
 # groupadd postdrop
 # useradd  -g postfix -d /usr/local/postfix/home -s /bin/true postfix
 # chown postfix:postfix /usr/local/postfix/home

*設定 [#qb639994]
Postfixではバーチャルユーザーという形で、OSのユーザーに依存しないかたちで、自由にメールアドレスの追加を行うことが出来る。

**データベース利用時の設定 [#a1f8c05c]
postfix では、mysqlなどのDBを利用したメール管理が可能。インストールされた postfix が、どのようなDBを使えるかは、以下のコマンドで確認できる。
 # postconf -m

**main.cfの設定 [#w2522cfc]


|項目名|初期値|概要|h
|soft_bounce|no|yesにすると、恒久的なエラーが一時的なエラーとして扱われる。この場合、宛先が無い場合、送り元のサーバーが何度も再送をするため、スパムが大量に送られた場合、大変な事になる。|
|queue_directory|/var/spool/postfix|postfixがメールを送信する場合など、非同期で行われる際に一時的にメールを保存し管理するフォルダを指す。postfixがchroot起動すると、ここも相対的に移動してしまうので注意が必要|
|command_directory|/usr/sbin|postfix関連のコマンドが保存されているフォルダを指定する。yumなどでインストールされている場合は、変更の必要は無い|
|daemon_directory|/usr/libexec/postfix|postfixデーモン本体のフォルダ位置。yum インストールなどの場合、変更の必要は無い|
|data_directory|/var/lib/postfix|ここは、postfixがメール管理に利用する管理用のデータ領域のフォルダを指す。主にキャッシュファイルや番号管理ファイルなどに利用される。変更の必要は無し|
|mail_owner|postfix|postfixが作成する管理用のキューやデータ、プロセスのユーザーなどを指定する。通常 yum などでインストールされると、自動的にOSに postfix というユーザーが作成されるので、特に変更の必要はない|
|default_privs|nobody|受け取るユーザーが無い場合の、初期ユーザーを指定する。これは設定によっては、プログラムの起動が伴う設定などが存在するため、nobody以外の指定はまず行わない。特に管理者権限やpostfixユーザーなどの設定は絶対に行わないこと|
|myhostname|virtual.domain.tld|postfixで管理するホスト名を指定する。ここは自分の環境に合わせて変更する。|
|mydomain|domain.tld|postfixで管理するドメイン名を指定する。ここは自分の環境に合わせて変更する。|
|myorigin|$mydomain|ローカルで送信されたメールがどのドメインから来るように見えるかを指定する。この$mydomainは、上記の mydomain 設定を引用していることを意味する。|
|inet_interfaces|localhost|メールが受け取れるサーバー範囲の指定。ここは外部からのメールを受け取るサーバーの場合、all を指定する|
|inet_protocols|all|メールが受け取れるプロトコルの指定。ここはIPv4のみの受信の場合、IPv4 を指定できる(IPv4, IPv6が指定可能)。但し基本的には ipv4 が良い。|
|proxy_interfaces||inet_interfacesの設定の拡張指定。通常は指定する必要はない。|
|mydestination|$myhostname, localhost.$mydomain, localhost, $mydomain|このマシンが自分自身が最終目的地だとみなすドメインのリストを指定する。 バーチャルドメインの名前を指定してはならない。よって通常変更の必要は無し。|
|local_recipient_maps||このパラメータが定義されていると、存在しないローカルユーザ宛のメールを拒否する。特に設定の必要は無し|
|unknown_local_recipient_reject_code|550|存在しないローカルユーザ宛のメールの場合のコード。500番台は恒久的エラー|
|mynetworks_style||リレー出来る信頼するsmtpクライアントを指定する。指定がない場合、postfixが自動的に判断する|
|mynetworks||上記のIP設定版。こちらが設定されていると、mynetworks_styleの設定は無視される。通常中継させるサーバーを設定する機会が無いと思うので、基本は 127.0.0.0/8 を指定して、事実上の中継は無しに設定する。|
|relay_domains|$mydestination|どの目的地にメールを中継するかを制限します。通常中継設定しなければ、設定の必要無し|
|relayhost||これも配送に関する設定のため、設定の必要無し|
|relay_recipient_maps||指定されたリレーユーザー以外は拒否される。例:hash:/etc/postfix/relay_recipients。但しリレーしなければ意味なし|
|in_flow_delay|1s|メッセージ到着速度が配送速度を越えた時、指定秒停止。設定の必要無し|
|alias_maps|hash:/etc/aliases|ローカル配送エージェントが利用するエイリアスデータベースのリストを指定。バーチャルを使っている場合、エイリアスを使っていない場合には意味はなし|
|alias_database|hash:/etc/aliases|エイリアスデータベースを指定。alias_mapsと基本同じ。|
|recipient_delimiter|+|ユーザ名と拡張アドレス(user+foo)のセパレータ(分離符号)を指定。通常指定の必要無し|
|home_mailbox|Maildir/|メールボックスフォルダ名の指定/を最後につけると、maildir形式での保存。DBを利用する場合などでは設定する必要無し|
|mail_spool_directory|/var/spool/mail|UNIXスタイルのメールボックスが保存されるディレクトリを指定。DBを利用する場合などでは設定する必要無し|
|mailbox_command|/some/where/procmail|メールボックス配送の代わりに利用するオプションの外部コマンドを指定。指定の必要無し|
|mailbox_transport|lmtp:unix:/var/lib/imap/socket/lmtp|master.cf に挙げられた配送方法をオプションで指定。指定の必要無し|
|fallback_transport|lmtp:unix:/var/lib/imap/socket/lmtp|UNIX passwd データベースに見つからなかった受信者に対して使う master.cf 内の配送方法をオプションで指定。指定の必要無し|
|luser_relay|admin+$local|パラメータは知らない受信者に対する、転送先アドレスをオプションで指定。設定の必要無し|
|header_checks|regexp:/etc/postfix/header_checks|複数の物理行にまたがるヘッダも含めて、正規表現テーブルマッチの判定をオプションで指定。指定の必要無し|
|fast_flush_domains|$relay_domains|遅延メールの情報を持つ目的地毎のログファイルを維持している情報を、コマンドでflush することができる。設定の必要無し|
|smtpd_banner|$myhostname ESMTP $mail_name ($mail_version)|バージョンの問い合わせに対しての返答方法の指定。設定の必要無し|
|default_destination_concurrency_limit|20|同一目的地に対する最大並行送信数の指定|
|debug_peer_level|2|デバッグエラーログのレベル指定|
|debug_peer_list|127.0.0.1|指定ホストのエラーのみをマッチング出力|
|debugger_command||デバッガーのコマンドライン指定|
|sendmail_path|/usr/sbin/sendmail.postfix|sentmail互換の為のパスを指定|
|newaliases_path|/usr/bin/newaliases.postfix|newaliases互換の為のパスを指定|
|mailq_path|/usr/bin/mailq.postfix|mailq互換の為のパスを指定|
|setgid_group|postdrop|メール提出およびキューマネージメントコマンドのグループ|
|html_directory|no|Postfix HTML ドキュメントの場所|
|sample_directory|/usr/share/doc/postfix-2.6.6/samples|オンラインマニュアルページの場所|
|readme_directory|/usr/share/doc/postfix-2.6.6/README_FILES|README ファイルの場所|
|append_at_myorigin|yes|初期値:yes。ローカル投稿メールでドメイン情報のないメールアドレスに文字列 @$myoriginを付与。リモート投函メールでは、代わりに @$remote_header_rewrite_domainを付加|
|append_dot_mydomain|yes|初期値:yes。基本的には不必要。append_dot_mydestinationと関係|



***Mysqlを利用したmain.cfの設定例 [#ae4f81b7]
 # vi /etc/postfix
     myhostname = mail.mydomain.com
     mydomain = mydomain.com
     myorigin = $mydomain
     inet_interfaces = all
     mynetworks=127.0.0.0/8
     virtual_alias_domains = mysql:/etc/postfix/connect_domain.mysql
     virtual_alias_maps = mysql:/etc/postfix/connect_map.mysql

|項目名|設定値|概要|h
|virtual_alias_domains|mysql:/etc/postfix/postfix_domain.mysql|転送用に受信するドメイン名|
|virtual_alias_maps|mysql:/etc/postfix/postfix_map.mysql|転送先のマッピング|

<データベース接続設定ファイル>
 # vi /etc/postfix/postfix_domain.mysql
    hosts = localhost
    user = postfixuser
    password = postfixpass
    dbname = postfix
    query = SELECT name FROM domains WHERE name = '%s'

# vi /etc/postfix/postfix_map.mysql
    hosts = localhost
    user = postfixuser
    password = postfixpass
    dbname = postfix
    query = SELECT fwdaddr FROM virtual_maps WHERE name = '%s'

***MySQL側の設定 [#e8c9ac80]
<テーブルの作成>
 > create database postfix;
 > grant all on postfix.* to postfixuser@localhost identified by 'postfixpass';
 > create table domains (name varchar(253) not null unique);
 > create table virtual_maps (name varchar(254) not null unique, fwdaddr varchar(254) not null);

**バーチャルドメインの設定 [#qe57c719]
postfixでは、unixアカウントを利用せず、かつ複数のドメインのメールを受け取る事が出来る。

***バーチャルドメイン&ユーザーのmain.cfの設定 [#sbcb8a66]

|項目名|設定例|概要|h
|virtual_minimum_uid|100|virtual_uid_maps 検索から返されたものとしてuid の最小値を指定します。返り値がこの値より小さいと拒否されメッセージは遅延する。基本的には virtual_uid_maps の記述ミスの為の安全機構なので、uidが static 指定であれば必要ない|
|virtual_uid_maps|static:5000|ファイルで指定すれば、各バーチャルユーザー毎にuidを設定できるがあまり意味がないので通常は、static指定でuidを固定しておく|
|virtual_gid_maps|static:5000|ファイルで指定すれば、各バーチャルユーザー毎にgidを設定できるがあまり意味がないので通常は、static指定でgidを固定しておく|
|virtual_mailbox_base|/var/spool/mail/virtual|全てのバーチャルメールボックスのパスの前に付けるパス名を指定。要するにこのフォルダ以下に仮想メールボックスが作成される|
|virtual_mailbox_domains|/etc/postfix/virtual_mailbox_domains|ファイル内にドメイン一覧を記述。ファイル名の代わりに、ここに直接受け取れるドメイン名も指定できる。カンマで複数ドメイン名の指定も可能|
|virtual_mailbox_maps|hash:/etc/postfix/virtual_mailbox_maps|バーチャルユーザーの指定。バーチャルなのでユーザー名はドメイン名付きで記述。hash がかかっているので、postmap コマンドを忘れないこと。詳細は下記|
|virtual_mailbox_limit|0|各バーチャルユーザーのメールボックスの最大容量を設定。Bytes指定。0なら無制限。指定がない場合は50MBが初期値|
|virtual_transport|virtual|virtual_mailbox_domains パラメータ値にマッチするドメイン宛の、 デフォルトのメール配送 transportの指定。指定なしの場合の初期値=virtual よって設定の必要無し。|


***バーチャルドメインの管理 [#b1bc6839]
ここでは、mailboxを対象にしたものも、aliasを対象にしたものも設定方法は同じ。
 # vi /etc/postfix/virtual_mailbox_domains
    mydomain.com
    mydomain2.com
    mydomain3.com

ドメインの更新
 # postfix reload

***バーチャルユーザーの管理 [#de5498ea]
複数のドメインでも同じファイルに記述する。以下に記述方法の参考。
 # vi /etc/postfix/virtual_mailbox_maps
     foo.001@domain001.com   domain001.com/foo.001/
     foo.002@domain001.com   domain001.com/foo.002/
     foo.001@domain002.com   domain002.com/foo.002/

※ユーザー名を記述せずドメイン名だけだと、存在しないユーザのメールも何でも受けるユーザーとなる。(SPAMが大量に来るので使用注意)
     @example.com	example.com/catchall/


ファイル変更後データを更新する。
 #  postmap /etc/postfix/virtual_mailbox_maps

サービスを再起動(centos7の場合は systemctl で)

 # service postfix reload


***バーチャルユーザーの参考設定 [#h1b1c49f]
バーチャルメールボックス有り

 # vi /etc/postfix/main.cf
    mail_owner = postfix
    myhostname = mail.mydomain.com
    mydomain = mydomain.com
    inet_interfaces = all
    inet_protocols = all
    mydestination = 
    mynetworks = 127.0.0.0/8
    virtual_mailbox_base = /home/mail/virtual/
    virtual_mailbox_domains = /etc/postfix/virtual_mailbox_domains
    virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox_maps

**バーチャルエイリアスの設定 [#z0e18d19]
バーチャルエイリアスは、その名の通り実際のメールボックスを持たずに、エイリアス機能のバーチャル版として、バーチャルメールアドレスの別名やメールの転送などを設定する。

***バーチャルドメイン&ユーザーのmain.cfの設定 [#sbcb8a66]

|項目名|設定例|概要|h
|virtual_alias_domains|/etc/postfix/virtual_alias_domains|ファイル内にエイリアスドメイン一覧を記述。virtual_mailbox_domainsと同じ|
|virtual_alias_maps|hash:/etc/postfix/virtual_alias_maps|バーチャルユーザーのアイリアス設定ファイル|

virtual_alias_mapsの記述方法は、virtual_mailbox_mapsと同じ。また同じ様にファイル修正後は、postmapを忘れないこと。

 # postmap /etc/postfix/virtual_alias_maps



***名前解決における注意点と設定のコツ [#mb661076]
postfixは、virtual_alias_maps を先に検索してから、virtual_mailbox_maps を探しにいく。そのため、自分の mailbox にも配送し、別の携帯などのメールにも配送させたい場合、このような設定が可能となる。
 # vi virtual_alias_maps 
    myname@mydomain.com      myname@mydomain.com,myname@docomo.ne.jp

一軒すると無限ループなのだが、postfixは無限ループを発見すると、そこで評価を止め、virtual_mailbox_maps の方で再検索する。よって、この設定では mailbox 内の  myname@mydomain.com アドレスにメールの実体が格納されつつ、myname@docomo.ne.jp のアドレスにも転送される設定となる。

***纏めて転送 [#d9f543db]

設定ファイルで正規表現を使っているファイルであることを設定(/etc/postfix/main.cf)

 virtual_alias_maps = regexp:$config_directory/virtual_alias_maps.regexp

エイリアス設定ファイルを下記の様に設定(/etc/postfix/virtual_alias_maps.regexp)

 /^(.*)@domain1\.com$/      $1@domain1.com, $1@domain2.com

※hashは掛けない。

***メールボックスを作成しないバーチャルエイリアスのみの設定例 [#qd2758de]

 # vi /etc/postfix/main.cf
    mail_owner = postfix
    myhostname = mail.mydomain.com
    mydomain = mydomain.com
    inet_interfaces = all
    inet_protocols = all
    mydestination =
    mynetworks = 127.0.0.0/8
    virtual_alias_domains   = mydomain.com
    virtual_alias_maps      = hash:/etc/postfix/virtual_alias_maps


*便利なコマンド [#ma9ef65a]
<バージョンチェック>
 # /usr/sbin/postconf  | grep mail_version

<初期値と違っている項目だけ表示>
 # /usr/sbin/postfix -n

*セキュリティ設定 [#jcfaf0fc]

**メーラーからのSMTPDへの接続 [#u66fa4ab]
+ VRFY {user}コマンドを発行し、200が返ってくるとユーザーの存在が確認できる。セキュリティ上不安なので無効にしておく。
+ HELOコマンドを発行しないクライアントは受け付けない。

 #vi main.cf
  disable_vrfy_command = yes  <- VRFY off
  smtpd_helo_required = yes   <- HELO送らないクライアントも無視
  smtpd_client_restrictions = reject_unauth_pipelining,reject_multi_recipient_bounce,check_client_access hash:/etc/postfix/client_access

 # vi /etc/postfix/client_access
   #--- IP指定
   202.66.133 DISCARD client_access
   #--- domain指定
   black-hacking.co.jp DISCARD     <- DISCARDはREJECTと違いスルーして捨てる。
   apple.com OK                    <- OKは許可
   #---DNS逆引きチェック
   unknown REJECT reverse_lookup_failure

**他のsmtpサーバーへの接続でSASLを利用する。(gmailの場合) [#g49a6726]
SASL(Simple Authentication and Security Layer)といって、認証と通信の暗号化を行うための仕組み。587ポート等を利用して他のsmtpサーバーに、メールの転送などのために接続するときに利用される。

 # vi main.cf
   relayhost = [smtp.gmail.com]:587  <- 転送先の指定
   smtp_sasl_auth_enable = yes     <- saslを有効化する。
   smtp_sasl_auth_enable = yes     <- 接続にユーザー認証を必要とする。
   smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd  <- 転送先のログイン情報
   smtp_sasl_security_options = noanonymous  <- 匿名接続を禁止
   smtp_sasl_mechanism_filter = plain, login  <- md5はトラブルになるので。
   smtp_use_tls = yes  <- TLSを利用する場合。gmailだと必須?
   smtp_sasl_mechanism_filter = plain, login  <- md5はトラブルになるので付けない。そもそもmd5は信頼性低いので意味が無い。下記のTLS使えば問題ない。
   smtp_use_tls = yes  <- TLSを利用する場合。gmailだと必須か。
   smtp_tls_security_level = may
   smtp_tls_loglevel = 1           <- 数字が大きいほど詳細logを出力
   smtp_tls_CAfile = <自分のCAファイルの場所>
   smtp_tls_loglevel = 1           <- 数字が大きいほど詳細logを出力(0-4)
   smtp_tls_CAfile = <保存してあるCAファイルの場所>
   smtp_sasl_tls_security_options = noanonymous  <- tlsの場合のsecurity options

 # vi sasl_passwd
   [smtp.gmail.com]:587   <自分のgmailアカウント>:<自分のgmailパスワード>
 # postmap sasl_passwd  <- hash形式のファイル作成



*トラブルシューティング [#a8b22c9c]
**自分のサーバーのIPがブラックリストに登録されていないか? [#z01d2c56]
 url : https://mxtoolbox.com/blacklists.aspx

**チェックツール [#x07843ea]
 https://mxtoolbox.com/SuperTool.aspx?action=smtp

**SPFの設定 [#h2c2ce18]
- https://support.google.com/a/answer/33786?visit_id=636800936783516729-1884951719&rd=1
- https://takeshiyako.blogspot.com/2016/01/spf-dkim-postfix-centos.html

**Googleメールに届かない。 [#j87a5bc5]
- [[Google 一括送信ガイドライン:https://support.google.com/mail/answer/81126?p=UnsolicitedRateLimitError&visit_id=636802527960452404-1913919203&rd=1]]

- [[Google Postmaster(承認ドメイン追加):https://support.google.com/mail/answer/6227174]]

- [[Google Postmaster Tools:https://postmaster.google.com/managedomains]]

- [[Google SPF でメールの送信者を承認する:https://support.google.com/a/answer/33786?visit_id=636800936783516729-1884951719&rd=1]]

- [[Google 一括送信ガイドライン:https://support.google.com/mail/answer/81126?p=UnsolicitedRateLimitError&visit_id=636802527960452404-1913919203&rd=1]]