port forwarding
さて、前回までにメールの送信はできるようになっていますので、今回は sendmail 関連の最終章として、sendmail によるメールの受信、DMARC による偽メールのブロック、IMAP によるメールクライアントの接続の順で書いてゆきたいと思います。まず、dhcp さんの sendmail でメールの受信を行うには、ISP ルータの設定をいじる必要があります。IPv4 の場合は、ISP ルータが持っている IPv4 パブリックアドレスの tcp ポート 25 番と 587 番を dhcp さんのアドレスである 192.168.0.250 の tcp ポート 25 番と 587 番に転送してやる必要があります。では、ISP ルータが持っている IPv4 パブリックアドレスをどうして知るかというと、各種 WEB サイトがありますので ( “myip” などを検索して得られるサイトなど )、それらをお使いいただくか、curl コマンドなどでも取得することができます。こんな感じです。IPv4 のアドレスはブラウザを使用して得られた IPv4 アドレスと通常一致します。なぜなら PAT という技術を使用していることが多いからです。ですので、ご家庭内で同じ ISP ルータを経由してインターネットへつながっている全ての機器は同じ IPv4 アドレスを使っていることがほとんどです。このようなことをしないといけなくなった原因が IPv4 アドレスの枯渇が最大の理由です。例えば tcp のポートとして使用できるのは 64K 個あります。ですので、ISP ルータで使用するソースポートを管理することで、見かけ上1つの IPv4 アドレスを 65000 個以上のデバイスで共有することができます。

一方、IPv6 アドレスは ISP ルータの内側でもパブリックアドレスが使われます。元々 IPv6 アドレスは IPv4 アドレスの枯渇から脱出するために作られたものなので、PAT などという姑息な手法を用いずとも、十二分なアドレススペースを得ることができるようになりました。IPv4 アドレスは 32bit ですが、IPv6 アドレスは 128bit のアドレス長があります。アドレス長はたったの4倍ですが、アドレス数は IPv4 アドレス全空間が2の96 [ 128 – 32 ] 乗倍定義することができますので、ほぼ無限と言っていいくらいあります。ですので、アドレスが足りなくなってきたことで作られた IPv4 プライベートアドレスのような概念は、そもそも IPv6 にはありません。ですので、IPv6 のアドレスは curl などを使わずとも、ifconfig で得られるアドレスがパブリックアドレスとなります。こんな感じです。

ifconfig に物理インターフェースを指定して得られた IPv6 アドレスで、fe80 で始まるものはリンクローカルアドレスと呼ばれ、そのインターフェースがつながっている同じセグメント内のみで使用できるアドレスです。もう一つの 2001 ( 私が使用している ISP の場合 ) で始まっているアドレスがパブリックアドレスになります。Windows などのクライアントデバイスはさらに一時 IPv6 アドレスと呼ばれるパブリックアドレスも持ち、通常の接続はこのアドレスから行い、本来の IPv6 アドレスを隠すことができます。まぁ、なんと贅沢な使い方なのでしょうか? dhcp さんの場合は、サーバとして使用することもあり、自動で割り当てられる IPv6 アドレスは長いので、短くなるように手動で割り当てています。因みに 私が使っている ISP が提供している IPv6 アドレスの prefixlen は 64 となっていますが、これは IPv4 アドレスのサブネットマスクに相当するものです。prefixlen が 64bit なので、128bit アドレスの半分のアドレス空間を一個人に割り当ててくれて、そのうちであれば自由にアドレスを使えるということを意味しています。これだけでも全 IPv4 アドレス空間の 2 の 32 乗倍のアドレス空間を一個人で使えるということを意味していますので、PAT などという姑息な発想が不要だということはわかると思います 🙂
dns mx record
さて、話が脱線してしまいましたが、これらの IPv4 と IPv6 アドレスを内側の DNS 同様に外部の正規の DNS にも MX レコードとして登録する必要があります。メールはこの MX レコードの設定に従ってメールを配送してくれます。正規の DNS に MX レコードを登録してみました。こんな感じです。

