メールサーバーの構築(sendmail SASL)

1.なぜsendmailか

sendmailはインターネット上で最もシェアの高いMTAで、アメリカのSendmail社が開発元です。企業が開発を行っていますが、フリーウェアですので無料で使用可能です。sendmailは柔軟かつ強力なMTAで、メインの設定ファイルを正しく設定すればメールに関するほとんどのことが実現可能です。
しかし、かつてsendmailはroot権限で動作していたためセキュリティーホールが見つかった場合に重大な問題に発展する可能性がありました。またメール配送自体もそれほど高速ではないため、大規模なメーリングリストを運用したり、大量にメール配送するには不向きです。
最近では、メール爆弾、スパムメールといった犯罪、または犯罪として認定されつつある行為に利用されてしまうことになります。このようなメールの中継ホストとして利用されると、他のホストやユーザーに大変な迷惑をかける上、サーバーやネットワークのリソースを利用されてしまいます。また、サーバーの所属する組織と管理者の信用を著しく失墜させることになります。管理し切れない方は素直にqmailかpostfixを使用する事をお薦めします。
しかし、sendmailに付随する各種メールに関するソフトはsendmailを基本に作られていることが多いので
ここは素直にsendmailを引き続き使用する事にします。
そのまま使用するのは危険ですので外出先からでも安心して送信できる環境であるSMTP-AUTH(TLS/SSL)を構築します。

2.インストール

FreeBSDの場合、sendmailはデフォルトでインストールされています。
暗号化の為にSASLが必要ですのでportsから一気にインストールしてします。
# cd /usr/ports/security/cyrus-sasl2-saslauthd
# make install clean
これでSASL2もインストールされます

sendmailですが、2種類の方法があります
1つはFreeBSDにデフォルトでインストールされているものを再度コンパイル
もう1つは最新版をportsでインストールしてデフォルトのsendmailはオフするです。

まず再コンパイルのみの場合を説明します。
まず /etc/make.conf に下記を追加します
SENDMAIL_CFLAGS+= -I/usr/local/include -DSASL=2
SENDMAIL_LDFLAGS+= -L/usr/local/lib
SENDMAIL_LDADD+= -lsasl2
そして下記実行
# cd /usr/src/lib/libsm
# make obj depend all
# make
# make install
# cd /usr/src/lib/libsmutil
# make obj depend all
# make
# make install
# cd /usr/src/usr.sbin/sendmail
# make cleandir
# make obj
# make depend
# make
# make install
インストールしたらSASLが有効になっているか確認します。
# sendmail -d0.1 -bv root
Version 8.15.2
 Compiled with: DNSMAP IPV6_FULL LOG MAP_REGEX MATCHGECOS MILTER
          MIME7TO8 MIME8TO7 NAMED_BIND NETINET NETUNIX NEWDB NIS
          PIPELINING SASLv2 SCANF STARTTLS TCPWRAPPERS USERDB XDEBUG
太字があれば大丈夫だと思います。

portsから最新版にする場合は
# cd /usr/ports/mail/sendmail-sasl
# make install clean
これでインストールは完了しますので、デフォルトをOFFするには
webminなどで現在走っているsendmailを停止して
/etc/rc.confに以下の行を追加します
sendmail_enable="NONE"
そして今度はports側のsendmailを起動時でも走るようにします。
# cd /usr/local/etc/rc.d
# cp sendmail.sh.sample sendmail.sh
# /usr/local/etc/rc.d/sendmail.sh start
これで起動します。

このままですと他のアプリケーションなどから /usr/sbin/sendmail をアクセスしてきてしまいます
幸いにもFreeBSDは/usr/sbin/sendmail というのは、実は /usr/sbin/mailwrapper なのです
そしてこのmailwrapperといのは /etc/mail/mailer.conf を見てメーラーを呼び出しています。
ですので、sendmailの場所が変わっただけで有ればこの /etc/mail/mailer.conf を編集すれば今まで通り
/usr/sbin/sendmail を呼び出せば最新のsendmailが走るということです。
では編集します
/etc/mail/mailer.conf
#sendmail       /usr/libexec/sendmail/sendmail
#send-mail      /usr/libexec/sendmail/sendmail
#mailq          /usr/libexec/sendmail/sendmail
#newaliases     /usr/libexec/sendmail/sendmail
#hoststat       /usr/libexec/sendmail/sendmail
#purgestat      /usr/libexec/sendmail/sendmail

sendmail        /usr/local/sbin/sendmail
send-mail       /usr/local/sbin/sendmail
mailq           /usr/local/sbin/sendmail
newaliases      /usr/local/sbin/sendmail
hoststat        /usr/local/sbin/sendmail
purgestat       /usr/local/sbin/sendmail
これでportsのsendmailが呼び出されるようになります

saslの設定をします
/usr/local/lib/sasl2/Sendmail.conf
pwcheck_method: saslauthd

