目次
はじめに
前回でメールを保存する用の領域をRAIDで作成することができたので、今回はついにメールサーバを立ち上げます。
かなり大変でした。
環境はURoad-Home2+にOpenWRTを入れたものです。
目標
SMTP、SMTPs、サブミッションポートで送受信し、IMAPsでメールを配信するメールサーバです。メールは外付けHDDに保存します。
また、Gmail等に迷惑メールと認識されないようにするために、SPF、DKIMの設定も行います。
参考文献
CentOSで自宅サーバー構築「メールサーバー構築(Postfix+Dovecot)」
Qitta「自ドメインのDNSとPostfixをSPF/DKIM対応させてみた」
事前準備
外部ストレージの接続
OpenWRTはルータ向けのOSでルータはROMがもちろん少ないので、外付けストレージをつけないとどう考えても足りません。自分は、前回記事のOpenWRTでmdadmを使用したソフトウェアRAIDを組むでRAID1でHDDを接続しています。マウントも適当な場所にしておいてください(例/mnt/md0)。
ソフトウェアのインストール
Postfix、dovecot、dovecot-utils、acmeをインストールして下さい。
ディレクトリの設定
postfix用のディレクトリを作成します。
mkdir /mnt/md0/postfix
証明書の準備
すでに証明書がある場合はそれを使用して下さい。自分はなかったので、OpenWRTのACMEを使用しました。
ACMEを使用する条件として80ポートと443ポートが開放されている必要があります。ローカルネットワークにサーバを置いてゲートウェイでポートフォワーディングを使用してメールサーバを公開しようとしている場合は注意が必要です。その場合は、ローカルネットワーク無いからSSHやLuci(80ポート)にアクセスできるようにするためにファイアーウォールを無効or80ポートを開けていると思いますがそれだと外部からLuciが見えてしまいます。それを回避するためにLuciのポートを変更します。
Luciポート変更は/etc/config/uhttpdを開いてhttpのポートが定義されている部分を変更し、
option listen_http '0.0.0.0:8080 [::]:8080'
みたいな感じで8080にしました。/etc/init.d/uhttpd restartやLuci(システム→スタートアップ)からuhttpdを再起動して下さい。これ以降、Luciへの接続は:8080をつけて、8080ポートでアクセスしてください。
ACME自体はluci-i18n-acme-jaをインストールするとLuciから設定できます。証明書の期限が来た時に通知してくれるメールアドレスと、証明書設定で、ドメイン名を設定し、有効化すれば自動で証明書が発行されます。パスは下みたいな感じです。
証明書: /etc/acme/ドメイン名/fullchain.cer
鍵: /etc/acme/ドメイン名/ドメイン名.com.key
Postfixの設定
/etc/postfix/main.cf
ドメイン、ホスト名周りの設定
myhostname = サーバのホスト名
mydomain = 使用するメールアドレスのドメイン
myorigin = $mydomain
外部からのアクセスを有効にします。
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
Maildir形式で保存します。
home_mailbox = Maildir/
メールサーバソフトを非公開に
smtpd_banner = $myhostname ESMTP unknow
最後の部分には、今まで設定してきたことと同じ内容が書かれている部分があります。適当にコメントアウトしてください。あと、data_directory、queue_directory、queue_directoryは外付けディスク(下の例では/mnt/md0)にして下さい。
inet_protocols = ipv4
default_database_type = cdb
config_directory = /etc/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
shlib_directory = /usr/lib/postfix
manpage_directory = no
data_directory = /mnt/md0/postfix
queue_directory = /mnt/md0/postfix
mail_spool_directory = /mnt/md0/postfix
# myhostname = OpenWRT 先程定義したためコメントアウト
# mydomain = lan 同じくコメントアウト
mynetworks_style = host
追加で、認証時のユーザ名を隠すために
# hide user
disable_vrfy_command = yes
認証方式であるSASLの設定です。dovecotの認証を利用します。
# setting for sasl
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
SMTPの設定です。SSL周りの設定を行っています。
# SMTP setting
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
smtpd_tls_auth_only = yes
smtp_tls_security_level = may
smtpd_tls_received_header = yes
メールのサイズを制限を設定します。10MBあたりが一般的だと思います。
# Mail size limit
message_size_limit = 10485760
SSLの証明書、秘密鍵のパスの設定
ACMEを使用した場合は以下のパスです。
# pem path
smtpd_tls_cert_file = /etc/acme/ドメイン名/fullchain.cer
smtpd_tls_key_file = /etc/acme/ドメイン名/ドメイン名.com.key
メールヘッダにUnicodeの使用を可能とするSMTPUTF8を無効にします。これをしないと
postsuper: warning: smtputf8_enable is true, but EAI support is not compiled in
と言われます。
# bypass warning: smtputf8_enable is true, but EAI support is not compiled in
smtputf8_enable = no
/etc/postfix/master.cf
こんな感じに設定すればSMTP、SMTPs、Submissionポートとかが使用できるようになります。よくわかってないですが動作してるのでヨシ!
smtp inet n - n - - smtpd
#smtp inet n - n - 1 postscreen
#smtpd pass - - n - - smtpd
#dnsblog unix - - n - 0 dnsblog
#tlsproxy unix - - n - 0 tlsproxy
submission inet n - n - - smtpd
# -o syslog_name=postfix/submission
# -o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
# -o smtpd_tls_auth_only=yes
-o smtpd_tls_security_level=encrypt
# -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
smtps inet n - n - - smtpd
# -o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-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
あとは、Postfixを開始させます。
postfix start
実行時に様々なメッセージが出るので、適宜修正して下さい。多分、ディレクトリの権限や所有者についてのエラーが出ると思います。
Dovecotの設定
/etc/dovecot/dovecot.conf
使用するプロトコルをimapsだけにしたかったので変更しました。
# Protocols we want to be serving.
protocols = imaps
/etc/dovecot/conf.d/10-master.conf
IMPAsの設定を有効化します。
service imap-login {
inet_listener imap {
#port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
Postfix用のSASL認証を有効にします。data_directory = /mnt/md0/postfixとしたため、それに合わせて、authファイルのパスも変更して下さい。
# Postfix smtp-auth
unix_listener /mnt/md0/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
/etc/dovecot/conf.d/10-mail.conf
Maildir形式を設定します。~はユーザディレクトリを表しています。
mail_location = maildir:~/Maildir
/etc/dovecot/conf.d/10-auth.conf
SSLを有効化します。
disable_plaintext_auth = yes
ユーザ名@ドメイン名が付属した状態でログインを可能とします。これを有効にしないと、ユーザ名のみでなければログインできなくなってしまいます。
auth_username_format = %n
それ以外は多分もとから設定されていますが、一応載せておきます。
auth_mechanisms = plain
#!include auth-deny.conf.ext
#!include auth-master.conf.ext
!include auth-system.conf.ext
#!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-static.conf.ext
/etc/dovecot/conf.d/auth-system.conf.ext
設定する選択肢が2つあります。1つ目は、PAMをインストールして認証システムとして使用する方法です。もう一つは、passwd、shadowファイルを直接読み取り認証に使用する方法です。セキュリティとしてはPAMのほうが優れていますが、PAM自体のインストールと設定が必要です。それが手間だったので、今回はpasswd、shadowを直接読み取る方法にしました。
ディフォルトで有効となっているPAMを利用したpassdbを無効にします。
#passdb {
# driver = pam
# [session=yes] [setcred=yes] [failure_show_msg=yes] [max_requests=<n>]
# [cache_key=<key>] [<service name>]
#args = dovecot
#}
passdbをshadowベースにします。
passdb {
driver = shadow
# [blocking=no]
#args =
}
userdbはそのままです。今回はpasswdでホームディレクトリを外付けドライブの/mnt/md0に指定しているので問題ありませんが、場合によっては、override_fields = home=/mnt/md0/%uとかにしたほうが良いかもしれません。
/etc/dovecot/conf.d/10-ssl.conf
SSLでの通信を必須とします。
ssl = required
証明書と秘密鍵のパスを指定します。ACMEを使用した場合
ssl_cert = </etc/acme/ドメイン名/fullchain.cer
ssl_key = </etc/acme/ドメイン名/ドメイン名.key
こんなもんです。あとは、dovecotを開始させます。
dovecot
エラー等は
logread
で確認できます。
ユーザの追加
メールのユーザを追加します。ユーザIDが小さいアカウントは動作しません。ホームディレクトリ下のMaildir/下にメールが配信されるので、ホームディレクトリは外付けドライブ(例/mnt/md0)にする必要があります。また、ホームディレクトリを作成する必要もあります。面倒なので、スクリプトを作成しました。これを使用すればメールユーザが簡単に作成できます。ただし、/etc/groupにmailuserを追加してください。
外付けドライブのマウントディレクトリは/mnt/md0となっています(4箇所)が、適当なものに変えて下さい。
#!/bin/ash
# enter new username
echo "Enter new username:"
read username
# check username
if grep -q "^$username:" /etc/passwd; then
echo "Error: User $username already exists."
exit 1
fi
# detect uid in passwd
uid=1000
while grep -q "^.*:x:$uid:" /etc/passwd; do
uid=$((uid + 1))
done
# add user to /etc/passwd
echo "$username:x:$uid:1000:mailuser:/mnt/md0/$username:/bin/false" >> /etc/passwd
echo "$username:x:0:0:99999:7:::" >> /etc/shadow
# set passwd
passwd $username
# make dir
echo "make dir /mnt/md0/$username"
mkdir -p /mnt/md0/$username
chown $username:1000 /mnt/md0/$username
chmod 775 addmailuser.shとかで実行権限を与えて、実行して指示に従って入力すればユーザが作成されます。uidは1000から開いている順に割り当てられます。
mailuser:x:1000:mailuser
ポート開放
もちろんして下さい。
直接インターネットに接続されている場合は、Luciでネットワーク→ファイアウォール→ポートフォワーディングで設定できます。
ローカルネットワーク内の場合は、ゲートウェイでポートを解放してください。
ポートですが、IMAPsの993、SMTPの25、SMTPsの465、SMTP SubmissonPortの587が必須です。ACMEで定期的に自動で証明書を更新する場合は80、443ポートも解放してください。
動作確認
ここまでできたらとりあえず動作確認します。適当なメーラでIMAPでログインできます。メールアドレスも、ユーザ名も、パスワードも、ポート番号も間違っていないのにログインできない場合は、logreadを使用してログを確認して下さい。/etc/dovecot/conf.d/10-logging.congのauth_verbose = yesを有効にすると、詳細なログイン試行のログが見れます。
MXレコード
こっから先はDNS周りの設定です。
まず初めにMXレコードです。これは、メール用のDNSレコードみたいな感じです。すでに登録済みのAコードと同じ場合は、同じIPアドレスを登録するか、mail.unagidojyou.comみたいなCNAMEレコードを作って、それを参照するみたいな感じでも大丈夫です。
SPFの設定
SPFはメールの送信元IPアドレスと、DNSからのIPアドレスが等しいかどうかで正しい送信元か判定するものです。お使いのドメイン管理サイトでTXTレコードとして設定します。mxレコードを参照する場合は以下のような感じです。
"v=spf1 mx -all"
mxコード以外の指定の仕方もあります。各自で調べてみて下さい。
DKIMの設定
これが難しくて他のLinux機が必要です。一応Rubyとモジュールをいくつかインストールすれば動くようですが、どのモジュールをインストールすればよいのかわからなかったので他のLinux機で鍵と証明書を生成しました。
パッケージとして、opendkimをインストールしてください。
Postfixで追加の設定が必要です。以下を追加して下さい。
/etc/postfix/main.cf
# DKIM
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = inet:localhost:8891
milter_default_action = accept
鍵の発行ですが、適当なLinuxにて同じくopendkimをaptやyumでインストールします。その後、
sudo mkdir /etc/opendkim/key/ドメイン名
sudo opendkim-genkey -D /etc/opendkim/key/ドメイン名/ -d ドメイン名
で公開鍵(.txt)と秘密鍵(.private)を作成します。セクタの入力を求められたら、適当に今日の日付とかにします。これができたら、scpなどでOpenWRT機に転送して下さい。
OpenWRTでも、鍵の場所はmkdir /etc/opendkim/key/ドメイン名で作成し、その中に格納して下さい。
続いて、OpenDKIMの設定を行います。
/etc/opendkim.conf
ドメインの設定をします。
# A set of domains whose mail should be signed by this filter.
# Mail from other domains will be verified rather than being signed
domain 使用するメールアドレスのドメイン
セクタの指定、秘密鍵の指定を行います。秘密鍵は多分、セクタ.private
って感じになっていると思います。
# Defines the name of the selector to be used when signing messages
Selector セクタ
KeyFile /etc/opendkim/key/ドメイン名/.privateのファイル
Postfixのホストの指定をします。DKIMサーバとPostfixのサーバが同一機なので、次IPアドレスと、ループバックIPアドレスを指定しておけば問題ありません。
## Hosts to sign email for - 127.0.0.1 is default
## See the OPERATION section of opendkim(8) for more information
#
#InternalHosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
InternalHosts 自機のIPアドレス, 172.0.0.1
あとは
opendkim
でスタートさせます。
続いて、レコードの設定です。
cat /etc/opendkim/key/ドメイン名/.txtのファイル
でファイル中身を表示させます。そしたら、ドメイン管理サイトでtxtレコードを追加し、ドメインは
セクタ名._domainkey.ドメイン名
レコードの内容は
“v=DKIM1; h=sha256; k=rsa;
p=*********”
“*******”
みたいに少し変えて登録します。
ADSPレコードの登録
追加でADSPレコードも登録します。txtレコードで、ドメイン名は
_adsp._domainkey.ドメイン名
レコードの内容はdkim=unknown(DKIMで署名されていないものも送信)か、dkim=all(すべて署名済み)、dkim=discardable(DKIMで署名されていないor署名が無効の場合破棄)のいずれから選びます。特に深く考えずにdkim=unknownを設定しました。
再起動時の設定
機種によると思いますが、外付けHDDがかなり遅れてマウントされることがあります。こうなるとPostfixがHDDがマウントされるよりも早く実行されてしまい、マウンタポイントにディレクトリが作成されてしまったりして、面倒なことになります。そのため、別で起動時のシェルスクリプトを作成すると良いと思います。
自分の場合は、mdadmを使用したRAID1を使用しており、スタートアップ時にRAIDの構成用にシェルスクリプト(マウントまで行う)を使用していたため(詳細はこの記事)、このシェルスクリプトを実行したあとにpostfixとdovecotを実行するようにしました。
おわりに
メールサーバの立ち上げ(2週間)も、この記事の作成(1.5週間)も大変でした。Googleで検索をかけてもOpenWRTでメールサーバを構築している人がいなかったのでOpenWRT固有のエラーが出た時は手こずりました。また、自分のメールサーバではVPNでの接続も行っているので、メモリが足りなくて落ちるなんてこともありました。メールサーバを立ててから記事を書き終わるまで時間が空いてしまったので掻き落としがあるかもしれません。気をつけて下さい。メインのメールアドレスを移行するつもりなので、落ちないようにメンテナンスを頑張ります。