元々の MX レコードは jf3vqb.net が 10 のプライオリティで登録されており、これしかありませんでした。これを smtpauth.jf3vqb.net をプライオリティ 10 として新規追加して、jf3vqb.net のプライオリティを 20 と変更しました。この変更で、世間のメールサーバは smtpauth.jf3vqb.net にまずつなげようとします。これがつながらなければ jf3vqb.net につなげようとします。ですので、smtpauth.jf3vqb.net がプライマリの SMTP サーバで、ISP の jf3vqb.net がセカンダリ、つまりバックアップとして使用されるということになります。それぞれのアドレスはこんな感じです。google DNS に問い合わせたものが世間一般のメールサーバが得るアドレス情報で、もう一方が家庭内のクライアントが得ることになるアドレスです。IPv6 アドレスは同じですが、IPv4 は異なるアドレスとなっています。

smtpauth.jf3vqb.net というマシン名が家庭内でもインターネットでも使えて、アドレスが異なるのは後に実験してみる IMAP によるクライアント接続のためです。smtpauth.jf3vqb.net というマシン名でアクセスできるようにしておけば、ネットワーク機器は IP アドレスしか理解しませんが、DNS が現在つながっているところに応じて適当な IP アドレスを提供してくれます。既に、ISP ルータにおける IPv4 ポート転送と、IPv6 の通過は既に設定済みと仮定して話を進めます。試しに、ホスティングしているインターネットにあるサーバからポートに接続できるか試してみます。

/var/log/maillog
IPv4、IPv6 ともにおなじみの dhcp さんの名前が見えます 🙂 因みに xxxx.xxx.ne.jp:22 としてつながった先は jf3vqb.net の SMTP サーバとしてメールも送受信する正規の SMTP サーバです。ですので SMTP ポートはブロックされていません 🙂 因みに OS は FreeBSD 13.0 です 🙂 さて、この状態で、外部からメールを送ると既に dhcp さんの sendmail につなげてきます。メールのログをちょっと見てみます。

最後の2つは私が借りているサーバからの IPv4 と IPv6 接続のテストです。それ以外にも数多くのスキャナが巡回しています。あからさまに .cn からの接続は好きになれませんねぇ 🙂 ISP ルータの設定を変える時に何をしているのかがわからない場合は何もしないことをお勧めした理由がお分かりいただけると思います。お試しで、gmail.com からメールを送ってみたいと思います。既に dhcp さんの MX レコードのプライオリティが一番高いですので、メールを直接送り付けてくるはずです。届きました。

メール自体はこんな感じです。

えっ? 何を書いたかって?こちらです 🙂

opendmarc
UTF-8 の文字コードを base64 でエンコードしています。ですので、逆の手順を踏めば元がなんであったかわかります。文字列を base64 でデコードしてやれば tera term が UTF-8 を理解してくれます。これで、メールが受信できることが確認できました。次は DMARC で偽メール対策をしてみたいと思います。DMARC として使用できるソフトウェアとして使用するのは opendmarc を使用してみたいと思います。他には Amavisd SPAM フィルタなどを思いつくのですが、どちらかというと SPAM フィルタとしてのイメージが大きいので、DMARC の処理がよくわかるように opendmarc を使ってみます。ポーツのディレクトリから make 一発コンパイルします。

インストール時のメッセージは特に出力されませんでした。設定ファイルは opendkim と同じく /usr/local/etc/mail に置かれます。コメント行と空白行を除くと何もなくなりました。ということで、man opendmarc を参考にしてオンラインドキュメントを見ることにします。基本 SPF 情報と DKIM 情報を確認して問題があれば DNS の指示通りに MILTER インターフェースを使って sendmail をコントロールする指示を出すだけのはずなので、仰々しいドキュメントは不要なのかもしれません 🙂 早速やってみましょう。