これで暗号化関係は準備が整いました
され、それではsaslを起動させます

/etc/rc.confに追加
saslauthd_enable="YES"
saslauthd_flags="-a pam"
立ち上げます
# /usr/local/etc/rc.d/saslauthd start
これで暗号化関係は準備が整いました

3.CFファイル設定

mcファイルを編集します。
/etc/mail/freebsd.mcに追記
dnl 証明書の設定
define(`confCACERT_PATH', `/usr/local/etc/letsencrypt/live/hogehoge.mydns.jp')dnl
define(`confCACERT', `confCACERT_PATH/chain.pem')dnl
define(`confSERVER_CERT', `confCACERT_PATH/cert.pem')dnl
define(`confSERVER_KEY', `confCACERT_PATH/privkey.pem')dnl
define(`confCLIENT_CERT', `confCACERT_PATH/cert.pem')
define(`confCLIENT_KEY', `confCACERT_PATH/privkey.pem')
define(`confDH_PARAMETERS', `/etc/mail/certs/dh2048.param')

dnl smtpsの設定
define(`confTLS_SRV_OPTIONS',`V')
define(`confAUTH_OPTIONS', `A')
define(`confTO_IDENT',`0s')
define(`confDONT_BLAME_SENDMAIL',`GroupReadableSASLDBFile')
define(`confRUN_AS_USER', `root:mail')
define(`confAUTH_MECHANISMS', `DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')
TRUST_AUTH_MECH(`DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')
FEATURE(`no_default_msa')
DAEMON_OPTIONS(`Port=smtp, Name=MTA, Address=0.0.0.0', Family=inet)
DAEMON_OPTIONS(`Port=smtps, Name=TLSMTA, M=s', Family=inet)

dnl 他の設定
define(`confCW_FILE', `-o /etc/mail/local-host-names')
define(`confDOMAIN_NAME',`hogehoge.mydns.jp')
dnl 同時送信最大数
define(`confMAX_RCPTS_PER_MESSAGE', `50')
これが基本です
認証方式で本来はDIGEST-MD5 CRAM-MD5があればよいのですが、
設定の少ないメーラーの場合は平文にSSLだけというのを認可しておかないと駄目な場合があるのでLOGINやPLAINなども入れておきます。
またデフォルトで
define(`confCW_FILE', `-o /etc/mail/local-host-names')
が有るのでこれも念のため、作成しています
/etc/mail/local-host-names
localhost
root
す。

TLS における Diffie-Hellman 鍵交換の脆弱性が過去にあったので念のためにファイルを作成しておく。(mcファイルには上記に記載済み)
l# cd /etc/mail/certs
# openssl dhparam -out dh2048.param 2048

編集できたらwebminのSendmail M4 Configurationを使用してcfファイルを作成してしまいましょう
その際にmcファイルのありかを設定しておくのを忘れないようにしてください
サーバー⇒sendmailの設定から

を押して下に有る

を押します、そして
差分が出てきますので確認します。
< が削除
> が追加です
良ければ

を押せばcfファイル生成でき反映します
あとはsendmailを再起動すればOKです
変更を反映ではなく、バイナリーを再コンパイルしていますので、しっかりと停止して起動しましょう

再起動
# /etc/rc.d/sendmail restart
# /usr/local/etc/rc.d/saslauthd start

それでは動作確認をしてみます。
% openssl s_client -connect hogehoge.mydns.jp:587 -starttls smtp
CONNECTED(00000003)
...<省略>
250 HELP
EHLO mta.next-hop.net
250-mta.next-hop.net Hello mta.next-hop.net [192.168.0.10], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-DSN
250-AUTH DIGEST-MD5 CRAM-MD5 LOGIN PLAIN
250-DELIVERBY
250 HELP
MAIL FROM:<root@next-hop.net>
530 5.7.0 Authentication required

4.ユーザー追加

saslのデータにユーザーを追加します
# saslpasswd2 -u ドメイン名 -c ユーザー名
Password: パスワード入力
Again (for verification):パスワード入力

さて、ちゃんと追加されているか確認しましょう
# sasldblistusers2
で、出て来ます

削除する場合は -c を -d で削除できます。
パスワード変更は
# saslpasswd2 -u hogehoge.mydns.jp ユーザー名

5.qpopperのインストール

sendmailが動いているだけでは送信は可能ですがメールをメーラーで取り込めません。
メールを取り込むにはPOPサーバーとして動かなければなりません。
POPにはqpopperを使用します。
# cd /usr/ports/mail/qpopper
# make install clean

6.qpopperの設定

POPサーバーは普段からデーモンが走っている必要はあまりないので、inetdで起動するようにします。
/etc/inetd.confに追加
pop3 stream tcp nowait root /usr/local/libexec/qpopper qpopper -s

次にユーザー登録をしますが、これはやらなくても大丈夫のような気がします
だいぶ昔にやった覚えが有るのでとりあえず記録として書きますがまずはやらないでトライして見てください
登録はtelnetでおこないます。
# telnet localhost pop3
trying 127.0.0.1...
Connected to localhost.hogehoge.net
Escape character is '^]'.
+OK QPOP (version 4.0.4) at chaco.hayagui.com starting.
user hogeuser ←ユーザー名入力
+OK Password required for ******.
pass hogepass ←パスワード入力
+OK kenz has 0 visible messages (0 hidden) in 0 octets.
quit ←終了の入力
+OK Pop server at chaco.hayagui.com signing off.
Connection closed by foreign host.

7.APOPの設定

POPそのままではユーザーパスが平文で流れるのでとても危険です、暗号化するAPOPを導入して見ます
まずは初期化します
# qpopauth -init
エラーが出る場合は
/usr/local/etc/qpopper
のディレクトリーを作成して下さい

次にユーザー登録をします
# qpopauth -user ユーザー名
Adding only APOP password for ユーザー名.
New password:(ここでパスを打ち込みます)
Retype new password:(もう一度パス入力)
#

8.ログ

このままだと/var/log/messagesに
qpopper[10399]: Stats: user 0 0 0 0 マシンドメイン クライアントIP
というのが、ずらずら出て来てじゃまですので、これを排除します
まず
/etc/syslog.conf に追加
!qpopper
*.* /var/log/qpopper.log

/etc/inetd.conf のqpoperの部分
pop3 stream tcp nowait root /usr/local/libexec/qpopper qpopper
本当は-sを-dにすればいいはずなのですが、なぜかうまくいかず全部取ったらうまくいきました
これでログは
/var/log/qpopper.log
のみになります

9.POPS(TLS/SSL)

さて受信も暗号化しましょう
qpopperだと意外と簡単でした
まず下記ファイルを作成します
/usr/local/etc/qpopper.config
set clear-text-password      = ssl
# この場合はAPOPだけになるので、APOP無しのSSLのみの場合はalwaysにする
set reverse-lookup           = false
set statistics               = true
set timeout                  = 600
set tracefile                = /var/log/qpoppers.log
set tls-support              = alternate-port
set tls-private-key-file     = /usr/local/etc/letsencrypt/live/hogehoge.mydns.jp/privkey.pem
#set tls-server-cert-file     = /usr/local/etc/letsencrypt/live/hogehoge.mydns.jp/cert.pem
# 中間証明書を含めないサーバー証明書「cert.pem」を指定するとスマホでエラーしたので中間証明書を含む証明書に変更します。
set tls-server-cert-file     = /usr/local/etc/letsencrypt/live/hogehoge.mydns.jp/fullchain.pem
set shy                      = true

/etc/inetd.conf に追記
pop3s stream tcp nowait root /usr/local/libexec/qpopper -s -f /usr/local/etc/qpopper.config qpopper
これでinetdを起動し直せば終了です

10.メーラーの設定

すべて動いた所でメーラーを設定します
私はBeckyを使用していますのでBeckyで設定を説明します
アカウントの設定を開きます

赤丸のPOP3s?SMTPSへチェックを入れます
APOPまで行った場合は認証方式のAPOPを選んで下さい。
次に詳細タグへ切替えて

SMTPとPOP3のポート番号は自動で切り替わっているのを確認します
そしてSMTP認証とCRAM-MD5をONします
もし、項目4で説明したパスを変えている人はその下のユーザーIDとおパスワードへ入力しましょう
個人個人設定しないで送信は1種類にするという方法もありますね。
あと、SSL/TLS関係では「証明書を検証しない」「クライアント証明を使用」の2点をONにします
自分で作成した証明書なので検証するとエラーします
証明書がタダで証明してくれる所が有ればApacheも含めてスマートにできるんですけどね
と、これでメールを送受信して見ましょう
リレーを許可していなくてもリレー送信できます
もしFirewallを使用している人は上記ポート番号を開ける事を忘れないで下さい。

11.スパム制御

sendmailでは受け取りたくないドメインやアドレスが指定できます。
webminはこちらから設定できます。

もしくは直接編集して設定します。
/etc/mail/assess
117.114               550 We don't accept mail from spammers  #IPでブロック
net.th                550 We don't accept mail from spammers  #ドメイン名でブロック
From:lxpyjeh.net      550 We don't accept mail from spammers  #fromでブロック
163.com               REJECT                                  #黙ってブロックする場合はREJECTにする

編集が完了したら、そのままのデータでは有効になりませんのでファイル変換します。
# makemap -v hash access.db < access
これでaccees.dbへ変換されます。

あとはmcファイルで指定します。
FEATURE(access_db, `hash -o -T<TMPF> /etc/mail/access.db')
終わったらM4をリビルドしてsendmailを立ち上げ直せば完了です。