= mail / LM: [2024-09-04 16:43:44]
メールサーバの設定についてのメモを置く場所.
間借りしていたメールサーバーがもうすぐなくなりそうと言うことで,自分でさくらの VPS なサーバを借りた.だが,vCPU が 2 core,メモリ 1GB ということで,全文検索などあまり多くの機能を動かすとすぐにメモリがリソースが溢れそう.リソースと言う意味では,必ず 1 台は,設置場所の停電などで止まることがあるが,グローバル IP の振られている自分のマシンを確保している.そこで,さくら VPS はメールを受けとる専用,もう一台をメインで imap 接続したり spam 処理,全文検索処理などを行う構成にした.
% imapsync --host1 mail2.sakaki.works --port1 143 --authmech1 LOGIN --user1 skk.bps@sakaki.works --password1 "Password" --host2 mail2.sakaki.works --port2 143 --authmech2 LOGIN --user2 skk.bps@sakaki.works --password2 "Password"
% imapsync --host1 mail2.sakaki.works --port1 143 --authmech1 LOGIN --user1 skk.bps@sakaki.works --password1 "Password" --host2 mail2.sakaki.works --port2 143 --authmech2 LOGIN --user2 skk.bps@sakaki.works --password2 "Password" --folder コピー元対象フォルダ --f1f2 コピー元対象フォルダ=コピー先対象フォルダ
(2007 年時点の設定参照)
SSL/TLS に対応した
smtpd_tls_cert_file = /usr/local/etc/letsencrypt/live/ns.sakaki.works/cert.pem smtpd_tls_key_file = /usr/local/etc/letsencrypt/live/ns.sakaki.works/privkey.pem smtpd_tls_CAfile = /usr/local/etc/letsencrypt/live/ns.sakaki.works/fullchain.pem smtpd_tls_session_cache_database = btree:/var/cache/postfix/smtpd_scache smtpd_tls_session_cache_timeout = 3600s smtpd_tls_received_header = yes smtpd_tls_loglevel = 1
特定の From ドメインからのみ,特定の relay_host を利用するように設定した.個人メールアカウントは,さくら VPS から直接配送とし,会社のメールは,会社の SMTP サーバ(Amazon SES)に送る,という流れ.
/usr/local/etc/postfix/main.cf は以下の通り.
smtp_use_tls = yes smtp_sender_dependent_authentication = yes sender_dependent_default_transport_maps = hash:/usr/local/etc/postfix/sender_relay smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous smtp_sasl_password_maps = hash:/usr/local/etc/postfix/sasl_passwd smtp_always_send_ehlo = yes smtp_tls_policy_maps = hash:/usr/local/etc/postfix/tls_policy #smtp_tls_wrappermode = yes #smtp_tls_security_level = encrypt smtp_tls_security_level = may smtp_tls_note_starttls_offer = yes smtp_tls_cert_file = /usr/local/etc/letsencrypt/live/ns.sakaki.works/cert.pem smtp_tls_key_file = /usr/local/etc/letsencrypt/live/ns.sakaki.works/privkey.pem smtp_tls_CAfile = /usr/local/etc/letsencrypt/live/ns.sakaki.works/fullchain.pem
まず,smtp_sender_dependent_authentication を設定することで,sender_dependent_default_tarnsport_maps が有効になるように. sender_dependent_default_transport_maps には,以下のような sender_relay 情報を記述.
@bpsinc.jp smtps:email-smtp.us-west-2.amazonaws.com:587
Amazon SES から発行されているユーザ名とパスワードは,tls_policy にて encrypt を指定した後,sasl_passwd に以下のように設定.
sasl_passwd:
email-smtp.us-west-2.amazonaws.com ユーザ名:パスワード
tls_policy:
email-smtp.us-west-2.amazonaws.com:587 encrypt
sender_relay, sasl_passwd, tls_policy は,それぞれ postmap コマンドを通すのを忘れないように.
はまったのが,relay_host で SMTPS(465) で送信しようとすると,postfix の挙動全体で,
smtp_tls_wrappermode = yes
smtp_tls_security_level = encrypt
と書いた上で,25 番への relay ができないモードになってしまうと言う部分.これが,どうしても解決できずに,どこかで見た,submission ポートで送ってみたら,ちゃんと認証した上で送信してくれることが分かったので,この設定にしておくことに.
(2007 年時点の設定参照)
後で,FTS (Full Text Search) を行うため,ports インストールをする際に SOLR を選択する.すでに設定してしまっている人は,以下のように ports ディレクトリに移動して make config する.
% cd /usr/ports/mail/dovecot % make config
Maildir から dbox にした.Maildir は,1メール1ファイルで,既読管理をファイル名に頼っている.そのため,メール数が増えてきた時に,ストレージへのアクセスが大量に発生するため,パフォーマンスが落ちやすい.
dbox はメールを 10MB までのファイルにパッキングしつつ管理している.メタ情報は 10MB までのファイルの中に書いているため,ストレージへのアクセスがバランス良くなっているものと思われる.ちなみに mbox 形式は,1 フォルダのメールを 1 ファイルに入れるため,メールが多くなってきた時に,大量のデータを読み込まねばならず,これはこれでパフォーマンスの劣化につながっていた.
mail_location = mdbox:/home/mail/%d/%n
さくら VPS は 100GB しかストレージがないので,メールを圧縮するようにした.
以下の設定をしておけば,新規に到着するメールからは dbox ファイルの中で,そのメールだけ gzip 圧縮される.gzip 以外にも bzip2 などの圧縮形式は選択できる.新規到着メールから圧縮されるようになるのと,そこまでメール閲覧に関してパフォーマンスが悪くなった印象はないので,早い段階で設定しておいた方が良いと思う.後で dbox 形式のメールを全部圧縮するには,一度 dsync や imapsync などを利用してメールボックスを移動させて,圧縮が動作するようにしなければならないので,めんどくさい.
mail_plugins = $mail_plugins zlib plugin { zlib_save = gz zlib_save_level = 6 }
[2023-04-29]
追記:
mdbox を見ても,テキストで保存されていた.
plugin lda の中の mail_plugin にも zlib を追記しないと動かなかったかもしれない.
protocol lda { deliver_log_format = msgid=%m: %$ info_log_path = /var/log/dovecot-lda.log log_path = /var/log/dovecot-lda.log mail_plugins = sieve zlib ...
SSL/TLS に対応した.Let's encrypt を利用.Let's Encrypt の利用は別のページ参照.
dovecot.conf に以下の設定を行う.dh.pem については,存在していないので,事前に以下のコマンドで作成しておく.
% dd if=/var/db/dovecot/ssl-parameters.dat bs=1 skip=88 | openssl dhparam -inform der > /usr/local/etc/dovecot/dh.pem
dovecot.conf 設定:
service imap-login { inet_listener imaps { port = 993 ssl = yes } } ssl = yes ssl_dh = </usr/local/etc/dovecot/dh.pem ssl_cert = </usr/local/etc/letsencrypt/live/mail2.sakaki.works/fullchain.pem ssl_key = </usr/local/etc/letsencrypt/live/mail2.sakaki.works/privkey.pem
イコールのあとの ”<” は typo でないので注意.
doveadm コマンドを活用しまくると,コマンドラインにてメールの検索,メールボックスのサイズ取得,などが行えるので,シェルなどの操作がしやすい.普段の仕事では Thunderbird(+external edit) を使うので,コマンドラインを使うことはないが,管理していく際には活用しやすい.
doveadm の man の中に,色々なコマンドが書いてあり,doveadm-command という名前で man が準備されている. 基本的に root (または,mail ユーザ)でないと動作しない.
% man doveadm-purge
メールに対しての refcount が 0 になってるものを実際にストレージ上から削除するコマンド.Disk I/O の少ないタイミングで実行される,と記述があったが,実際に実行されているかの確認は [2021-12-31] 現在,とれていない.
[2024-09-04] 少なくとも利用しているファイル保存形式が mdbox の場合,メールクライアントからメールを大量に削除しただけでは,まだ,ストレージ自体の削減にはならないが,sudo doveadm purge -u hoge@hoge.com を実行した後は,ストレージが削減されているのを確認できた.doveadm mailbox で確認できるサイズよりもずっと多くのストレージが削減されているように見えている.base64 やファイルシステムのブロックサイズが影響するのか…?と妄想するが,確認はとれていない.
% sudo doveadm purge -u hoge@hoge.com
% sudo doveadm purge -A
% man doveadm-search
返ってくるのは,guid と uid という,内部管理の ID なので,次の fetch と併用して利用することになる.
% doveadm search -u <username> <キー>
% doveadm search -u <username> subject "件名"
% doveadm search -u <username> from 'hoge@hoge.com'
% doveadm search -u <username> mailbox 'Archives'
% man doveadm-fetch
guid, uid をベースに検索するので,ほぼ search と併用する.
% doveadm search -u skk.bps@sakaki.works from 'hoge@hoge.com| while read guid uid; do doveadm fetch -u <username> mailbox mailbox-guid $guid uid $uid | nkf -w \\ done
% doveadm search -u <username> mailbox 'Archives' | while read guid uid; do doveadm fetch -u <username> hdr.from mailbox-guid $guid uid $uid | grep -o "[-_a-zA-Z0-9\.]*@[-a-zA-Z0-9\.]*" done
% man doveadm-user
dovecot が認識しているユーザについての情報の表示・コントロールを行うコマンド.
passdb において,以下のような設定がしてある場合,dovecot.passwd.db に書いてあるユーザのみが一覧表示されるはず.
passdb { args = /usr/local/etc/dovecot.passwd.db driver = passwd-file }
% doveadm user '*'
% doveadm user -u <username>
% man doveadm-mailbox
メールボックスの中で設定されているフォルダに関する情報を得るためのコマンド.
% doveadm -f table mailbox status -u skk.bps@sakaki.works "vsize" '*'
% doveadm -f table mailbox status -u skk.bps@sakaki.works "vsize" '*' | awk -F' ' '{print $2 " " $1}' | sort -n
% doveadm -f table mailbox status -u skk.bps@sakaki.works "messages vsize" spam
% man doveadm-quota
以下が dovecot.conf に書いてある場合にのみ,利用できるコマンド.現状では特に quota を設定していないので,設定の仕方は分からない.
mail_plugins = $mail_plugins quota plugin { quota = count quota_vsizes = yes }
% doveadm quota get -u skk.bps@sakaki.works
% man doveadm-replicator % mad doveadm-dsync
そのうち書きたい.多分,コマンドラインでサーバ間の sync を行うなども可能だと思われる.imapsync の代わりとして利用できそうな気がする.imapsync より高速だと思われる.
Replication with dsync に,基本的に全て書かれている.二つの dovecot サーバ間で master/master 同期を行う,という機能.メールボックスに何か変化があった場合,replicator というプロセスが走り,もう一つのサーバに同期をかける.[2021-05-27] 現在,なんらかの原因で replicator プロセスが暴走することがあり,ちょいちょい core dump しているのが気になるが,原因は不明.
以下の設定は,さくら VPS・オンプレマシンの両方に必要.
/usr/local/etc/dovecot/dovecot.conf:
mail_plugins = $mail_plugins notify replicator service replicator { process_min_avail = 1 vsz_limit = 512M unix_listener replicator-doveadm { mode = 0600 } } dsync_remote_cmd = ssh -i /root/id_rsa -l%{login} %{host} doveadm dsync-server -u%u plugin { # mail_replica = remote:root@mail2.sakaki.works mail_replica = tcp:mail2.sakaki.works:12345 } service aggregator { fifo_listener replication-notify-fifo { user = mailuser } unix_listener replication-notify { user = mailuser } } replication_max_conns = 10 plugin { # When saving a new mail via IMAP or delivering a mail via LDA/LMTP, # wait for the mail to be synced to the remote site. If it doesn''t finish # in 2 seconds, return success anyway. replication_sync_timeout = 10 } doveadm_password = password
大事なのは,mail_replica の辺りで,ssh を使う方法と TCP を使う方法が存在している.
ssh 経由で行う場合は,root でのログインを有効にしないと行けないので,sshd において,以下のような設定をしておきつつ,鍵をお互いの root/.ssh/authorized_keys に登録すると良い.
## Okay allow root login with public ssh key for 210.160.237.138 ## Match Address 210.160.237.138 PermitRootLogin yes
今回は tcp を利用した.この場合,doveadm_password にて,お互いに共通のパスワードを書いておく必要がある.また,dsync_remote_cmd は必要ないと思われるが,消すのがめんどくさいので残してある.
dsync では,doveadm user で出てくるユーザ全てを同期してしまう.特定ユーザのみ同期したくない場合は,dovecot.passwd.db (passwd-file) の対象ユーザに,以下のような記述をしておく.
username:{plain}hogehoge:5000:5000::/home/mail/%d/%n::userdb_noreplicate=y
多くのページにて,userdb_ prefix がいらない,と書いてあった気がするが,結局つけなければ動作しなかった.
Apache Solr は,Java で動作する全文検索エンジンらしい.動作自体は,http://localhost:8983 など立ち上がり,そこにコマンドを http で送る形式の模様.
以下のような形で,textproc/apache-solr をインストールする.
/usr/local/etc/solr.in.sh の中に,データベース情報を保存する先の指定などができる模様.今回は特に変更せず,デフォルトのまま利用した.
% portmaster -D textproc/apache-solr % echo "solr_enable=\"YES\"" >> /etc/rc.conf % /usr/local/etc/rc.d/solr start
fts_solr プラグインを入れることで,メールボックスにメールが到着した際に,java な solr プロセスを立ち上げてインデックスを作成している模様.
設定の中にある indexer-worker は,indexer-worker という名前のプロセスが立ち上がる.xapian を設定した際も立ち上がっていたので,FTS 全般で動作する親プロセスみたいなものだと思われる.process_limit を指定しているのは,xapian が阿呆みたいにプロセスを立ち上げまくって,HDD を苛め抜いていたので,制限をかけた名残.これが残ったままでも Solr 自体は快調に動いてる.
text2decode は,xapian を設定している際に見かけた,添付ファイルや mime encode されたメールも処理できるようなスクリプトだと思われる.一応指定してあって問題はなさそう.
dovecot.conf:
mail_plugins = $mail_plugins fts fts_solr plugin { fts = solr fts_solr = url=http://127.0.0.1:8983/solr/dovecot/ fts_autoindex = yes fts_autoindex_exclude = \Trash fts_decoder = decode2text } service indexer-worker { vsz_limit = 4G process_limit = 2 } service decode2text { executable = script /usr/local/libexec/dovecot/decode2text.sh user = dovecot unix_listener decode2text { mode = 0666 } }
(2007 年時点の設定参照)
virtual domain 前提。
dovecot-1.2.17 Secure and compact IMAP and POP3 servers dovecot-sieve-1.2+0.1.18_1 A Sieve plugin for the Dovecot 'deliver' LDA
plugin { ... sieve=/home/mail/%d/%n/.dovecot.sieve }
protocol lda { ... mail_plugins = sieve }
filter unix - n n - 10 pipe flags=DRhu user=mailuser argv=/usr/local/bin/spamc -e /usr/local/libexe
c/dovecot/deliver -f ${sender} -d ${recipient}
rewrite_header Subject [SPAM]
postfix + dovecot でメールサーバ構築.環境は,FreeBSD 5.5R.
2007/03/17 作業.
# portupgrade -N mail/postfix
sendmail_enable="NO" // もし,yes となっていたら. postfix_enable="YES"
postfix: root
myhostname = banana2887.maido3.com mydomain = maido3.com myorigin = $mydomain inet_interfaces = all mynetworks = 127.0.0.0/8 ## virtual mailbox virtual_mailbox_domains = ztdn.org virtual_mailbox_base = /home/mail virtual_mailbox_maps = hash:/usr/local/etc/postfix/vmailbox virtual_minimum_uid = 100 virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_alias_maps = hash:/usr/local/etc/postfix/virtual ## sasl smtpd_sasl_auth_enable = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
上記3つは,ローカル配送したときとかに利用されるドメインになる.一番のベースドメインと言える.現在の設定ではヘッダの中に名前が出てしまうのでかっこわるい.
ここまでで,smtp server としての基本が終わり.次から,virtual host 設定と認証の設定に入る.
virtual_gid_maps = static:5000 : /home/mail 以下のファイルは gdi 5000 で取り扱われる. virtual_alias_maps = hash:/usr/local/etc/postfix/virtual : 後述.alias ファイルに近い.
skk@ztdn.org ztdn.org/skk/ yuki@ztdn.org ztdn.org/yuki/ www@ztdn.org ztdn.org/www/
# postmap /usr/local/etc/postfix/vmailbox
info@ztdn.org skk@hoge.com ml@hoge.com ml@localhost
ml: "|/path/to/mlprogram"
virtual host のケースによっては,他の実装方法がよいかもしれない.他の方法に関しては,ここを参照.
# restrict mail relay only to ice.bps smtp_use_tls = yes smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/usr/local/etc/postfix/relay_password smtp_sasl_security_options = noanonymous smtp_sasl_tls_security_options = noanonymous data_directory = /var/db/postfix
# vi /usr/local/etc/postfix/relay_password [smtp.hoge.jp]:587 hoge@hoge.jp:hogepassword # postmap /usr/local/etc/postfix/relay_password
protocols = imap pop3 listen = * mail_location = maildir:/home/mail/%d/%n first_valid_uid = 500 last_valid_uid = 5000 first_valid_gid = 0 last_valid_gid = 5000 auth default { # Space separated list of wanted authentication mechanisms: # plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi mechanisms = plain login passdb passwd-file { # Path for passwd-file args = /usr/local/etc/dovecot.passwd.db } passdb passwd-file { # Path for passwd-file args = /usr/local/etc/dovecot.passwd.db } socket listen { client { path = /var/spool/postfix/private/auth mode = 0660 user = postfix group = postfix } } }
skk@hoge.com:{CRAM-MD5}thaoseuh:5000:5000:/home/mail/%d/%n yuki@hoge.com:{plain}password:5000:5000:/home/mail/%d/%n
% doveconf -n
The standard filename definition is: "<base filename>:2,<flags>". Dovecot has extended the <flags> field to be "<flags>[,<non-standard fields>]". This means that if Dovecot sees a comma in the <flags> field while updating flags in the filename, it doesn't touch anything after the comma. However other maildir MUAs may mess them up, so it's still not such a good idea to do that. Basic <flags> are described here. The <non-standard fields> isn't used by Dovecot for anything currently. Dovecot supports reading a few fields from the <base filename>: - ,S=<size>: <size> contains the file size. Getting the size from the filename avoids doing a stat(), which may improve the performance. This is especially useful with Maildir++ quota. - ,W=<vsize>: <vsize> contains the file's RFC822.SIZE, ie. the file size with linefeeds being CR+LF characters. If the message was stored with CR+LF linefeeds, <size> and <vsize> are the same. Setting this may give a small speedup because now Dovecot doesn't need to calculate the size itself. A maildir filename with those fields would look something like: 1035478339.27041_118.foo.org,S=1000,W=1030:2,S
“P” | (passed) | the user has resent/forwarded/bounced this message to someone else. |
“R” | (replied) | the user has replied to this message. |
“S” | (seen) | the user has viewed this message, though perhaps he didn't read all the way through it. |
“T” | (trashed) | the user has moved this message to the trash; the trash will be emptied by a later user action. |
“D” | (draft) | the user considers this message a draft; toggled at user discretion. |
“F” | (flagged) | user-defined flag; toggled at user discretion. |
このページへのアクセス 今日: 5 / 昨日: 5 総計: 542