インストール直後の状態です。先ほどの opendmarc.conf.sample ファイルがあるのみです。opendmarc.conf にコピーして編集してゆきます。まずは、ファイル内のコメントを参考に変更してゆきます。DMARC チェックに引っ掛かって、なおかつ隔離するように DNS で指定している場合に本当に隔離するかどうかを指定します。当然隔離してほしいです 🙂 そのための DMARC です。

同様に拒否するように DNS で指定しているメールを本当に拒否するかどうかを指定します。当然そのようにしてほしいです。

From にドメインが異なる複数のアドレスがあるなど、不審なメールを拒否するか? してください。

RFC5322 に定義されている以外の不審なメッセージフォーマットのメールを拒否するか ? はい、してください。

他サイトで付けられた SPF チェックに関するヘッダを信じますか? 信じません 🙂

じゃぁ、自分で SPF チェックしますか? 勿論です 🙂

あなたは syslog を信じますか? はい 🙂

syslog のファシリティはデフォルトの mail で結構です。これはデフォルトのようです。

では早速動かしてみましょう。起動ファイルを確認して追加すべき変数を /etc/rc.conf に追加して起動スクリプトを実行します。結果、このように opendmarc が動いていれば OK です。

では、どうやって DMARC を sendmail から使うのでしょうか? opendmarc.conf ファイルを編集してゆく中で MILTER インターフェースの話が出てきています。ですので、ソケットインターフェースのスペックを確認して MILTER インターフェースの設定を加えてみましょう。sendmail の設定の元ファイルを編集します。

そして、他の MILTER の設定と同じように追加し、sendmail.cf を作って再起動をかけます。

試しにメールを送ってみて動きを見てみます。ちょっと話はそれますが、ちょっと記事を書いている間にもスキャンしにしています 🙁 ご注意ください。ついさっきポートをオープンしたところなのに 🙁 🙁

話を元に戻して、gmail.com からメールを送ってみます。メッセージが増えたので2ページでご紹介。


IPv6 で接続してきたようです。しっかり gmail.com の SPF と DKIM チェックの結果を確認して DMARC がパスしています。最終行には local mailer にリレーしてステータスとして sent となっています。問題なさげです。では、telnet を使って偽メールを送り付けてみます。適当な DKIM 署名をどこかのメールからとってきてそれを使ってみます。こんな感じです。こちらもちょっと長いので2ページです。因みに jf3vqb.net ドメインとは全く関係のない Azure US にある FreeBSD からのテストとしました。


配送はできたように見えます。dhcp さんのログではどのようになっていますでしょうか?こんな感じです。

SPF、DKIM ともに fail となっています。ですので、jf3vqb.net サイトの DMARC の DNS 設定に基づいて、隔離となっています。本当に隔離されたか見てみます。最後のメールは偽メールの前に送った gmail.com からのテストメールです。

ではどうなったかというと、こちらに隔離されているのです。

ここに溜まっているメールは dhcp さんの場合 ClamAV で検疫されたメールと、DMARC に引っ掛かったメールなので、Windows PC に持って行って中身を見てみようとはしないでください。感染してしまいますよ 🙂
cyrus-imapd
今回は IMAP を入れてメールクライアントを使って送受信までしたかったのですが、嫁さんからの大掃除コールが響いていますので、今年中に完結するかどうかは微妙なところです。もしかけなかった時のために一言、皆さんよいお年をお迎えください。
まだ年は明けていませんが、少々時間ができましたのでもう少し。dhcp さんのメールのログを見ていると、DMARC のお気に召さないメールが届いていました。

お仲間の FreeBSD 諸氏のメールがブロックされてしまいました。ホワイトリストを作成しましょう。opendkim と全く同じ内容となりますので、opendkim のファイルをそのまま指定します。

これでブロックされないはずです。また必要に応じて変更します。さて続いて IMAP を使えるようにしましょう。ポーツツリーを見てみます。何種類かあるようですが、cyrus-imapd が華やかそうなので、これの一番新しそうなものをインストールします。

make 一発 🙂

