Edited at

SMTPサーバとPOPサーバの実験を交えた詳解

More than 1 year has passed since last update.


0. この記事について

結論から書くと、smtpサーバとpopサーバを整理する内容の記事です。なぜ書こうかと思ったかというと、メールサーバにおいて「smtpサーバ」がメール送信、「popサーバ」がメール受信を行なっているという解釈をしてしまっているというのを聞いたためです。

厳密には違います。

という話を、実験を交えて違うという主張を行なう記事となります。

実験は2. 実験から、smtp・popの詳解については5. 解説から行ないます。歴史なんてしっとるわという人は2から、結論だけ読みたい方は5から読まれることをおすすめします。

また当方インフラエンジニアとかではないので、誤りを見つけた場合はガンガン指摘をお願いします。

あと読者はこんな感じの人を想定してます。


  • virtualboxでなんとなくosインストールでき、インストールしたosにssh接続できるところまで設定できる

  • ネットワークに関して、ホスト名・ipアドレス・DNSというキーワードを知っていて、ipアドレスが何かなんとなくわかる

  • Linuxの基本的なコマンドが分かる(cat、vim、yum、cdなどなど)


    • 分からない場合は適宜調べてもらえれば読める…はず

    • そんなに難しいコマンドは使ってないと思う

    • 分かり辛ければコメントで



  • プロンプトが分かる



    • # useradd user#の部分


    • #の場合はルートユーザであることを示す


    • $である場合は標準ユーザであることを示す

    • つまり#のついているコマンドはルート権限が必要になる




1. メールサーバの歴史


1.1. SMTPサーバの歴史

 SMTPサーバの背景として、当時(1980年代ぐらい)PCは常に電源がついている(シャットダウンしない)ような運用をしていた。理由は簡単で、PCが今と比べてべらぼうに高く一人一台支給することができなかったため、今でいうクライアントマシンとサーバマシンをないまぜにして使用していたためだ。PCを使いたい場合は、誰かが使っていれば順番待ちしなければならないというような状態。当然今のようなWorld Wide Webもない。

 SMTPはそういった状況下で生まれたため、相手が常に応答できる前提で設計されている。つまり相手のマシンは電源が入っており、かつSMTPサーバが起動状態でないと相手側のマシンはメールを受信できないというような状態。上記のような背景があるため、この運用で特に問題なし。ちなみにSMTP自体、メール送信に失敗すると一定時間後に再送するというような機能もある。たまたま電源が落ちていてもさして問題にならない。

 ところがPCが普及するにつれクライアントマシンとサーバマシンが分離、それに伴い電源をつけたり消したりするようになった。そしてSMTPは電源が落ちている相手には届かない。では電源をつけっぱなしの運用にすればよいのでは?という話だが、それにしても各クライアントマシンがSMTPプロトコルを読めるようにしないといけない。やってみればわかるけどSMTPサーバ、構築が大変。

 そこでSMTPサーバは1台だけ用意し、メールの送受信はそのサーバが行なうようになった。後述のPOPが登場するまでは、このSTMPサーバにtelnet等でアクセスし、各ユーザのhomeディレクトリに届いたメール(ファイルとして保存されている)を読み出すなどしていた。


1.2. POPの登場

 さすがにtelnetでいちいち読みだすのは面倒であるため、STMPサーバからメールを簡単に取り出す仕組みの考案が急がれた。これがPOPプロトコル。そもそもSMTPサーバは受信したメールを適切なディレクトリにテキストで保存している。POPはこれをどう読みだすかの仕組みとなる。

 POPはSMTPサーバ内にPOPサーバとして構築される。POPサーバは あくまでSTMPサーバに届いたメールファイルを取り出す ものなので、基本的に同じサーバ内に構築される(あくまで基本的には)。

 メールの受信側はPOPプロトコルをしゃべることができるクライアントソフトウェアを用意することになる。昨今だとMicrosoft OutlookやThunderbirdなどがある。

 メールクライアントソフトにサーバへアクセスする際のユーザ名/パスワード等を設定し受信ボタン等々を押すことにより、STMPが受信済みのメールを対象サーバのディレクトリ内からクライアント側にダウンロードし参照することができる。これがPOPの基本的な受信の仕組みとなる。


1.3. 補足


  • SMTPはMTA(Mail Transfer Agent[メール配送(転送)エージェント])等と呼ばれる


    • メールの送受信・中継を行なう



  • OutlookやThunderbirdはMUA(Mail user agent[電子メールクライアント])等と呼ばれる


    • メールをクライアントサイドにダウンロードしたりする

    • つまりPOPがしゃべれる




2. 実験


