curl で smtp 経由でメールを送信する。
curl で送信できる。めっちゃ便利だわこれ。
シンプルなメール
curl -v --url 'smtp://127.0.0.1:2525' \ --mail-rcpt admin@exp.tld\ --mail-from takuya@exp.tld \ -T - <<EOS To: takuya@exp.tld From: takuya@exp.tld Subject: this is a test this is a test using smtps EOS
シンプルメールなのにコマンドはシンプルじゃない.
メールを送るには「本文=To:,From,Subject, body」が必要だからどうしても長くなる。
シンプルなメール(手抜き版)
お手軽に送りたい。上記のようなちゃんとしたメールを投げるのは大変ですよ。
curl -v --url 'smtp://127.0.0.1:2525' \ --mail-rcpt takuya@ex.tld \ --form-string text='hello'
かなり省略している。多少エラーが出るかもしれないが、届くはずである。
これはメールボディを作らずに「テキストファイルを添付」してる。
手抜きしまくりです。でもほとんどのサーバー相手では、これでサクッと送信できる。
CC の例
メールは封書なので、封書(Envelope=mail-from,mail-rcpt)と本文(To: , CC: ) で分けて書く必要がある。
curl -v --url 'smtp://127.0.0.1:2525' \ --mail-from admin@exp.tld \ --mail-rcpt takuya@exp.tld \ -T - <<EOS To: takuya@exp.tld CC: admin@ex.tld From: admin@exp.biz Subject: this is a test BCC/CC this is a test using smtps EOS
添付ファイル付き
curl -v --url 'smtp://127.0.0.1:2525' \ --mail-rcpt takuya@example.tld \ --form "sample-file=@/home/takuya/project/.gitignore"
curl のSMTPでは、メールを送るときは、「本文」が添付ファイルとして扱う。 一方で、添付ファイルがある場合は、Multipartになる。本文もマルチパートになるが、そのへんはサクッとかける。
Base64エンコードするもの(写真など)
ただ、上記の場合は、エンコードが必要なファイルが多重エンコードされておかしくなる。壊れる。そこで、写真やTar.gzやZipファイルなどは次のようにする。
curl -v --url 'smtp://127.0.0.1:2525' \ --mail-rcpt takuya@example.tld \ --form "photo=@out.png;encoder=base64"
詳しくは、man curl に書いてある。
メール本文
cat <<EOS > sample-mail.txt To: takuya@exp.tld CC: admin@ex.tld From: admin@exp.tld Subject: this is a test BCC/CC this is a test using smtps EOS curl -v --url 'smtp://192.168.1.1:2525' \ --upload-file sample-mail.txt \ --mail-from takuya@example.com \ --mail-rcpt takuya@example.com
冒頭の cutl -T -
はこの「添付ファイル」を入れた処理である。
-T
は -T / --upload-file
であり同じ意味である。
ファイルを添付する
単純にファイルを添付する
curl -v --url 'smtp://127.0.0.1:2525' \ --mail-rcpt takuiya@example.tld\ -F photo=@/path/to/sample.txt
マルチパートのファイルは、-F --form
項目として取り扱う。
BCC
BCC は mail-rcpt (recipient) を複数書く
curl -v --url 'smtp://192.168.1.1:2525' \ --mail-from takuya@example.com \ --mail-rcpt takuya@example.com --mail-rcpt boss@example.com ...
SMTPプロトコルでは、Envelope指定でRCPT TO: addr
を使う。
このときBCCならSTMP通信中にRCPT TO: addr
RCPT TO: addr2
と複数回書く。
なので、--mail-rcpt
が複数回登場する。
実際のcurl通信ログの例
* Connected to 127.0.0.1 (127.0.0.1) port 2525 (#0) < 220 localhost says welcome! > EHLO acid < 250-localhost at your service! < 250-8BITMIME < 250-SMTPUTF8 < 250 OK > MAIL FROM:<admin@example.tld> < 250 OK > RCPT TO:<admin@example.tld> < 250 OK > RCPT TO:<takuya@example.tld> < 250 OK > DATA < 354 Enter message, ending with "." on a line by itself
このように、BCCは配送される。
curl で送信が便利。
SMTPプロトコルを喋るために、sendmail や snail を覚えなくて済む。
何より、SMTPメールサーバーを指定できるのが嬉しい。sendmail コマンドとだとローカル配送から考えないといけないし。
smtp をTELNETで接続してメール送信テストしなくて済む。 ポート解放をしておけば、あとあと困らないでメール送信ができますね。
curl って万能ですね。
ELHO ホスト名を指定する場合
Postfixをポートフォワーディングで使っていて、 Helo command rejected: need fully-qualified hostname
となる場合
curl -v --url 'smtp://192.168.1.1:2525/smtp.example.com' \ --mail-from takuya@example.com \
このように、スラッシュのあとに、EHLOのホスト名を追記すればいい。
curl で smtps で gmail 経由する場合
メールのログインとパスワードを追記したら SMTP-AUTH を経由してSMTPSでメールが送信できる。
curl --url "smtps://smtp.gmail.com:465" \ \ --ssl-reqd --mail-from "sender@gmail.com" \ --user "sender@gmail.com:senderGmailPassword" \ \ --mail-rcpt "example@gmail.com"\ --upload-file /var/scripts/mail.txt \
GMAILのメール送信もcurl で1行でできるので、google の 「 less scure app ( 安全性の低いアプリ)」が1ヶ月未使用ならオフにされちゃうので定期的にログインしておくのに良さそう
postfix 相手にSMTPS (SSL / starttls ) で、オレオレ証明書
Postfixがオレオレ証明書を使っていて、Submissionポート 587 を通して接続する場合
startls は内部がSMTPなので、smtp:// を使う。smtps ではない。ただし、starttls でSSLを使うので --ssl
をつける。さらに、証明書がオレオレ証明書なので -k / --insecure
をつける。
curl -v --url 'smtp://10.185.93.22:587/mailcow.example.com' --ssl -k
さらに、それが、SMTP Auth を経由する場合
curl -v --url 'smtp://10.185.93.22:587/mailcow.example.com' --user "takuya@example.com:PASSWORD" --ssl
なんかオプションが増えて大変だけど、ちゃんと送信できる。
TO / FROM を正確に記述する
curl は to(recpt) / from をSMTPのプロトコルにつかうので、メールの本文のFROM/TOは書き換えは行われない。当然であるが。
メールのボディを指定して、FROM/TOとSubjectを正確に記載すると普通のメールとして送信が可能。SMTPの動作チェックであればなくても構わないので上記まででは省略してた。
echo 'To: takuya@example.com From: takuya@mydomain.tld Subject: this is a test from 465 this is a test using smtps ' \ | curl -v --ssl --url 'smtps://mailcow.mydomain.tld:465' \ --mail-from service@mydomain.tld \ --mail-rcpt takuya@example.com \ --user "account@mydomain.tld:XXX_PASS_XXX" \ -T -
ここでは、--mail-from
と、ボディの From:
と、--user
は、敢えてすべて異なるようにしている。SMTPではこれらを一致させる必要はなく、実際にこれで送れてしまうのだ。
一般のメールだと、拒否されるかもしれないが、smtp replay に直接投げ込みできると送信が可能なのである。
そして、From:
が受信者のメーラーで表示されるはずだ。 ---mail-from
は smtp プロトコルだし、--user
はSMTP Auth用である。ややこしいですがそういうものなんでしょうね。
curl はほとんどの環境で使える。
curl はWindows に添付された ( C:/Windows/System32/curl.exe ) ので、すべての環境で使えるコマンドになった。
curl未インストールは、 alpine や debian 軽量版など、特殊状況に限られるようになった。
curl だけでメールは送れるし、コマンド呼び出しで使えるのである。
メールプログラムを書く、ライブラリをインストールするなど、車輪の再発明するくらいならcurl でいいのである。
2022-03-15 追記
EHLOについて追記。
2022-03-16 追記
メールボディ指定、FROM / mail-fromについて追記。
2024-09-08 追記
BCCについて追記。
CCに付いて追記。
コマンドを整理してパイプをなくすなど
写真の添付がうまくいかなったので調査した。
参考資料
16 Command Examples to Send Email From The Linux Command Line