インストール時に表示されたメッセージを確認しておきます。少し上の方にあるはずです。スクロールアップしてみます。設定も簡単なようです。”imapd.conf を適当に変更して mkimap を実行するだけ” と書かれています 🙂

では imapd.conf を順に変更してゆきます。セパレータは UNIX 方式の ‘/’ を使います。

サーバ名は前もって DNS に登録した smtpauth を使用します。TLS で暗号化しますので、PLAIN TEXT パスワードも OK とします。

管理者アカウントを cyrus とします。

Kerberos も使うかもしれないので realm を入れておきます。

sendmail で使用している saslauthd を使います。そして、素のテキストも使用可にします。

certificate
最後に TLS の証明書を指定します。sendmail では dhcp の名前で出ていますが、imap では smtpauth の名前で出たいので、証明書は smtpauth として作ります。とりあえず、server.* として指定しておきます。root 証明書は sendmail と共通で、CA ファイルのディレクトリとして ca_root_nss で作られた root 証明書のあるディレクトリを指定します。

次に、smtpauth の証明書を作ります。認証局は krb5 さんに作りました。まず openssl.cnf ファイルを編集し、マシン名を smtpauth に変更します。

そして、証明書を作成し、ナンチャッテ認証局の署名を付けます。

ホスト名があっていることを確認したら先に進みます。

完成!

セキュリティに気を付けてファイルを dhcp さんに持ってゆく準備をします。

dhcp さんに持ってゆきます。

まず、sendmail にもサーバとして動いたときに smtpauth と答えてほしいので、サーバ証明書を今持ってきたものに置き換えます。sendmail.cf の元ファイルを編集します。

サーバ証明書を今コピーしてきたものに書き換えて、sendmail.cf を作り直して sendmail を再起動します。

エラーが無いかログを確認します。相変わらずアタックを受けています 🙁

では、imapd を起動してみます。マニュアルによると、imapd はこの master プロセスからフォークされるようです。imapd や ipopd 専用の inetd みたいな動きをするようです。

pop3 や imap 関連のポートがオープンしていることが確認できます。

pam -> sasldb
ここで一つ考えます。元々 sendmail の smtp auth を使おうと思った時は OS に作ったユーザのパスワードを使おうと考えていました。ただこれだけアタックを受けていることを考えると、複雑なパスワードを使えるようにしておいた方がよいと思いなおしました。saslauthd はそのまま使用したいのですが、パスワードデータベースを PAM から SASLDB に変更したいと思います。そうすると、ログイン自体は普段使いの比較的平易なパスワードが使えて、メールクライアントに保存するパスワードは複雑度 MAX のパスワードが使えるようになります。これを実現するために各所に変更をかけます。まず、saslauthd の起動オプションを pam から sasldb に変えます。

ユーザを作って動作確認しておきます。まず cyrus ユーザは imapd.conf に定義した管理者のアカウントです。pokemon は私のアカウントです。まず簡単なパスワードで作成し、動作確認を行って、確認が取れたら複雑なパスワードに置き換えます。文字列が変わるだけで saslauthd 経由で認証は通るはずです。

先に進む前に、ログを見やすくしておきたいと思います。マニュアルから syslog ファシリティ local6 で出力されるということなので、専用のファイルに出力されるようにしておきます。

見やすくなりました 🙂 マニュアルによると、imap 専用のメールストアにスプールする必要があるということです。先ほど作った pokemon ユーザにメールボックスを作ります。

sendmail の元ファイルを修正して、imap 専用のストレージにメールが届くようにします。マニュアル通りに sendmail を設定します。

そして wordpress さんからテストメールを送ってみます。

dhcp さんのメールログを見てみます。

email client on iPhone
新しく作った cyrus2 mailer でステータスが sent となりました。imap クライアントをつないだら今送ったメールが届いているはずです。その前に当初の目的の smtpauth.jf3vqb.net で家庭内でもインターネットでも IMAP で接続できるようにするため、ISP ルータに tcp ポート 993 がポート 25 や 587 同様、dhcp さんに届くようにルールを追加します。今回は pop3 はスコープ外、つまり使用しないこととします。/usr/local/etc/cyrus.conf を修正して pop を起動しないようにしておいても構いません。では、私の iPhone を imap のクライアントにしてみたいと思います。設定のメールを開いて、アカウント追加を行います。勿論選ぶのは一番下の Other です。