2.1. 注意喚起


  • 実験中でやっている設定はローカルでテストするための設定なため、セキュリティ的に問題しかない、間違ってもAWS上のサーバとかにやってはならない

  • 特にsmtpは認証をしてないので、一瞬で乗っ取られてスパムメール用の踏み台に使われてAWSのアカBANを食らう可能性まである(事前に「お前メール送りすぎ、乗っ取られてね?直さないとアカウントロックするぞ」という警告が来るはずだが)



2.2. 実験の前提など


  • ここから本番

  • 前提として、SMTPサーバがPOPサーバにメールを送信していると思い込んでいる人がいる


    • 分かっている人向けに分かりやすく解説すると、SMTPサーバがSMTPのプロトコルでPOPサーバにメールを送りつけていると思っている人がいる

    • つまりPOPはSMTPのプロトコルもしゃべれるという解釈…らしい

    • この勘違いは非常に起こりやすい(と思っている)

    • ちなみに筆者は1年近く勘違いしてました



  • 実際にSMTPサーバを立ててPOPサーバにメールを送信してみて、その説が正しくないことを実証しようというもくろみ


    • 構成は以下




2.3. 実験環境の情報


  • VirtualBox上

  • NATネットワークで下記を設定済み


    • ネットワークCIDR:10.0.2.0/24



  • 各仮想マシン内からping www.google.co.jpが通る


    • 通らない場合、デフォルトゲートウェイの設定か/etc/resolv.confの設定がおかしいか




  • firewalldSELinuxは事前に無効にしておく


    • 実験したら破棄する環境なので設定は割愛



  • 各マシンにSSH接続できる(=ポートフォワーディング設定が済んでいる)

  • 各マシンに下記IPアドレスが付与されている


    • FQDNはあとで/etc/hostsに書くので気にしなくて良い

    • ホスト名もhostnamectl set-hostname {ホスト名}とかして後で変える



  • 使うソフトウェア

ソフトウェア名
役割

Postfix
SMTPサーバ

Dovecot
POP3サーバ

Thunderbird
メールクライアント


  • サーバ情報

用途
OS
ホスト名
ip
FQDN
インストールするソフトウェア

SMTPサーバ
CentOS 7.4
smtp
10.0.2.210/24
smtp.example.com
Postfix

POPサーバ
CentOS 7.4
pop3
10.0.2.220/24
pop3.example.com
Postfix, Devecot

MUA用
Lubuntu 17.10
(デフォルトで可)
10.0.2.230/24
(なし)
Thunderbird


2.4. 実験の手順


  • [1] SMTP用のサーバにPostfixをインストール・設定

  • [2] POP3用のサーバにPostfixをインストール・設定


    • SMTP用のサーバのインストール・設定がうまく行っていることを確認するため



  • [3] [1]で立てたSMTPサーバ <-> [2]で立てたSMTPサーバでメール送受信できるか動作確認

  • [4] POP3用のサーバにDovecotをインストール・設定

  • [5] POP3にてメールが受信できることを確認(クライアント)

  • [6] SMTP用サーバ -> POP3用サーバへ送信ができるかテスト


3. 実験・構築


[1] SMTP用のサーバにPostfixをインストール・設定


ホスト名の設定


  • ホスト名は変えておくと分かりやすい

  • ホスト名を変更したら再ログインする

# hostnamectl set-hostname smtp


インストール


  • yumで一発

# yum -y install postfix


hostsの設定


  • DNSサーバ用意したりするのは大変なので/etc/hostsに設定を書いて済ませる


/etc/hosts

10.0.2.210  smtp.example.com

10.0.2.220 pop3.example.com


Postfixの設定


  • 設定ファイルにいろいろ書き込む


    • Postfixの設定記事ではないため設定はガバガバ



  • vimとかで設定名を検索して適宜変える


/etc/postfix/main.cf

# コメントアウトされているので外して下記を設定.

myhostname = smtp.example.com

# コメントアウトされているので外して下記を設定.
mydomain = exapmle.com

# コメントアウトされているので外して下記を設定.
myorigin = $mydomain

# (デフォルト=localhost)今回は2つのサーバ間でやり取りをするため,allに変える.
inet_interfaces = all

# (デフォルト=all)今回はipv4しか通信に用いない(設定しない)ため念のためipv4としておく.
inet_protocols = ipv4

# ネットワークCIDRを指定,コメントアウトされている場合は外して設定.
mynetworks = 127.0.0.0/8, 10.0.2.0/24

# メール保存場所・形式の変更./home/{ユーザ名}/Maildir配下にメールが格納されるようになる.
# コメントアウトされている場合は外して設定.
home_mailbox = Maildir/

