telnetによるSMTP通信

SMTP

別のドメイン宛のメイルはSMTPサーバどうしでやりとりをしながら 配送が行なわれる。このときのやりとりの進め方の決まりがSMTPである。 SMTPは単純化すると以下のような順番でのやりとりである。

送信側受信側
HELO自己ホスト名の送出
受理
OK
MAIL FROM送信者アドレス
受理
OK
RCPT TO宛先アドレス
受理
OK
DATAヘッダを含む本文
終端記号"." だけの行
OK
QUIT受理
OK

たとえば、taro@host-A から hanako@host-B に送るときのやりとりの流れ は以下のようになる。

host-Aが送る文字列 host-Bが送る文字列
220 host-B SMTP
HELO host-A
220 host-B SMTP
MAIL FROM: taro@host-A
250 ok
RCPT TO: hanako@host-B
250 ok
DATA
354 go ahead
ヘッダと本文
.
250 ok
QUIT
221 host-B

ヘッダと本文は1行空行を入れて境界とする。

サーバとの対話実験

実際にSMTPサーバと「対話」しながらメイル送信してみよう。このようなメ イルを送るものとする。

From: i2006000@qm200.is.koeki-u.ac.jp
To: i2006000@qm200.is.koeki-u.ac.jp
Subject: test

This is my first mail.

ktermをもう一枚起動し、irsv上のシェルを起動する。 telnetを使ってサービスデーモンと直接対話する。telnetは、

telnet サーバ ポート番号

のように利用する。SMTPのポート番号は25番で、その番号を書いてもよいし、 "smtp"と指定してもよい。サービス名とポート番号の対応表は /etc/servicesにある。

% telnet qmXXX.is.koeki-u.ac.jp smtp
Trying 172.19.5.200...
Connected to qm200.is.koeki-u.ac.jp.
Escape character is '^]'.
220 qm200.is.koeki-u.ac.jp ESMTP
HELO irsv.e.koeki-u.ac.jp
250 ok
MAIL FROM: i2006000@qm200.is.koeki-u.ac.jp
250 ok
RCPT TO: i2006000@qm200.is.koeki-u.ac.jp
250 ok
DATA
354 go ahead
To: i2006000@qm200.is.koeki-u.ac.jp
From: i2006000@qm200.is.koeki-u.ac.jp
Subject: test

This is my first mail.
.
250 ok 1141889590 qp 5244
QUIT
221 qm200.is.koeki-u.ac.jp
Connection to qm200.is.koeki-u.ac.jp closed by foreign host.

サーバ側にログインしているktermに切り替えて、配送されたか確認してみよう。

% cd
% ls -l maildir/new
total 1
-rw-------  1 i2006000  369  3  7 21:08 1141733337.116.qm200.is.koeki-u.ac.jp
-rw-------  1 i2006000  365  3  9 16:34 1141889662.59.qm200.is.koeki-u.ac.jp

一番最後に表示されるファイル名がたった今届いたものなので、これを less で見てみる。

% less maildir/new/1141889662*
Return-Path: <i2006000@qm200.is.koeki-u.ac.jp>
Delivered-To: i2006000@qm200.is.koeki-u.ac.jp
Received: (qmail 5244 invoked from network); 9 Mar 2006 07:32:32 -0000
Received: from irsv.e.koeki-u.ac.jp (172.21.90.10)
  by qm200.is.koeki-u.ac.jp with SMTP; 9 Mar 2006 07:32:32 -0000
To: i2006000@qm200.is.koeki-u.ac.jp
From: i2006000@qm200.is.koeki-u.ac.jp
Subject: test

This is my first mail.
~
~
~

Return-Path から Received までは自動的に付けられたヘッダで、 To: 以降は手入力したものである。空行で区切られた部分までがヘッダで、 一般のメイルリーダはここまでの情報を元に色々な表示を行なう。

エンベロープ

手動でSMTPを喋って送信するときに、送信者(From)と受信者(To)のアドレス を2回ずつ入れなければならないのは一見無駄に思えるが、これらは 別の働きをする。

最初に入力した MAIL FROM と RCPT TO はそれぞれ envelope-from envelope-to といい、お互いのMTAがそのときの実際の送信者と実際の 受信者を特定するためのものである。DATA以降に入力したもの、つまりメイル本 体の From: と To: は普段目にする「From:ヘッダ」と「To:ヘッダ」で、 実際の送受信者と同じ場合もあるし、違う場合もある。

たとえば、taro@koeki-u.ac.jp の人がそこに来たメイルを taro@example.ne.jp に転送するような場合、To:ヘッダはそのままにして、 envelope-to を taro@example.ne.jp に変更して転送する。このため ヘッダとenvelopeは異なる。

メイル配送の全手順

実際にMTAが外部にメイルを送信する手続を手で追ってみよう。ここでは送信 先が foo@example.co.jp だとしてMTAと同じ手順で送信してみる。

  1. メイルアドレスのドメインパートのMXレコードを引く。

    hostコマンドを使う。
    % host -t mx example.co.jp
    example.co.jp mail is handled by 1 mail0.example.co.jp.
    example.co.jp mail is handled by 10 mail1.example.co.jp.
    
  2. 数字(preference値)の一番小さなホストに対して SMTPコネクションを張る。

    % telnet mail0.example.co.jp smtp
    
  3. HELO, MAIL FROM, RCPT TO, DATAを正しく送信して メイルを送る。

    (手順はqmXXXに送る例と同じなので省略)

目次


(C)2006 HIROSE Lab. koeki-u.ac.jp