vCSA からメールを送信する

都合により vCSA から任意の Email をとばしたくなったので方法を調べてみた。


環境情報

まず前提かつ必要となる条件は以下である。

必須条件:

vCSA が正常に動作していること
宛先ドメインを解決可能な DNS が設定されていること(ラボ用と別でよい)
vCSA が DNS および SMTP サーバと適切に疎通可能であること

任意条件:

vSphere Client から SMTP サーバ IP を設定していること

意外に思うかもしれないが、vSphere Client から設定できる SMTP Server は必須ではないと判断している。
今回の環境ではメールサーバ都合で実際にメール送信が確認できなかったので、確証ではないがおそらく SMTP サーバの指定は必要ない。
一方で、DNS で宛先ドメインの MX レコードを引けることは必須であると思われる。
SMTP サーバの設定をした場合は、DNS で検索した MX レコードではなく設定した SMTP サーバが利用される。
ならば、DNS で宛先ドメインを解決できなくてもいいのではないか、と考えたくなるが、DNS で宛先ドメインを検索できない場合は Name Server Timeout になり、メールの送信が完了しない。

今回の環境では MX レコードで検索できる SMTP サーバが、セキュリティ都合で利用できなかったため、
vSphere Client で SMTP サーバを設定することで、MX レコードのメールサーバではなく、vSphere Client で設定した SMTP サーバに転送するようにしている。


DNSについての補足

DNS で宛先ドメインが検索できることが必須であると記載したが、この DNS サーバは仮想環境用の DNS サーバと異なっていてもよい。
言い換えると、仮想環境で VCSA が必要とする名前解決(ESXi や AD など)を提供する DNS サーバと、今回の目的であるメール送信の宛先ドメイン検索用の DNS サーバを2台設定しても問題ないという意味である。

DNS Client の挙動に多少の造詣のある人なら違和感を覚えるかもしれない。

通常、resolv.conf に DNS サーバが複数記載されている場合でも、名前解決で利用されるDNS は resolv.conf の一番上の DNS サーバが利用され、その DNS サーバにアクセスできる限り、2番目以降に記載されている DNS サーバに問い合わせされることはない、と教えられた人は多いと思う。私も新人の頃に実際にそう学んだ。

そのため、DNS サーバ側で転送設定をするなどして、自ドメイン以外の名前解決要求に応えなくてはならないのが普通である。
しかしながら IT の世界は日進月歩で進歩しているため、現在の技術ではより便利にDNS を利用することができ、宛先のドメインに応じて DNS サーバを使い分けることができる。
最近の Linux の一部の Distribution では、systemd-resolved という DNS Client がデフォルトになっており、この DNS Client を利用することでも、宛先ドメインに応じた DNS サーバの使い分けが可能だ。
systemd-resolved や DNS Client の挙動については以下の記事が大変参考になる。

vCSA ではどのようにしているかというと、systemd-resolved のような DNS Client 側での進歩というよりも、従来の DNS サーバ側の転送設定に近い仕組みでこの問題を解決している。(なので、systemd-resolved の話は忘れて構わない)

具体的にいうと、dnsmasq という簡易  DNSサーバが vCSA上で稼働しており、vCSA が発する名前解決要求はすべて dnsmasq へ送られるようになっている。(resolv.confの一番上に loopback address が記載されているのはそのため)

名前解決要求を受け取った dnsmasq は resolv.conf に記載されている DNS サーバ情報を取得し、検索ドメインに応じて適切な(解決可能な) DNS へリクエストを送信する。

つまり、特定の FQDN を解決可能な DNS サーバと、そうでない DNS サーバの両方を設定した場合でも、dnsmasq が自動的に解決可能な DNS サーバのほうに振り分けてくれるというわけだ。

したがって、仮想環境用の DNS と、 MX レコードを解決するための宛先ドメイン用のDNS サーバが別々に管理されていても問題ない。2つの DNS サーバが相互に連携するための設定や、レコードの追加も不要である。 


Email 送信コマンド

前置きが長くなったが、vCSAからメールを送信するためのコマンドは以下である。

# echo "test body" | sendmail -v -f hogehoge@hoge.com hogehoge@hoge.com

-v オプションを指定しているため、コマンドを実行すると以下のようにSMTPのやり取りが確認できる。

 

