==GitLab==構築時にPostfix
をインストールすることになり、メールサーバーであることは知ってはいたが使ったことなかったので、これを機に構築したときの備忘録を残しておく。
どうも旧来からある==sendmail==は、設定の難しさやセキュリティ・速度の問題で、このPostfixへ徐々に移行しているとのこと。ただし、メール不正中継防止として、後述するDovecot
と組み合わせて利用するのが一般的らしい。
Postfixインストール
> sudo apt install postfix
いきなりインストールでつまずいたのは、/etc/init.d
に起動スクリプトを作成した後にチェックが走ってエラーになってしまった。
どうも手動で追加した別のスクリプトに、お約束のヘッダが追加されてなかったため、チェックでエラーになってインストーラが異常終了していた。 以下のテンプレートを各スクリプトに追加したところ、完了できた。
#!/bin/bash
### BEGIN INIT INFO
# Provides : script name
# Required-Start : xxx.sh start
# Required-Stop : xxx.sh stop
# Default-Start : 2 3 4 5
# Default-Stop : 0 1 6
# Short-Description : Some info
# Description : Some more info
### END INIT INFO
Postfix 基本設定
インストールが完了すると、コンフィグレーション設定に移行するが、 なにもせずに終了して手動で設定ファイルを編集していく。
> sudo vi /etc/postfix/main.cf
:
メールサーバーのホスト名(完全修飾名)を設定する
myhostname = hoge.com
ドメイン名の設定
mydomain = hoge.com
myhostnameのドメイン部分
myorigin = $mydomain
メール受信の設定
inet_interfaces = all
IPアドレスのプロトコル
IPV4のみ
inet_protocols = ipv4
ローカルに配送するドメインのメールかどうかの判断
ここに記載していないドメインのメールアドレスはDNSで引き当ててほかへ転送される
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
全てのメールを配送する信頼されたネットーワークを指定する
ローカルマシンからのメールのみ転送
mynetworks = 127.0.0.0/8, 192.168.0.0/24
ユーザのメールボックスの場所を設定する
"/home/mail"を指定すると、"/home/mail/<user>"がメールボックスとなる
"/"で終わる値を設定すると Maildir形式のメールボックスになる
home_mailboxを有効にする場合はこちらをコメントアウトする
mail_spool_directory = /home/mail
各ユーザディレクトリ以下にメールボックスを作成する場合は以下で指定する
"/"で終わる値を設定すると Maildir形式のメールボックスになる
mail_spool_directoryを有効にする場合、こちらをコメントアウトする
home_mailbox = Maildir/
メールボックスの上限
mailbox_size_limit = 51200000
メール1件あたりの上限サイズ(もちろんメールボックスの上限を超えてはいけない)
message_size_limit = 10240000
外部からきたメールの中で転送するドメイン名を指定する
外部からのメールを受け取らない
relaydomain =
拡張メールアドレスの区切り文字
ここで指定した区切り文字を付与するとすべて同じメールボックスに届く
hoge@mail.domain.comだと、hoge+abc@mail.domain.comやhoge+123@mail.domain.com
が同じメールボックスに届く
recipient_delimiter = +
aliasで別ユーザ宛のメールを受信するときの参照先
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
構築方法や設定方法、操作方法が書かれたPostfix READMEファイルの場所
readme_directory = no
ローカルメールで、".domain" のないアドレスに対して、
".$mydomain" を自動で付与する
append_dot_mydomain = yes
append_at_myorigin = yes
指定時間以内に配送できない場合は送信者に通知が行く
指定しないと通知しない
delay_warning_time = 4h
新着メール通知を送信する
biff = no
smtp_helo_name = $myhostname
SMTP グリーティングバナー
先頭が$myhostnameは必須のルール
smtpd_banner = $myhostname ESMTP unknown
Postfixで、SMTPで認証を行い任意のIPアドレスからメール中継を可能にする設定
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
main.cfの内容をチェックする。以下を実行すると、 現在の設定の内容すべてがダンプされて、末行に問題箇所があれば出力される。
> postconf -d
> postconf -n
エイリアスを更新
> sudo newaliases
Postfixを再起動する
> sudo /etc/init.d/postfix restart
[ ok ] Restarting postfix (via systemctl): postfix.service.
メールコマンドを使えるように==mailutils==をインストールする
> sudo apt install mailutils
気をつける点として、main.cfで、home_mailbox
を有効にした場合、
mailコマンドでメールボックスを参照するときは-f
でメールボックス
を指定して実行する。これを指定しないと、デフォルトパスの
/var/mail/<usrname>
を確認して、=="no mail for xxx=="と
なってしまうので注意する。これでかなり悩んだ。
とりあえず、自分宛にメールを送信して、正しく受信できることをまず確認する。
> mail <user-name>@hoge.com
CC:
Subject: test mail
test !
(Ctrl+D)
>mail -f ~/Maildir
"/home/<user-name>/Maildir": 1 message 1 new
>N 1 Hoge 13/429 test mail
? 1
Return-Path: <hoge@hoge>
X-Original-To: hoge@hoge.com
Delivered-To: hoge@hoge.com
Received: by usagi1975.com (Postfix, from userid 1000)
id A08CF381CC6; Tue, 7 Feb 2017 08:29:22 +0900 (JST)
To: <hoge@hoge.com>
Subject: test mail
X-Mailer: mail (GNU Mailutils 2.99.99)
Message-Id: <20170206232922.A08CF381CC6@hoge.com>
Date: Tue, 7 Feb 2017 08:29:22 +0900 (JST)
From: hoge@hoge (Hoge)
test !
?
Dovecotの設定
POP3またはIMAPによるメール受信ができるようにするために
Dovecot
をインストールする。
> sudo apt install dovecot-core dovecot-pop3d dovecot-imapd
設定ファイルを編集する
> sudo vi /etc/dovecot/dovecot.conf
# IPv4のみListenする
listen = *
> sudo vi /etc/dovecot/conf.d/10-auth.conf
# 平文テキストでも認証可能とする
disable_plaintext_auth = yes
> sudo vi /etc/dovecot/conf.d/10-mail.conf
# メールボックスの保存先を指定する(Postfixのhome_mailboxと同じ場所)
mail_location = maildir:~/mailbox
> sudo vi /etc/dovecot/conf.d/10-master.conf
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
main.cfも併せて修正する。
# 以下SMTP-Auth用(Dovecotを使う設定)
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = permit_mynetworks,permit_auth_destination,permit_sasl_authenticated,reject
Postfix SMTP Submission SMTP_AUTH有効化
smtpポート(25番)はOP25B
対策により、事実上メール送信で使用
できなくなっている。代替案として、メールの送信を行うための送信専用
のポート(587番)をサブミッションポート(Submission)と呼ばれる。
このポートとSMTP認証
(SMTP Auth)を利用する設定を行う。
master.cfをオープンして、以下の行のコメントを解除する。
>sudo vi /etc/postfix/master.cf
submission inet n - n - - smtpd
-o syslog_name=postfix/submission
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
一旦Postfixを再起動して、ポートが利用可能になっているか確認する。
> sudo netstat -anp | grep "master" | grep "0.0.0.0"
tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN 10514/master
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 10514/master
telnetコマンドで、ポート587に接続し、ehlo localhost
と入力。
250-AUTH PLAIN LOGIN
という項目があればOK.
(quitで終了する)
>telnet localhost 587
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.example.com ESMTP
ehlo localhost
250-mail.example.com
:
250-AUTH PLAIN LOGIN
:
quit
つづいて、==SMTP認証==の設定を行う。 証明書やサーバ用の秘密鍵は既存のものを利用する。 一応有効期限は、2027年までになっていた。
> sudo vi /etc/postfix/main.cf
Postfix SMTPサーバRSA証明書関連の設定
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
master.cf
ファイルに対しても以下をコメント解除する。
> /etc/postfix/master.cf
-o smtpd_tls_security_level=encrypt
smtps inet n - y - - smtpd
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
Postfixを再起動して、Listenしているポートを確認する
> sudo netstat -anp | grep "master" | grep "0.0.0.0"
tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN 10823/master
tcp 0 0 0.0.0.0:465 0.0.0.0:* LISTEN 10823/master
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 10823/master
再度587ポートに接続し、250-STARTTLS
になっていればOK
telnet localhost 587
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.example.com ESMTP
ehlo localhost
250-mail.example.com
:
250-STARTTLS
:
トラブル備忘録
外部からメールが受信されない
smtp_helo_name
を設定していなかった。> /etc/postfix/main.cf smtp_helo_name = $myhostname
mailコマンドで自身宛にメールしても届かない
home_mailbox
でMaildir形式を設定していたため、 mailコマンドのデフォルトで参照するメールボックスの場所 と異なっていた。mailコマンド起動時に-f
オプションで メールボックスの場所を指示するようにした。> /etc/postfix/main.cf
/home/(username)/Maildirにメールボックスを作成
home_mailbox = Maildir/
> mail
no mail for xxxx
> mail -f ~/Maildir
外部へメール送信できない
いわゆる
OP25B(メール送信規制)
で送信できなかった。 デフォルトでは25番ポートを使ってメール送信されるわけだが、 メジャーなメールサーバーはすでにこのポートは塞いで別のポート でしかメールを受け付けていない。以下は==/var/log/mail.err==の抜粋。
Feb 7 20:14:52 saba postfix/smtp[7949]: 8GTY7399CFB: to=<xxx@xxx.co.jp>, relay=none, delay=3401, delays=3340/0.01/61/0, dsn=4.4.1, status=deferred (connect to xxxx.xxx.com[203.198.122.09]:25: Connection timed out)
対応としては、Gmailアカウントを利用して、GmailのSMTPサーバを 中継先として使用するようにPostfixの設定を変更する。
> sudo vi /etc/postfix/main.cf
外部へのメールを送るメールサーバーを指定する
OP25B対応(Gmail Smtp)
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_mechanism_filter = plain
smtp_sasl_password_maps = hash:/etc/postfix/gmail_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_use_tls = yes
上記で指定したファイルに以下のフォーマットでGmailのパスワードを 記録する。(userとpasswordをアカウントのものに置き換える)
>sudo vi /etc/postfix/gmail_passwd
[smtp.gmail.com]:587 user@gmail.com:password
> sudo chmod 600 gmail_passwd
ちなみにほかのSMTPサーバーとリレーする場合の書式は以下 が一般的。また先ほど作成したファイルに追記しておくことも可能。
[smtp.hoge.com]:587 user:password
以下のコマンドでdbファイルを作成する。postfixを再起動して 送信できるか確認する。
> sudo postmap hash:/etc/postfix/gmail_passwd
注意点として、gmailアカウントでgmailのメールボックスを確認し、 ロックされてないか確認する。
メールログを見ると、"Diagnostic-Code: smtp; 554 5.4.0 Error: too many hops"と表示されて外部からのメールが受信できない。
外部からメールが送信されたときに発生する。 SMTPサーバーは自分宛じゃないと判断されると、 メールが==たらい回し==にされて次のサーバーに転送される。 ここで解決できなくて、永久ループを避けるために"たらい回し"の回数 を制限しており、この上限に達するとこのエラーが送信元に通達される。
ログをみていると、大量にログが流れたあとにエラーになるのがわかる。 確認すべきポイントとしては、誰宛にメールが来ているのかを確認し、 その宛先アドレスのドメイン名(@の後ろ)が、postfixの==main.cf== 設定ファイルの==mydestination==に含まれていなかったのが問題だった。
# 送信されていたメールアドレス # hoge@server.hoge.com # 誤:mydestination = server, hoge.com mydestination = server, hoge.com, server.hoge.com
OP25B問題の回避策として、gmailのsmtpサーバー経由で送信したところ、 Outlookで受信すると、==「XXXの代理で送信」==と表示されてしまう。
ネットでこの問題を検索すると、「アドレスを追加して、gmailの設定で fromを指定できる」ような記述がたくさんヒットしたが、 この情報は古いと思われる。
確かにアドレスは追加できて、送信元の自前のsmtpサーバーの FQDNとユーザIDパスワードを指定すれば、転送してくれる。 が、依然として==「XXXの代理で送信」は解消しなかった。==
どうも、gmailの仕様で、メールヘッダに代理で送信した情報が送信した メールに追記されてしまうみたいで回避できないんじゃないか と思っている。(Fromは自前のサーバー、SenderにGmailサーバーが 表示されている)
回避した方法としては、smtp.gmail.comの利用はあきらめて、加入している プロバイダのsmtpサーバーを
relayhost
で指定することで解決とした。