# /etc/hostsに設定した内容を参照するための設定,これがないと/etc/hostsを見てくれない
# 設定値が存在しない場合は追記すること.
smtp_host_lookup = native



メール用ユーザの追加


  • rootは何かと都合が悪いので

  • ユーザ名,パスワードとも「user」で作成した

# useradd user

# passwd user
ユーザー user のパスワードを変更。
新しいパスワード:
よくないパスワード: このパスワードは 8 未満の文字列です。
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。
# su - user
$ cd
$ mkdir Maildir
$ exit
ログアウト
#


起動

# systemctl start postfix


送信テスト


  • とりあえず自分自身に送信してみる


    • 下記通りEnterで普通に改行してOK



# sendmail user@smtp.example.com

To:user@smtp.example.com
From:user@smtp.example.com
Subject:test

myself(stmp).

.
#


受信確認


  • さっきMaildir/に格納する形式に設定したためそこに届いている

# su - user

最終ログイン: 2018/01/29 (月) 21:00:01 JST日時 pts/0
$ ls ~/Maildir/new/
1517215658.Vfd00I300369M38332.smtp
$ cat ~/Maildir/new/1517215658.Vfd00I300369M38332.smtp
~中略~
Return-Path: <user@smtp.localdomain>
Received: by smtp.localdomain (Postfix, from userid 0)
id F319D8E0361; Mon, 29 Jan 2018 20:47:37 +0900 (JST)
To:user@smtp.example.com
From:user@smtp.example.com
Subject:test
Message-Id: <20180129204737.F319D8E0361@smtp.localdomain>
Date: Mon, 29 Jan 2018 20:47:37 +0900 (JST)

myself(smtp).

--F319D8E0361.1517215658/smtp.localdomain--

$ exit
ログアウト
#


[2] POP3用のサーバにPostfixをインストール・設定


ホスト名の設定


  • ホスト名を変更したら再ログインする

# hostnamectl set-hostname pop3


インストール


  • 「[1] SMTP用のサーバにPostfixをインストール・設定」と同じ


hostsの設定


  • 「[1] SMTP用のサーバにPostfixをインストール・設定」と同じ


Postfixの設定


  • 下記一行を除き、「[1] SMTP用のサーバにPostfixをインストール・設定」と同じ


/etc/postfix/main.cf

# コメントアウトされているので外して下記を設定.

myhostname = pop3.example.com


メール用ユーザの追加


  • 「[1] SMTP用のサーバにPostfixをインストール・設定」と同じ


起動


  • 「[1] SMTP用のサーバにPostfixをインストール・設定」と同じ


送信テスト


  • host名が違うのでそれを変えて送る

# sendmail user@pop3.example.com

To:user@pop3.example.com
From:user@pop3.example.com
Subject:test

myself(pop3).

.
#


受信確認

# su - user

最終ログイン: 2018/01/29 (月) 21:05:01 JST日時 pts/0
$ ls ~/Maildir/new
1517216423.Vfd00I30036cM326769.pop3
$ cat ~/Maildir/new/1517216423.Vfd00I30036cM326769.pop3
~中略~
Return-Path: <user@pop3.localdomain>
Received: by pop3.localdomain (Postfix, from userid 0)
id 45F568E035F; Mon, 29 Jan 2018 21:00:23 +0900 (JST)
To:user@pop3.example.com
From:user@pop3.example.com
Subject:test
Message-Id: <20180129210023.45F568E035F@pop3.localdomain>
Date: Mon, 29 Jan 2018 21:00:22 +0900 (JST)

myself(pop3).

--45F568E035F.1517216423/pop3.localdomain--

$ exit
ログアウト
#


[3] [1]で立てたSMTPサーバ <-> [2]で立てたSMTPサーバでメール送受信できるか動作確認


[1]で立てたSMTPサーバ -> [2]で立てたSMTPサーバ


送信テスト


  • 送信は[1]のサーバ(10.0.2.210)から行なう

# sendmail user@pop3.example.com

To:user@pop3.example.com
From:user@smtp.example.com
Subject:test

smtp to pop3.

.
#


受信テスト


  • 受信確認は[2]のサーバ(10.0.2.220)から行なう

# su - user

最終ログイン: 2018/01/29 (月) 21:26:23 JST日時 pts/0
$ ls -1t ~/Maildir/new | head -n 1
1517217913.Vfd00I300327M788645.pop3
$ cat ~/Maildir/new/1517217913.Vfd00I300327M788645.pop3
Return-Path: <user@example.com>
X-Original-To: user@pop3.example.com
Delivered-To: user@pop3.example.com
Received: by pop3.example.com (Postfix, from userid 0)
id BCD168E035E; Mon, 29 Jan 2018 21:25:13 +0900 (JST)
To:user@pop3.example.com
From:user@smtp.example.com
Subject:test
Message-Id: <20180129212513.BCD168E035E@pop3.example.com>
Date: Mon, 29 Jan 2018 21:25:13 +0900 (JST)

