自宅のメールをスマートフォンでも見たい

POP でメールを取得するとメールは MUA で完結してしまうが、IMAP だと IMAP 対応 MUA を使えばサーバー上のメールボックスを参照してメールを読むことが出来るので、スマートフォンだろうがなんだろうが IMAP クライアントさえ有ればサーバー上のメールを共有することが出来るという利点がある。

そこで IMAP サーバーをインストールしてこれを実現する。

インストールの前にいくつか気になった点

IMAP サーバーは今回「Dovecot 2」を使用することにした。
これはプッシュ配信に必要な「IMAP IDLE」をサポートしていることがその理由だ。
初めは「uw-imap」を使用していたが、それはシンプルな MRA (Mail Retrieval Agent) だったが IMAP IDLE をサポートしていなかったのが乗り換えた理由。
uw-imap から Dovecot に引っ越すつもりの人はいくつか気になる点がある。

実装の前に諸注意など

Dovecot のインストール前にいくつか注意事項を。

まず、Dovecot は MRA - Mail Retrieval Agent - なのでメールボックスと MUA のつなぎを行うに過ぎない。
そのためメール送信を行うための SMTP サーバーは別途構築する必要がある。
今回は SMTP サーバーに構築済みの Postfix を使っている (説明はしていない) が、SMTP サーバーに「コレを使わなければならない」ということは無いので自由に選択して欲しい。

暗号化について。
IMAP 認証は CRAM-MD5 用のパスワードファイルを作成するのが面倒なので今回は PLAIN 方式を採用している。
しかし PLAIN 方式だと後述するように x LOGIN の後ろに続くユーザー名とパスワードが平文となる。
そのままだと通信経路上をそれらの文字列が平文で流れて危険なので、必ず SSL/TLS で保護しなければならない。
多少面倒ではあるが「オレオレ証明書」を作成して Let's Encrypt で証明書を発行してもらって経路を暗号化すること。

Dovecot 2 のインストール

今回インストールしたのは Dovecot 2.0.15。
今回も無精して packages で pkg_add してインストールしたので特になし。

Dovecot 2 の設定

設定ファイルは packages でインストールすると雛形が /usr/local/share/doc/dovecot/example-config/ に有るので、そこからいくつかピックアップしてコピーを使用する。
使用したファイルは以下の通り。

これらを /usr/local/etc/dovecot/ にコピーする。

# cd /usr/local/share/doc/dovecot/example-config/
# cp dovecot.conf /usr/local/etc/dovecot/
# mkdir /usr/local/etc/dovecot/conf.d/
# cp 10-auth.conf 10-mail.conf 10-master.conf 10-ssl.conf auth-system.conf.ext /usr/local/etc/dovecot/conf.d/

以下に各ファイルの設定項目を説明する。
説明項目は変更した部分のみを説明しているので注意されたし。

dovecot.conf

全体的な設定を定義する。

# pop3 などは他に任せて IMAP 特化とする。
# 古今ではもう pop before smtp などで SMTP 認証をする必要も無い # (Submission ポートを使って SMTP-AUTH) ので、qpopper はやめて # Dovecot の pop3 機能を使おう。 protocols = imap pop3

# IPv6 を使っている人はデフォルトのままで。
# IPv6 のみ使っている人は「::」だけ。
# IPv4 のみ使ってる人は以下のように。
# そうしないとエラーで起動しません。
listen = *
10-auth.conf

認証関連の設定を定義する。

# 認証時のパスフレーズ送信方式で PLAIN を許可するようにする。
# SSL/TLS で繋ぐときは PLAIN を使用しても特に問題は無いため。
disable_plaintext_auth = no

# 認証時のパスフレーズ送信方式を指定する。
auth_mechanisms = plain login
10-mail.conf

メールボックスに関する設定を定義する。

# メールボックスのタイプ及び格納場所を指定する。
# 今回は
# ・メールボックス形式は mbox 型を使用する
# ・MUA で使うキャッシュディレクトリとして ~/mail を使用する
# ・メールの INBOX が 有るディレクトリは /var/mail/%u (%u は UNIX アカウント名)
mail_location = mbox:~/mail:INBOX=/var/mail/%u
# Dovecot がメールを取り込むときにドットファイルを INBOX ディレクトリに
# 作成する必要があるので、書き込むことが出来るグループを指定する。
mail_privileged_group = mail
# IMAP を利用することが出来る UID の開始番号を指定する。
first_valid_uid = 100
# IMAP を利用することが出来る GID の開始番号を指定する。
first_valid_gid = 0
10-master.conf

サービスに関する設定を定義する。

