イベントで登壇した際に以下のスライドでもお話しさせていただきました!
背景
業務でメール送信サーバー周り(使っているのはSendGrid)のタスクをすることがありました。
メール送信用サーバーと通信をしてメールを送信していることは分かりました。
概要を掴みたいと思います。
SMTPとは
Simple Mail Transfer Protocolの略です。
SMTPはメールを送信する際のプロトコルです。
認証の機能はありません。
GmailのSMTPサーバーを使ってGmailを送信する
今回は自分宛に送信します。
SSL
- インターネット上の通信を暗号化するための仕組み
TLS
- SSLの後継の仕組み
ESMTP
- ESMTPはSMTPを拡張したプロトコルで主に以下をサポートしている
- 認証
- TLS暗号
- メッセージサイズの拡張
- バイナリデータの送信
- GMailのSMTPサーバーもESMTPプロトコルで通信している
- EHLOを送ることでSMTPサーバーがESMTPの拡張機能(AUTH/STARTTLS 等)の対応可否を通知する
以下をターミナルで順に実行するとGmailを自分に送ることができます。
# gmailのSMTPサーバーにTLSプロトコルで接続する
openssl s_client -starttls smtp -connect smtp.gmail.com:587 -crlf -quiet
# SMTPサーバーからグリーティングメッセージを受け取った後に送る、認証コマンドを使うため
EHLO example.com
# 認証(Gmail)
AUTH LOGIN
# gmailアドレスのbase64エンコードの入力指示(334 VXNlcm5hbWU6)が出たら送る
xxxxxxxxxxxxxxx
# App Passwordのbase64エンコードの入力指示(334 UGFzc3dvcmQ6) が出たら送る
# https://myaccount.google.com/apppasswords
xxxxxxxxxxxxxxx
# 235 2.7.0 Acceptedが表示されたら、メールの送信元を打つ <>で囲む
MAIL FROM:<xxxxxxx@gmail.com>
# 250 2.1.0 OKが表示されたら、メールの送信先 <>で囲む
RCPT TO:<xxxxxxx@gmail.com>
# 250 2.1.5 OKが表示されたら、SMTPサーバーにメール本文を送るための指示
DATA
# 354 Go ahead が表示されたら、メールの件名
Subject: test
# メールの本文
test
# メール本文の終了の印が.
.
# 250 2.0.0 OKが表示されたら送信完了
実際に自分宛にgmailを送れました。
Goで開発用SMTPサーバーに接続してメールを送る
maildevでメール送信をテストできる
maildevを使います。
メール送信をテストできるSMTPサーバーです。
以下のようにUI上で確認できます。

以下の記事ではターミナルでmaildevにメールの送信テストをしていますのでご覧ください。
Goで実装する
今回実装したものは以下にあります。
サーバー側のバッチで定期的にメールを送るようなシーンを想定しています。
今回は単純にメールを送る処理を書きます。
net/smtpパッケージを使ってsmtp通信をします。
先ほどのmaildevをSMTPサーバーとして使用します。
このファイルを実行するとメールを送信できます。
go run send_mail/main.go
Mail sent successfully!
maildevにアクセスします。
http://localhost:1080/#/
確かにメール送信ができていることが確認できました。
SASLについて
業務でSMTPサーバー(ESMTPの拡張機能の使用可能なもの)の認証でSASLを使用してたので調べてみます。
SASLとは
- Simple Authentication and Security Layer の略
- 認証のやり取りと認証情報の保護に関する仕組みを用意しているフレームワーク
まとめ
- SMTPはメールを送信する際のプロトコル
- ESMTPはSMTPを拡張したプロトコルで主に以下をサポートしている
- 認証
- TLS暗号
- メッセージサイズの拡張
- バイナリデータの送信
- メール送信周りの開発では誤送信対策や、負荷テストの用途でSMTPサーバーを模倣しているサーバー(例;maildev)が使われる
- SASLはhttp、SMTP等で必要な認証機能を提供してくれるフレームワーク
今後勉強したいこと
- メールの受信側、閲覧する際に使われるPOP3プロトコルについて
- telnetコマンド、その他通信で使用したコマンドについて