root@vc [ ~ ]# echo "email body" | sendmail -v -f sender@example.com rcpt@example.com
rcpt@example.com... Connecting to [127.0.0.1] via relay...
220 vcsa.example.local ESMTP Sendmail 8.15.2/8.15.2; Tue, 29 Jun 2021 16:45:27 GMT
>>> EHLO vcsa.example.local
250-vcsa.example.local Hello vcsa.example.local [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH GSSAPI CRAM-MD5
250-STARTTLS
250-DELIVERBY
250 HELP
>>> STARTTLS
220 2.0.0 Ready to start TLS
>>> EHLO vcsa.example.local
250-vcsa.example.local Hello vcsa.example.local [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH GSSAPI CRAM-MD5
250-DELIVERBY
250 HELP
>>> MAIL From:<rcpt@example.com> SIZE=12 AUTH=rcpt@example.com
250 2.1.0 <rcpt@example.com>... Sender ok
>>> RCPT To:<rcpt@example.com>
>>> DATA
250 2.1.5 <rcpt@example.com>... Recipient ok
354 Enter mail, end with "." on a line by itself
>>> .
250 2.0.0 15TGjRUr065088 Message accepted for delivery
rcpt@example.com... Sent (15TGjRUr065088 Message accepted for delivery)
Closing connection to [127.0.0.1]
>>> QUIT
221 2.0.0 vcsa.example.local closing connection


sendmail コマンドでメールを送信しているわけだが、接続先の SMTP サーバは vCSA 自身である。
これは、vCSA が sendmail サービスを稼働させているためである。sendmail コマンドによる Email 転送要求は vCSA自身の Sendmail サービスによって受信され、Sendmail サーバが vSphere Client で設定した SMTP リレーサーバを経由して宛先メールサーバに届く流れとなる。 
 
sendmail コマンド中で -f で sender address を指定しているが、これは必須ではない。今回利用した環境では sender address を明示的に組織の domain address にしなければ送信できなかったために、-f で明示的に sender address を指定しているに過ぎない。おそらくは、利用した SMTP サーバで SPF (Sender policy framework)が利用されているものと思われる。 
SPF についてはここでは説明しない。(知りたい人はググってほしい) 
 
Email Body の部分はファイルから読み込んだり、対話式で入力することも可能であるが、今後の利用体系に合わせて Oneliner で実現するために、echo した本文をパイプで渡している。 
 
以上がコマンドの解説である。


メールが飛ばない場合のトラブルシューティング

メールが宛先メーラーで受信できない場合、まずは DNS による宛先ドメインの名前解決や、SMTP リレーサーバ(vSphere Client で設定した SMTP サーバ)の機能を確認したほうが良い。 
また、SPF なども考慮し、送信アドレスは SMTP リレーサーバと同じ組織のものを利用するほうが良い。
また、以下のコマンドで sendmail のログを抽出するとも可能である。

# journalctl -u sendmail

また、以下のコマンドで sendmail サービスの mail queue を確認できる

# mailq

mailq についてや、df ファイルと qf ファイルについての説明は以下の記事が参考になる。

https://mytracking.hatenablog.com/entry/2016/09/03/042044


SMTP リレーサーバ側の問題の可能性を切り分けるため、vCSA の sendmail コマンド/サービスを利用せずにメール送信を試みることも有効である。
その場合は 、 telnet を利用して、直接メール送信を試すのが良い。
手順については以下の記事が参考になる。

https://qiita.com/sheepland/items/973198fa80f0213fe5a1


なお、vCSA には telnet コマンドは入っていない。ではどうするのかというと、curl コマンドを利用する。
curl コマンドは便利なもので、 curl -v telnet://<smtp_ipaddress>:25 として、protocol 部分で http/https ではなく、telnet を指定すると、smtp サーバの TCP 25 ポートと、telnet 接続が可能である。 
最近の Linux Distribution や、仮想アプライアンス製品は、telnet が入っていないことが多いので、 curl コマンドで telnet を代用するこのやり方は、サポートや運用担当者などはぜひとも覚えておきたい。 

 

コメント

このブログの人気の投稿

vSwitchにSTPが不要な理由

ESXi に DNS サーバを何個まで登録できるか

障害でVDSから切断されたVCSAの復旧方法