2022年7月2日土曜日

curlやtelnetを使って添付ファイル付きメールを送信する

メールサーバの構築時などにおいて、作業環境にThunderbirdなどのメールクライアントが導入されておらず、メールの送信確認ができない状況がある。

そのような状況であっても、telnetコマンドを使って直接SMTPのコマンドを実行することでメール送信を行うことができる。なお、近年のLinuxディストリビューションではtelnetコマンドはデフォルトではインストールされていないが、以下のようにcurlコマンドにてtelnetコマンドと同等の処理が可能となる。

curl -v telnet://[接続先IPアドレス]:[ポート番号]

例えば、単純なメールを送るだけであれば、以下のようにTelnetによるコマンド実行をすればメール送信は可能である。

# curl -v telnet://[メールサーバのIPアドレス]:[ポート番号]
helo example.com
mail from: <送信元メールアドレス>
rcpt to: <宛先メールアドレス>
data
From: 送信元メールアドレス
To: 宛先メールアドレス
Subject: 件名

メール本文
.
quit

しかし、メール本文だけではなく添付ファイル付きのメールを送信する場合はもう少しコマンドが長く複雑となる。

本記事ではcurltelnetを使って添付ファイル付きメールを送信する手順を記載する。

環境

本コマンドは、RHEL 7およびRHEL 8の環境で確認しており、問題なく稼働することを確認した。それぞれのcurlのバージョンは以下の通り。

OS curlバージョン
RHEL 7.6 curl 7.29.0
RHEL 8.3 curl 7.61.1

telnetを使ってSMTPで添付ファイル付きメールを送信する手順

1. 添付ファイル付きメールを送信するコマンド

以下コマンドにて添付ファイル付きのメール送信が可能となる。curlコマンドに対して、パイプで複数行にわたるコマンドの実行結果を渡すことで、Telnetで実行したいコマンドを一気に流すことができる。

attachment="添付ファイル名"
from_address="送信元メールアドレス"
to_address="宛先メールアドレス"
subject="メール件名"
message="メール本文"

( echo "helo example.com"
echo "mail from: <${from_address}>"
echo "rcpt to: <${to_address}>"
echo "data"
echo 'Content-Type: multipart/mixed; boundary="ABCDEFGH12345678"'
echo "MIME-Version: 1.0"
echo "From: ${from_address}"
echo "To: ${to_address}"
echo "Subject: ${subject}"
echo ""
echo "--ABCDEFGH12345678"
echo "Content-Type: text/plain; charset=UTF-8; format=flowed"
echo "Content-Transfer-Encoding: 8bit"
echo ""
echo "${message}"
echo ""
echo "--ABCDEFGH12345678"
echo "Content-Type: application/x-zip-compressed; name=\"${attachment}\""
echo "Content-Disposition: attachment; filename=\"${attachment}\""
echo "Content-Transfer-Encoding: base64"
echo ""
echo $(cat "${attachment}" | base64) | tr " " "\\n"
echo ""
echo ""
echo "--ABCDEFGH12345678--"
echo "."
echo "quit"
) | curl -v telnet://[メールサーバのIPアドレス]:[ポート番号]

curlではなくtelnetコマンドを使いたい場合は、最後の行のコマンドをtelnetに変更すれば同様に動作する。

添付ファイルのデータはBase64エンコードし、文字列として記述する必要があるため、base64コマンドにて変換する。ただし、エンコードした文字列をechoで表示すると、改行が失われて空白文字に置換されてしまうので、再度trコマンドに渡して改行コードに置換する処理を入れている。

2. 実行結果

実際の実行結果は以下の通り。250 okが出ていればメールは正常に送信できている。

# attachment="test.zip"
# from_address="from@example1.com"
# to_address="to@example.com"
# subject="Test mail"
# message="Test message."
# 
# ( echo "helo example.com"
> echo "mail from: <${from_address}>"
> echo "rcpt to: <${to_address}>"
> echo "data"
> echo 'Content-Type: multipart/mixed; boundary="ABCDEFGH12345678"'
> echo "MIME-Version: 1.0"
> echo "From: ${from_address}"
> echo "To: ${to_address}"
> echo "Subject: ${subject}"
> echo ""
> echo "--ABCDEFGH12345678"
> echo "Content-Type: text/plain; charset=UTF-8; format=flowed"
> echo "Content-Transfer-Encoding: 8bit"
> echo ""
> echo "${message}"
> echo ""
> echo "--ABCDEFGH12345678"
> echo "Content-Type: application/x-zip-compressed; name=\"${attachment}\""
> echo "Content-Disposition: attachment; filename=\"${attachment}\""
> echo "Content-Transfer-Encoding: base64"
> echo ""
> echo $(cat "${attachment}" | base64) | tr " " "\\n"
> echo ""
> echo ""
> echo "--ABCDEFGH12345678--"
> echo "."
> echo "quit"
> ) | curl -v telnet://192.168.1.1:25
* About to connect() to 192.168.1.1 port 25 (#0)
*   Trying 192.168.1.1...
* Connected to 192.168.1.1 (192.168.1.1) port 25 (#0)
220 mail.example.com ESMTP
250 mail.example.com
250 sender <from@example1.com> ok
250 recipient <to@example.com> ok
354 go ahead
250 ok:  Message 10164 accepted
221 mail.example.com
* Closing connection 0

実際にThunderbirdで確認したメール送信結果は以下の通りとなる。きちんとメールが送信され添付ファイルが付与されていることがわかる。

以上で、curltelnetを使って添付ファイル付きメールを送信する手順は完了となる。

1 件のコメント:

  1. 添付ファイルを複数指定した場合どうしたらよいでしょうか

    返信削除

人気の投稿