SMTPってどんなプロトコル?

はい、どうも。

 

今回はメールプロトコルでおなじみのSMTPについて調べたことを記述していきます。

 

一般的なSMTPでのメールの仕組み自体は、多くのサイトで解説しているのでそれらのサイトを参照していただけたらと思います。

 

今回僕が行ったことは、SMTPプロトコルのメール送信をGmailで確かめてみました。

 

どういうことか。以下の図を見ていただきたいです。

  f:id:k12si:20190325222830p:plain

 

まず、自分のPC => GmailSMTPサーバ へとopensslを用いてTLS接続を行います。

 

opensslとはSSL/TLS機能を実装したオープンソースライブラリです。今回はtelnetのように、遠隔のサーバにクライアントとしてログインする用途で用います。

 

SMTPサーバ内にSSL/TLSクライアントとして接続した後、SMTPサーバ内で、メール送信を試みます。

 

では、早速方法について紹介します。

 

方法

  1. Googleのアプリケーションパスワードを発行
  2. $ openssl s_client -connect smtp.gmail.com:465 -crlf -ign_eof  
  3. SMTPプロトコルのやり取りに準じてサーバにメール送信を依頼

順番に説明していきます。

 

まず、Googleのアプリパスワードを発行します。

これは、Googleアカウントへのアクセス権をアプリやデバイスに付与する16桁のパスワードです。

目的としては、GmailSMTPサーバにTLS接続をする際、アカウントの認証が行われます。その際、アプリケーションパスワードで認証を行うために必要となります。

詳しい説明は以下のURLで。

https://support.google.com/accounts/answer/185833?hl=ja

 

続いて、ターミナルなどでコマンドを実行します。

opensslの使い方は以下の通りです。

```

$ openssl コマンド [ コマンドオプション ] [ コマンド引数 ]

```

opensslを利用する際、コマンドというものが必須パラメータとなります。

今回指定した` s_client `はSSL/TLSクライアントとして動作するというコマンドです。

これにより、Gmailのサーバにログインすることができます。

続いて、オプションについて説明していきます。

` -connect `は接続するドメインとポート番号を指定します。

` -crlf `はターミナルから送られる改行文字をCR+LF(\r\n)に変換します。通常のターミナルのエンターキーではLF(\n)だけが送信されます。

` -ign_eof `は入力時に「end of file」がある時に、接続の切断を抑制します。「ignore_end_of_file」の略だと思われます。

s_clientでは入力に「R」もしくわ「Q」で始まる行があると、それぞれ「再接続」、「中断」と認識し切断されてしまいます。

これでは、後半で説明する「RCPT TP」という入力ができないため、このオプションを指定します。

 

さて、接続先のGmailのサーバですが、以下のサイトから調べました。

Use IMAP to check Gmail on other email clients - Gmail Help

 

ここでちょっと余談なのですが、実際のGmailSMTPサーバは` smtp.gmail.com `ではありません。

 

` nslookup `というコマンドで、DNSサーバ内のゾーンファイル中のDNSレコードを参照することができます。

 

`smtp.gmail.com`ドメイン宛てのメール配送先に関するDNSレコードはMXレコードを参照することわかります。

 

実際に以下のコマンドを実行すると、` smtp.gmail.com `のメール配送先がわかります。

```

$ nslookup -type=mx smtp.gmail.com

```

実行してみるとわかるのですが、実際は` gmail-smtp-msa.l.google.com `にSMTPメールは配送されています。(ここら辺は、正直合っているか怪しいので間違っていたらコメントお願いします。)

 

話を元に戻します。

 

SMTPサーバにSSL/TLSクライアントで接続ができたら、後はSMTP通信のやり取りです。

 

以下の手順の通りにコマンド実行していきます。

 

手順

  1. HELLO:` ehlo localhost `
  2. 認証:` AUTH LOGIN `
  3. 認証:base64エンコードしたGmailアドレス入力
  4. 認証:base64エンコードしたアプリパスワード入力
  5. メール(送信元):` MAIL FROM: <送信元アドレス> `
  6. メール(宛先):` RCPT TO:<宛先アドレス> `
  7. メール(本文):` DATA `
  8. メール(タイトル):` Subject:<メールタイトル> `
  9. メール(本文):` ********* `
  10. メール(本文終わり):` . `

こちらも順に説明していきます。

 

まず、SMTPサーバへHELLOを送信することでSMTP通信を開始します。このときコマンドは` ehlo localhost `です。(SMTPSSL/TLSクライアントで接続しているためlocalhost

近年のSMTP通信では拡張機能による暗号化が必須になってきているらしく、` ehlo `コマンドでサーバ側が対応している認証方法が返ってきます。(ehlo/Extended HELLO

 

続いて認証フェーズです。今回の認証には` AUTH LOGIN `を利用します。

この認証方式は、ユーザ名とパスワードをBase64エンコードして送ります。

Gmailのアカウントのメールアドレスと前述で取得したアプリケーションパスワードが必要です。

 

認証ができたら、メールの送信元と宛先を指定します。

余談ですが、この時、送信元を認証したユーザ以外で送信してみました。

結果は、自動的に認証したユーザから送信したことになっていました。(なりすましとか簡単にできるのかと思ってたけどそうではないんですね笑)

 

続いてメールの本文を送るため、` DATA `コマンドを送信します。

 

本文が送り終わったら、最後にピリオドを送信します。

 

これで、認証ユーザが送信元のメールが宛先に届きました。

 

結果は以下です。

             f:id:k12si:20190326191545j:plain

 

というわけで、終わりです。

皆さんもぜひ試してみてください!