# IMAP で使用するポートを設定する。
# SSL も使用するので忘れないように。
service imap-login {
  inet_listener imap {
   port = 143
  }
  inet_listener imaps {
   port = 993
   ssl = yes
  }
}
# POP3 で使用するポートを設定する。
# SSL も使用するので忘れないように。
service pop3-login {
  inet_listener pop3 {
   port = 110
  }
  inet_listener pop3s {
   port = 995
   ssl = yes
  }
}
10-ssl.conf

SSL に関する設定を定義する。

# サーバー証明書とサーバー秘密鍵を指定する。
# Let's Encrypt の証明書を使用するならば ssl_cert には
# fullchain.pem を指定する。
# apache の server.crt を fullchain.pem にしているならば
# server.crt にシンボリックリンクを張っても良い。
# (パーミッション的には問題なし)
ssl_cert = </usr/local/apache2/conf/ssl.crt/server.crt
ssl_key = </usr/local/apache2/conf/ssl.key/server.key

確認と起動

設定が完了したらデーモンを起動する。

# /usr/local/etc/rc2.d/dovecot start

確認を行う。
出来れば SSL/TLS での通信も確認する。

「OK [ ]」のカギ括弧に囲まれている文字列は Dovecot がサポートしている命令が羅列されている。
特に注意するのは以下の 3つ。
これらが見えることを確認しよう。

コマンドの入力は先頭に必ず「x」を付けること。

non SSL
# telnet localhost 143
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY (省略)] Dovecot ready.
x LOGIN username password
x OK [CAPABILITY (省略)] Logged in
x LOGOUT
* BYE Logging out
x OK Logout completed.
Connection closed by foreign host.
STARTTLS/TLS (Explicit)
# openssl s_client -connect localhost:143 -starttls imap CONNECTED(00000003)
(証明書の内容が表示される)
(以下省略)
* OK [(省略)] Dovecot ready.
x LOGIN username password
x OK [(省略)] Logged in
x LOGOUT
* BYE Logging out
x OK Logout completed.
closed
IMAP over SSL (Implicit)
# openssl s_client -connect localhost:993
CONNECTED(00000003)
(証明書の内容が表示される)
(以下省略)
* OK [(省略)] Dovecot ready.
x LOGIN username password
x OK [(省略)] Logged in
x LOGOUT
* BYE Logging out
x OK Logout completed.
closed

確認が完了したら /etc/rc.conf に Dovecot が自動起動するよう追記する。

dovecot_enable="YES"

クライアントの設定

emacs + mew

以下のような項目を .mew.el に書き足した。 フォルダの作成はメールがフォルダに無い場合は作成出来ないので以下のように作成する。

  1. 適当なメールを o で作成したいフォルダ名を指定。
    「%test2 does not exist. Create it? (y or n)」と問われるので「y」。
  2. x で移動させる。
  3. g で移動先フォルダに移動。
  4. メールに # マークが付いているので s → リターンで更新。

ちなみにフォルダの削除は削除したいフォルダに移動してから Rd 。

      ("default"
         (proto             . "%")
         (fcc               . "%outbox")
         (name              . "G-ani")
         (mail-domain       . "griffonworks.net")
	 ;; 証明書の検証を行う。行わない場合は "0" を指定。
         (ssl-verify-level  . 2)
	 ;; IMAP サーバー名
         (imap-server       . "mail.griffonworks.net")
	 ;; SSL を使用する場合は "t"
         (imap-ssl          . t)
	 ;; imap-port と imap-ssl-port の両方を同じポート番号にすると STLS
	 ;; imap-ssl-port のみを指定すると IMAP over SSL
         (imap-port         . "143")
         (imap-ssl-port     . "143")
	 ;; IMAP 認証を行う場合は "t"
         (imap-auth         . t)
	 ;; IMAP のユーザー名
         (imap-user         . "griffon")
	 ;; IMAP クライアントでの削除をサーバーでも反映する
         (imap-delete       . t)
	 ※smtp設定は省略
      )
K-9 Mail

数少ない IMAP IDLE に対応した Android 用メーラー「K-9 Mail」の設定はほぼデフォルトのままで利用可能。
一部ややこしい部分は以下のように。
mew と連携させられるような説明をしている。

  • mew の trash や outbox をそのまま使うには
    「アカウント設定」→「フォルダ」で「送信済みフォルダ名」を「outbox」、「ゴミ箱フォルダ名」を「trash」に設定する。
    この時、mew 側でフォルダを先に作成しておく必要がある。
  • 「プッシュ接続の拡張設定」は特に触る必要は無し。
    下手に触ると IDLE 通知が受け取れなくなる。

なお、メール着信通知が行われなくなったり動きがおかしくなった場合は素直に K-9 Mail で設定している アカウント設定を削除し、もう一度作り直すことをお勧めする。
※K-9 Mail のアカウントを削除してもメールそのものはサーバー側に保管されているので削除されることはない。