smtp to pop3.

$ exit
ログアウト
#


[2]で立てたSMTPサーバ -> [1]で立てたSMTPサーバ


送信テスト


  • 送信は[2]のサーバ(10.0.2.220)から行なう

# sendmail user@smtp.example.com

To:user@smtp.example.com
From:user@pop3.example.com
Subject:test

pop3 to smtp.

.
#


受信テスト


  • 受信確認は[1]のサーバ(10.0.2.210)から行なう

# su - user

最終ログイン: 2018/01/29 (月) 21:32:56 JST日時 pts/0
$ ls -1t ~/Maildir/new | head -n 1
1517218291.Vfd00I300323M735020.smtp
$ cat ~/Maildir/new/1517218291.Vfd00I300323M735020.smtp
Return-Path: <user@example.com>
X-Original-To: user@smtp.example.com
Delivered-To: user@smtp.example.com
Received: from pop3.example.com (pop3.example.com [10.0.2.220])
by smtp.example.com (Postfix) with ESMTP id A6C6D8E0360
for <user@smtp.example.com>; Mon, 29 Jan 2018 21:31:31 +0900 (JST)
Received: by pop3.example.com (Postfix, from userid 0)
id 9BA908E035F; Mon, 29 Jan 2018 21:31:31 +0900 (JST)
To:user@smtp.example.com
From:user@pop3.example.com
Subject:test
Message-Id: <20180129213131.9BA908E035F@pop3.example.com>
Date: Mon, 29 Jan 2018 21:31:31 +0900 (JST)

pop3 to smtp.

$ exit
ログアウト
#


補足というかコラム的なやつ


  • この時点ですでに popサーバなどなくともメールが受信できている ことが分かる


    • このような回りくどいことをせずとも、実はsmtpサーバを立てて自分自身に送信ができ、それを受信もできている時点で実証はされている

    • 受信という言葉がややこしくしているが、要はsmtpのプロトコルで送られてきたデータをテキストデータとして設定されたディレクトリに保存しているだけ



  • これ以降はpopサーバで受信ができることと、smtpサーバが落ちると受信できなくなる(=popサーバが受信しているわけではない)ことを検証することとなる


[4] POP3用のサーバにDovecotをインストール・設定


インストール


  • yumで一発

# yum -y install dovecot


設定


/etc/dovecot/conf.d/10-mail.conf

# デフォルトでコメントアウトされているので外す.

# postfixでメールの保存場所をいじったのはこれのため.
mail_location = maildir:~/Maildir


/etc/dovecot/conf.d/10-auth.conf

# デフォルトでplainのみ設定されているのでloginを追記

auth_mechanisms = plain login

# plain textでのログインを許可,コメントアウトを外しnoに変更
disable_plaintext_auth = no



/etc/dovecot/conf.d/10-ssl.conf

# SSL/TLSに関する設定の類は一切行なっていないのでnoにする

ssl = no


起動

# systemctl start dovecot


[5] POP3にてメールが受信できることを確認(クライアント)


  • ここからはLubuntuをいじる


hostsの設定


/etc/hosts

10.0.2.210  smtp.example.com

10.0.2.220 pop3.example.com


メールクライアントのインストール

# apt-get install -y thunderbird


起動



  • 左下アイコン > インターネット > Thunderbird電子メールクライアントで起動

01.png


設定



  • Skip this and use my existing emailをクリック

02.png


  • 下記を設定しContinueをクリック

Your name
Email address
Password

user
user@pop3.example.com
user

03.png


  • うまく行っていると下記のようになるのでDoneをクリック

04.png


  • ものすごく警告が出るがI understand the risks.をクリックしチェックを入れDoneをクリック


    • SSL/TLSとか設定してないので、盗聴改ざんうんたらの警告、今回はvirtualbox上で盗聴もなにもないので大丈夫



05.png


受信確認


  • 左上のGet Messagesをクリックすると無事にメールを見ることができる

06.png

07.png


[6] SMTP用サーバ -> POP3用サーバへ送信ができるかテスト


  • いよいよ本丸

  • ここまでの構成は下記

smtp-pop_ok.png


  • もしPOP3がメールを受信しているのであれば、下記の構成でイケるはず

smtp-pop_ng.png


POP3側のPostfixをストップ



  • 10.0.2.220の方

