Dovecotには、Sieve(英語で「ふるい」という意味です)と呼ばれる「サーバサイドでの振り分け機能」を追加することができます。これを有効化すると、条件を設定してその条件に従ってメール受信時に特定のフォルダに移動する、ということが可能になります。
Sieveの利点は、「サーバサイドで行う」ので、メーラーを選ばないことです。メーラーで受信したときには既にフォルダに移動していますので、PCで見てもモバイルで見ても一緒の結果が得られます。
FreeBSD 14.1で動作確認しています。
追加パッケージのインストール
Sieveを使うためには、追加でパッケージをインストールする必要があります。いつものごとくpkgコマンドで追加しましょう。
pkg install -y dovecot-pigeonhole
これで追加パッケージがインストールされました。設定ファイルの雛形は「/usr/local/share/doc/dovecot/example-config」にあるので、これを所定の場所にコピーしてしまいます。
cd /usr/local/share/doc/dovecot/example-config
cp -pr * /usr/local/etc/dovecot/example-config
cp -pr * /usr/local/etc/dovecot
Dovecotの「example-config」配下にもコピーをしていますが、これは設定を完了したあとに「diff」コマンドで差分を取るときに便利なようにコピーしています。
Sieveの設定
設定ファイルをコピーし終えたら、設定を開始しましょう。
/usr/local/etc/dovecot/conf.d/20-imap.conf
Sieveスクリプトは配信時に実行されますが、RFC 6785ではIMAPでの実行を拡張しています。これを有効化するために、「/usr/local/etc/dovecot/conf.d/20-imap.conf」ファイルに、次のパッチを当てます。
*** 20-imap.conf.orig Wed Nov 6 10:51:26 2024
--- 20-imap.conf Wed Nov 6 10:52:34 2024
***************
*** 91,99 ****
protocol imap {
# Space separated list of plugins to load (default is global mail_plugins).
! mail_plugins = $mail_plugins imap_zlib imap_quota
# Maximum number of IMAP connections allowed for a user from each IP address.
# NOTE: The username is compared case-sensitively.
#mail_max_userip_connections = 10
}
--- 91,102 ----
protocol imap {
# Space separated list of plugins to load (default is global mail_plugins).
! mail_plugins = $mail_plugins imap_zlib imap_quota imap_sieve
# Maximum number of IMAP connections allowed for a user from each IP address.
# NOTE: The username is compared case-sensitively.
#mail_max_userip_connections = 10
+
+ # Enables metadata
+ imap_metadata = yes
}
プラグインに「imap_quota」に加えて「imap_sieve」が加わりました。また、この拡張に必要な「imap_metadata」の設定も加わりました。
/usr/local/etc/dovecot/conf.d/10-mail.conf
「20-imap.conf」で「imap_metadata」を有効にしたので、メタデータが格納される場所を設定しなければなりません。
*** 10-mail.conf.orig Fri Nov 29 23:39:38 2024
--- 10-mail.conf Fri Nov 29 23:38:05 2024
***************
*** 128,134 ****
# Dictionary for key=value mailbox attributes. This is used for example by
# URLAUTH and METADATA extensions.
! #mail_attribute_dict =
# A comment or note that is associated with the server. This value is
# accessible for authenticated users through the IMAP METADATA server
--- 128,134 ----
# Dictionary for key=value mailbox attributes. This is used for example by
# URLAUTH and METADATA extensions.
! mail_attribute_dict = file:/var/spool/vmail/%d/%n/dovecot-attributes
# A comment or note that is associated with the server. This value is
# accessible for authenticated users through the IMAP METADATA server
これで、前述の設定ができました。
/usr/local/etc/dovecot/conf.d/20-lmtp.conf
メール受信時にはDovecot LMTPが用いられますが、このDovecot LMTPがメールボックスへの配信時にSieveスクリプトを実行するように「/usr/local/etc/dovecot/conf.d/20-lmtp.conf」に次のパッチを当てます。
*** 20-lmtp.conf.orig Mon Nov 4 21:15:02 2024
--- 20-lmtp.conf Wed Nov 6 09:33:45 2024
***************
*** 36,40 ****
protocol lmtp {
# Space separated list of plugins to load (default is global mail_plugins).
! #mail_plugins = $mail_plugins
}
--- 36,40 ----
protocol lmtp {
# Space separated list of plugins to load (default is global mail_plugins).
! mail_plugins = $mail_plugins sieve
}
「mail_plugins」のコメントアウトを外したうえで、「sieve」を追記します。
/usr/local/etc/dovecot/conf.d/20-managesieve.conf
「ManageSieve」とは、クライアントがSiveスクリプトをアップロード/変更を行えるようにするための仕組みです。。「ManageSieve」の定義ファイルが「/usr/local/etc/dovecot/conf.d/20-managesieve.conf」ですが、デフォルトでは動作が止められているので、有効化します。次のパッチを当ててください。
*** 20-managesieve.conf.orig Wed Oct 9 23:27:36 2024
--- 20-managesieve.conf Wed Nov 6 09:43:32 2024
***************
*** 3,16 ****
##
# Uncomment to enable managesieve protocol:
! #protocols = $protocols sieve
# Service definitions
! #service managesieve-login {
! #inet_listener sieve {
! # port = 4190
! #}
#inet_listener sieve_deprecated {
# port = 2000
--- 3,16 ----
##
# Uncomment to enable managesieve protocol:
! protocols = $protocols sieve
# Service definitions
! service managesieve-login {
! inet_listener sieve {
! port = 4190
! }
#inet_listener sieve_deprecated {
# port = 2000
***************
*** 19,37 ****
# Number of connections to handle before starting a new process. Typically
# the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
# is faster. <doc/wiki/LoginProcess.txt>
! #service_count = 1
# Number of processes to always keep waiting for more connections.
#process_min_avail = 0
# If you set service_count=0, you probably need to grow this.
! #vsz_limit = 64M
! #}
! #service managesieve {
# Max. number of ManageSieve processes (connections)
#process_limit = 1024
! #}
# Service configuration
--- 19,37 ----
# Number of connections to handle before starting a new process. Typically
# the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
# is faster. <doc/wiki/LoginProcess.txt>
! service_count = 0
# Number of processes to always keep waiting for more connections.
#process_min_avail = 0
# If you set service_count=0, you probably need to grow this.
! vsz_limit = 128M
! }
! service managesieve {
# Max. number of ManageSieve processes (connections)
#process_limit = 1024
! }
# Service configuration
これでManageSieveが有効化します。
/usr/local/etc/dovecot/conf.d/90-sieve.conf
「90-sieve.conf」Sieveの動作に関する設定ファイルになります。これを実際の運用環境に合わせて変更します。次のパッチを当ててください。
*** 90-sieve.conf.orig Wed Oct 9 23:27:36 2024
--- 90-sieve.conf Wed Nov 6 11:00:34 2024
***************
*** 36,42 ****
# active script symlink is located.
# For other types: use the ';name=' parameter to specify the name of the
# default/active script.
! sieve = file:~/sieve;active=~/.dovecot.sieve
# The default Sieve script when the user has none. This is the location of a
# global sieve script file, which gets executed ONLY if user's personal Sieve
--- 36,42 ----
# active script symlink is located.
# For other types: use the ';name=' parameter to specify the name of the
# default/active script.
! sieve = file:/var/spool/vmail/%d/%n/sieve;active=/var/spool/vmail/%d/%n/.dovecot.sieve
# The default Sieve script when the user has none. This is the location of a
# global sieve script file, which gets executed ONLY if user's personal Sieve
***************
*** 76,81 ****
--- 76,82 ----
#sieve_before = /var/lib/dovecot/sieve.d/
#sieve_before2 = ldap:/etc/sieve-ldap.conf;name=ldap-domain
#sieve_before3 = (etc...)
+ sieve_before = /usr/local/etc/dovecot/sieve/before/
# Identical to sieve_before, only the specified scripts are executed after the
# user's script (only when keep is still in effect!). Multiple script
***************
*** 92,98 ****
# to the default. For example `sieve_extensions = +imapflags' will enable the
# deprecated imapflags extension in addition to all extensions were already
# enabled by default.
! #sieve_extensions = +notify +imapflags
# Which Sieve language extensions are ONLY available in global scripts. This
# can be used to restrict the use of certain Sieve extensions to administrator
--- 93,99 ----
# to the default. For example `sieve_extensions = +imapflags' will enable the
# deprecated imapflags extension in addition to all extensions were already
# enabled by default.
! sieve_extensions = +editheader
# Which Sieve language extensions are ONLY available in global scripts. This
# can be used to restrict the use of certain Sieve extensions to administrator
***************
*** 111,117 ****
# (wiki2.dovecot.org) or the pigeonhole website
# (http://pigeonhole.dovecot.org) for available plugins.
# The sieve_extprograms plugin is included in this release.
! #sieve_plugins =
# The maximum size of a Sieve script. The compiler will refuse to compile any
# script larger than this limit. If set to 0, no limit on the script size is
--- 112,118 ----
# (wiki2.dovecot.org) or the pigeonhole website
# (http://pigeonhole.dovecot.org) for available plugins.
# The sieve_extprograms plugin is included in this release.
! sieve_plugins = sieve_imapsieve
# The maximum size of a Sieve script. The compiler will refuse to compile any
# script larger than this limit. If set to 0, no limit on the script size is
***************
*** 202,205 ****
--- 203,209 ----
# Enables showing byte code addresses in the trace output, rather than only
# the source line numbers.
#sieve_trace_addresses = no
+
+ # Enables user Sieve script.
+ imapsieve_url = sieve://hostname.example.com
}
変更点は
- Sieveスクリプトの配置場所の変更(デフォルトではホームディレクトリですが、メールユーザはローカルユーザと切り離しているので、ホームディレクトリは無いので)
- グローバルで実行される(ユーザのSieveスクリプトが実行されす前に実行される)Siveスクリプトのディレクトリを設定
- Sieve言語の(デフォルトでは無効化されている)拡張機能を有効化
- IMAPでのSieveスクリプト実行(RFC 6875)を有効化
- ユーザが設定したSieveスクリプトの実行を許可(ホスト名は実際のものに書き換えてください)
となります。
既定で作成されるIMAPフォルダの設定(/usr/local/etc/dovecot/conf.d/15-mailboxes.conf)
後ほど、SPAM判定されたメールを迷惑フォルダに振り分ける設定をご紹介しますが、そもそも「迷惑フォルダ」を手動で作るのは非効率的です。そのため、Dovecotに設定を施してしまいます。「迷惑フォルダ」などの特別用途のフォルダには、RFCで決められた「フラグ」をセットすると、メーラーが自動認識します。「/usr/local/etc/dovecot/conf.d/15-mailboxes.conf」に次のパッチを当てます。
*** 15-mailboxes.conf.orig Sat Oct 12 17:44:22 2024
--- 15-mailboxes.conf Wed Nov 6 11:16:34 2024
***************
*** 49,70 ****
# These mailboxes are widely used and could perhaps be created automatically:
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
}
mailbox Trash {
special_use = \Trash
}
# For \Sent mailboxes there are two widely used names. We'll mark both of
# them as \Sent. User typically deletes one of them if duplicates are created.
mailbox Sent {
special_use = \Sent
}
! mailbox "Sent Messages" {
! special_use = \Sent
! }
# If you have a virtual "All messages" mailbox:
#mailbox virtual/All {
--- 49,74 ----
# These mailboxes are widely used and could perhaps be created automatically:
mailbox Drafts {
special_use = \Drafts
+ auto = subscribe
}
mailbox Junk {
special_use = \Junk
+ auto = subscribe
}
mailbox Trash {
special_use = \Trash
+ auto = subscribe
}
# For \Sent mailboxes there are two widely used names. We'll mark both of
# them as \Sent. User typically deletes one of them if duplicates are created.
mailbox Sent {
special_use = \Sent
+ auto = subscribe
}
! #mailbox "Sent Messages" {
! # special_use = \Sent
! #}
# If you have a virtual "All messages" mailbox:
#mailbox virtual/All {
変更点は
- 「Drafts(下書き)」フォルダを自動作成&自動購読に設定
- 「Junk(迷惑メール)」フォルダを自動作成&自動購読に設定
- 「Trash(ゴミ箱)」フォルダを自動作成&自動購読に設定
- 「Send(送信済み)」フォルダを自動作成&自動購読に設定
- 送信済みとして「Sent Messages」も定義されているが、二重には必要ないのでコメントアウト
の設定を施しています。
既定で実行されるSieveスクリプトの作成
先程の設定で、全ユーザに「迷惑フォルダ」として「Junkフォルダ」が必ず存在するようになりました。そこで、前に設定した「Rsapmd」で迷惑判定されたメールを、自動的に「Junkフォルダ」に入れてしまいましょう。次のコマンドを実行してください。
cd /usr/local/etc/dovecot
mkdir -p sieve/befor
cd sieve
chown vmail:vmail before
chmod 700 before
このディレクトリ(/usr/local/etc/dovecot/sieve/before)は、「/usr/local/etc/dovecot/conf.d/90-sieve.conf」ファイルの「sieve_before」で指定したディレクトリになります。このフォルダに存在するSieveスクリプトは、メール受信時(Dovecot LMTPがメールを配送するとき)にアルファベット順に次々と実行されます。では、このディレクトリに「spam.sieve」というSieveスクリプトを作成します。
/usr/local/etc/dovecot/sieve/before/spam.sieve
require "fileinto";
if header :contains "X-Spam" "Yes" {
fileinto "Junk";
}
見ての通り、メールのヘッダに「X-Spam」があり、その内容が「Yes」なら「Junk」に放り込む、とう単純なスクリプトです。このファイルを作成し終えたら「コンパイル」と「所有者・パーミッションの設定」を行いましょう。
cd /usr/local/etc/dovecot/sieve/before
sievec spam.sieve
chmod 600 *
chown vmail:vmail *
これでSPAM判定されたメールは、自動的に「Junkフォルダ」に放り込まれます。
Dovecotの再起動
設定が終わりましたら、Dovecotを再起動しましょう。次のコマンドを実行してください。
service dovecot restart
これで設定完了です。
(とりあえずの)動作確認したい場合は…
動作確認したい場合は、telnetでDovecotに接続し、そのCAPABILITYを確認してみましょう。
telnet localhsot 143
次のような応答があるはずです。
Trying ::1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ STARTTLS AUTH=PLAIN] IMAP server ready.
次は認証してCAPABILITYを見るのですが、実はlocalhostからの接続に限り、Dovecotは平文の認証を受け付けます。そこで
A10 LOGIN test@example.com password
と打ってみてください(メールアドレス、パスワードは実際のもので)。認証が成功すると、次のように応答があります。
A10 OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY PREVIEW STATUS=SIZE SAVEDATE LITERAL+ NOTIFY METADATA SPECIAL-USE IMAPSIEVE=sieve://hostname.example.com QUOTA] Logged in
ずらずらとCAPABILITYが並んでいますが、ここの最後の方に「METADATA」「IMAPSIEVE=sieve://hostname.example.com」が出ていれば、とりあえずDovecotがSieveを認識していると分かります。
次に、ManageSieveが動いているかどうか確認してみましょう。localhostのTCP/4190にtelnetしてみます。
telnet localhost 4190
ManageSieveが正常に起動していれば、接続ができて応答があるはずです。
Trying ::1...
Connected to localhost.
Escape character is '^]'.
"IMPLEMENTATION" "Dovecot Pigeonhole"
"SIEVE" "fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext editheader imapsieve vnd.dovecot.imapsieve"
"NOTIFY" "mailto"
"SASL" "PLAIN"
"STARTTLS"
"VERSION" "1.0"
OK "IMAP server ready."
この応答が得られればManageSieveは稼働しています。