アドレス帳やカレンダーは今回スコープ外とします。ですので、メールアカウント追加を選択します。

ここで指定するパスワードはスクリーンショットだと空に見えますが、SASLDB に作った pokemon ユーザの複雑なパスワードを入力しています。

送信も受信もサーバ名は smtpauth.jf3vqb.net を使用します。送信メールサーバのユーザ名とパスワードは “Option” となっていますが、SMTP AUTH を使用するので、オプションではありません。同じユーザ名とパスワードを入力します。

しばらく待っていると、全ての項目にチェックマークが入り、メールだけが使用できると教えてくれます。こうならなければパスワードが間違っていると思われます。最後に保存して終了です。

IMAP では SSL を使用するようになっているか確認します。

SMTP の方も SSL を使用するようになっているか確認します。

troubleshooting
これで設定は完了のはずです。メールクライアントを開いてみます。開いてみたのですが、ずっとメールのチェックをし続けています。ログを見てみると、証明書に問題があるようです。

ちょっと調べてみたところ、証明書は root のみがアクセスできるようになっておりますが、imap のプロセスは cyrus ユーザで動いていました。つまり、先ほど作った証明書が読み込めない状況だとわかりました。そこで、ちょっと対策を行います。

さぁ、これでどないじゃ?

エラーが1つ見える以外は OK のようです。idled の文字列は cyrus.conf で見たような気がします。

これでしばらく様子を見てみます。次は送信のテストを行います。iPhone から gmail.com 宛にテストメールを送ってみます。

TLS による暗号化の上、pokemon ユーザで認証をパスしているがメールのリレーが拒否されて、iPhone メールの Outbox にとどまっています。sendmail の README を見てみると、信頼できる認証方式を指定しないといけないようです。

さぁ、これでどない?

今度は sendmail が怒り出しました。 🙁 証明書をコピーして別ファイルにしてそれぞれのパーミッションを与えます。

これで sendmail の怒りは収まりました。では、imapd.conf の証明書のファイル名を変えて再起動します。同じファイルをコピーして使用するのが嫌な場合、server.key のオーナーを cyrus にするのもありと思います。sendmail は root 権限で読むので、sendmail、imap 共にハッピーのはずです。

これで皆さん平和になったはずです。iPhone で送受信のテストをもう一度行います。

sendmail は通るようになりましたが、DMARC が激怒しています。opendmarc.conf を見直します。ありました、認証を通過したクライアントは無視することができます。

これでどうでしょうか?

やっと通過しました。mailer=relay で stat=Sent となりました。こちらが gmail.com に届いたメールのヘッダ情報です。

OK 屋上です 🙂 最後のテストは、iPhone の WiFi を切って、インターネット直結にして送受信できるかどうか試してみます。

SoftBank の IPv6 アドレスからの接続が確認でき、STARTTLS で暗号化を行い、ユーザ ID pokemon で認証を通過して、gmail.com に返信できました 🙂 以上で sendmail に関する話題は終了です。8回に分けた大作になってしまいましたが、ご参考になれば幸いです。くれぐれもご注意いただきたいのは、インターネットから直接ご家庭のサーバーにパケットが届くようになるということです。ISP ルータの設定には細心の注意を払ってください。それと、SASLDB のパスワードに 1234567890 などを使っていると、あっという間に踏み台サーバーにされてしまい、世間に迷惑をかけることになります。くれぐれもご注意ください。私の方もしばらく使用してみて、問題があればページの更新を行いたいと思います。ただ、実験用のアカウントなので、近々に設定は元に戻す予定ではあります。ただ、快適ならば使うかもしれません 🙂
では、よいお年をお迎えください。
以下広告





コメント