# systemctl stop postfix

# systemctl status postfix
● postfix.service - Postfix Mail Transport Agent
Loaded: loaded (/usr/lib/systemd/system/postfix.service; enabled; vendor preset: disabled)
Active: inactive (dead) since 火 2018-01-30 20:53:51 JST; 3s ago
~略~


SMTP -> POP3へとメールを送信


  • 送信は[1]のサーバ(10.0.2.210)から行なう

# sendmail user@pop3.example.com

To:user@pop3.example.com
From:user@smtp.example.com
Subject:test

smtp to pop3.

.
#


受信確認


  • ThunderbirdでGet Meeesgesをクリック

  • すると ウンともスンとも言わない


メールログの確認



  • 10.0.2.210の方(SMTP専用の方)のメールログを確認

# cat /var/log/maillogJan 30 20:56:17 smtp postfix/pickup[11517]: 5C9218E0365: uid=1005 from=<user>

Jan 30 20:56:17 smtp postfix/cleanup[14325]: 5C9218E0365: message-id=<20180130045617.5C9218E0365@smtp.example.com>
Jan 30 20:56:17 smtp postfix/qmgr[1202]: 5C9218E0365: from=<user@exapmle.com>, size=306, nrcpt=1 (queue active)
Jan 30 20:56:17 smtp postfix/smtp[14327]: connect to pop3.example.com[10.0.2.220]:25: Connection refused
Jan 30 20:56:17 smtp postfix/smtp[14327]: 5C9218E0365: to=<user@pop3.example.com>, relay=none, delay=0.42, delays=0.41/0/0/0, dsn=4.4.1, status=deferred (connect to pop3.example.com[10.0.2.220]:25: Connection refused)


メールログの解析



  • dsn=4.4.1とある


  • メールのエラーコードと、メールサーバのmaillog解析方法まとめ | OXY NOTESを参考に解析

  • 1桁目が4なので「一時的なエラーが繰り返し発生する」状態

  • 2、3桁目が4.1なので「ホストから応答がない」状態


  • status=deferredなのでメールは送られていない



    • (connect to pop3.example.com[10.0.2.220]:25: Connection refused)とあるので25番ポートで通信ができないということ

    • 25番ポート=SMTPサーバのポート




4. 考察

 POP3側に立てたSMTPサーバを落とすことで見事メールが受信できなくなった。つまりメールを受信しているのは POPではなくSMTP であることが明らかとなった。POPの詳解はこの後行なうとして、一般的によくある「SMTPがメール送信、POPがメール受信」という言葉は 間違いである と結論付けることができる。

 POPとSMTPの関係がなぜないまぜになってしまったかということに関しては、下記の可能性があると推察する。


  • 受信と送信という関係性の方が分かりやすい関係にある(対極のため)

  • 多くの説明がSMTPサーバ=送信、POPサーバ=受信と書いてしまっている

  • 現状SMTPサーバとPOPサーバはほぼセットで使われるため、利用する(ユーザエンド)という側面からみたときにSMTPサーバ=送信、POPサーバ=受信という説明でも特に支障がない

  • POPサーバの役割が微妙に分かり辛い


5. 解説


  • POPがやっていることは(超ざっくり感で)


    • 1.SMTPにより受信したメールが格納されているであろうディレクトリを参照

    • 2.Maildir/new/の中に入っているメールをクライアント側に送信

    • 3.クライアント側に送信したMaildir/new/の中のメールにフラグを付けてMaildir/cur/ディレクトリへ移動





  • つまりディレクトリの中のメールをクライアント側に返すっていうのが主な仕事

  • ポストの中に入っている手紙・はがき・封筒なんかを回収するようなイメージ


    • 郵便の仕事があくまで「投函された手紙を対象の住所にあるポストに投函するまで」であるように、SMTPの仕事は 送信されたメールを対象のメールアドレスに書かれているドメインのユーザが持っているディレクトリに格納(投函)する という感じ

    • 現実世界だと家のポストは家に1個だが、メールの場合は1人1個のイメージ




6. あとがきとか


  • 世の中にあるSMTPサーバとPOPサーバの関係について正しく書かれている記事がない理由、記事を書いてみて分かった


    • 真面目に書こうと思うと、書く量が膨大



  • 書いておいてなんだけども、この記事を読むより素直にマスタリングTCP/IPを買って読んだ方が圧倒的に早い


    • この辺の説明が2~3ページにまとめられている他、めちゃめちゃわかりやすい



  • 冒頭にもありましたが私はインフラエンジニアではないので説明におかしなところがあるかと思います


    • その場合は指摘をくださるとありがたいです




参考リンク