Linux IMAPサーバー (dovecot by sendmail with procmail)

(2009.1.17 - 2019.5.21)

imapサーバーをたてimaps対応メーラーでメールの管理。dovecotによるimapsサーバー,sendmailによるsmtpsサーバー,procmailによるメールの振り分け,予約送信

(環境) CentOS 7.5, CentOS 6はこちら, CentOS 5はこちら

以下プロンプトが#ならroot,$なら普通のユーザー。

dovecot 2

dovecot 2をインストール
# yum install dovecot

dovecot設定ファイルの変更

imapプロトコル選択
# cd /etc/dovecot
# vi dovecot.conf

# Protocols we want to be serving.
#protocols = imap pop3 lmtp
protocols = imap
メールボックスの場所指定
# cd /etc/dovecot/conf.d
# vi 10-mail.conf
# Location for users' mailboxes. The default is empty, which means that Dovecot
# tries to find the mailboxes automatically. This won't work if the user
mail_location = maildir:~/Maildir
プレインテキストパスワードを使えるようにする。
# vi 10-auth.conf

# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
disable_plaintext_auth = no
Dovecot limits exceeded: max_userip_connections: 対応
# vi 20-imap.conf

  # 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
  mail_max_userip_connections = 100
自宅からthunderbird/imapで利用していると,頻繁に「サーバとの接続が切断されました」と表示されるようになった。ログを見るとこれが原因のよう。スマートフォン,タブレット,パソコンが2台あるからか?

SSL/TLSを使えるようにする。

# vi 10-ssl.conf

# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = yes

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
#ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
#ssl_key = </etc/pki/dovecot/private/dovecot.pem
ssl_cert = </etc/pki/tls/certs/mail.pem
ssl_key = </etc/pki/tls/certs/mail.pem
pemファイルの作り方(国,県,市,組織,部署,メールサーバー名,管理者メールアドレスを入力)
# cd /etc/pki/tls/certs/
# make mail.pem

...

-----
Country Name (2 letter code) [GB]:JP
State or Province Name (full name) [Berkshire]:Kanagawa
Locality Name (eg, city) [Newbury]:Sagamihara
Organization Name (eg, company) [My Company Ltd]:Kitasato University
Organizational Unit Name (eg, section) []:College of Liberal Arts and Sciences
Common Name (eg, your name or your server's hostname) []:mail.kitasato.com
Email Address []:postmaster@kitasato.com
Common Nameにはサーパー名を正確に入れること。

なお,pemファイル,PEM (Privacy Enhanced Mail)形式とは,デジタル証明書(X509証明書)を文字列で表現するフォーマット。ここでのmail.pemは,rootの読み書きだけが許可された(600))デジタル署名,公開鍵と秘密鍵の全ての入ったファイルである。

(注)すでにhttpdのSSLの秘密鍵と証明書が作ってある場合は,それを使う。上記mail.pemのかわりに

ssl_cert = </etc/pki/tls/certs/server.crt 
ssl_key = </etc/pki/tls/certs/server.key
を指定する。また,SSL証明書を購入した場合は,次のように中間証明書を指定する。
ssl_ca = </etc/pki/tls/certs/server-chain.crt

ポート993番のオープン(tcp)

# firewall-cmd --permanent --add-port=993/tcp
# firewall-cmd --reload

logwatch 7.4.0のバグ修正

logwatch 7.4.0を使ってdovecotのログ(/var/log/maillog)を見る場合,大量のUnmatched Entriesが出る。これはlogwatchのバグなので,logwatch 7.5.1を参考にして以下のように修正する。
# vi /usr/share/logwatch/scripts/services/dovecot
262行目の次の行に以下を挿入(太字部分)()
    } elsif (($Reason) = ($ThisLine =~ /Disconnected \((.*)\):/) ) {
       $Disconnected{$Reason}++;
    } elsif ($ThisLine =~ /Logged out (rcvd|bytes|top|in)=.*/) {
       $Disconnected{"Logged out"}++;
    } elsif ($ThisLine =~ /Server shutting down./) {
       $ConnectionCl{"Server shutting down"}++;
    } elsif (($Reason, $Host) = ($ThisLine =~ /TLS initialization failed/        ) ) {

dovecot再起動と自動起動の設定

# systemctl restart dovecot
# systemctl enable dovecot
以上で,メールクライアントから,imaps(imap, ssl)でサーバーのユーザに同じユーザ名とパスワードを使って安全にimap接続できるようになる。imap接続なので,ローカルに蓄積していたメールや,他のメールサーバーにためていたメールを,メールクライアントソフトを使って,このサーバー一箇所に移動(コピー)して,安全に蓄積管理できる。バックアップは,ホームディレクトリのMaildirディレクトリをtarでバックアップすればいいだけなので,とても楽。

sendmailによるsmtps

smtpsを使えば,メールクライアントからメールを送るときに,パスワードを盗まれること無く,安全にメールを送れます。

sendmail-cfのインストール

sendmail.mcからsendmail設定ファイル(sendmail.cf)を作成するのに必要なsendmail-cfをインストールする。
# yum install sendmail-cf

sendmail.mcの編集

sendmail.mc,sendmail.cfのバックアップをとって編集開始。
# cd /etc/mail
# cp sendmail.mc sendmail.mc.org
# cp sendmail.cf sendmail.cf.org
# vi sendmail.mc
外部からの受信を許可。(,Addr=127.0.0.1をトル)
DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl
SMTP-Authの有効化。(行頭のdnlを削除)
TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')
pemファイルの指定。(太字部分を追加)
dnl define(`confCACERT_PATH',`/usr/share/ssl/certs')
dnl define(`confCACERT',`/usr/share/ssl/certs/ca-bundle.crt')
dnl define(`confSERVER_CERT',`/usr/share/ssl/certs/mail.pem')
dnl define(`confSERVER_KEY',`/usr/share/ssl/certs/mail.pem')
define(`confCACERT_PATH',`/etc/pki/tls/certs')
define(`confCACERT',`/etc/pki/tls/certs/mail.pem')
define(`confSERVER_CERT',`/etc/pki/tls/certs/mail.pem')
define(`confSERVER_KEY',`/etc/pki/tls/certs/mail.pem')
(注)すでにhttpdのSSLの秘密鍵と証明書が作ってある場合は,それを使う。上記mail.pemのかわりに
define(`confCACERT',`/etc/pki/tls/certs/server.crt')
define(`confSERVER_CERT',`/etc/pki/tls/certs/server.crt')
define(`confSERVER_KEY',`/etc/pki/tls/certs/server.key')
を指定する。SSL証明書を購入した場合は,confCACERTに中間証明書を指定する。
define(`confCACERT',`/etc/pki/tls/certs/server-chain.crt')
SMTPSの有効化。(行頭のdnlを削除)
DAEMON_OPTIONS(`Port=smtps, Name=TLSMTA, M=s')dnl
sendmail.cfの書き換え。
# m4 /usr/share/sendmail-cf/m4/cf.m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
SMTP-Authの起動と自動起動設定。
# /etc/init.d/saslauthd restart
# /sbin/chkconfig saslauthd on

procmailrcの作成

(sendmailはMaildir形式に対応していない。その対処)
# vi /etc/procmailrc

SHELL=/bin/bash
PATH=/usr/bin:/bin
DROPPRIVS=yes
MAILDIR=$HOME/Maildir
DEFAULT=$MAILDIR/
#LOGFILE=$HOME/procmail.log
#VERBOSE=ON

465番(smtps)ポートのオープン(tcp)

firewall-cmd --permanent --add-port=465/tcp
firewall-cmd --reload
なお,メールを受信する場合やメーリングリストを使う場合は,25番(smtp)ポートもあけておく。
以上で,メールクライアントから,smtps(smtp, ssl)でサーバーのユーザと同じユーザ名とパスワードを使ってパスワードを盗まれること無く安全にメールを送れるようになる。メールアドレスは,ユーザ名@サーバ名。送信したメールもホームディレクトリのMaildirディレクトリに蓄積される。

procmailによるメールの振り分け

procmailを使ってサーバー側でメールをフォルダへ振り分ける。

まず,ユーザのホームディレクトリの.forwardファイル(無ければ新規作成)に次の一行を追加する。

"|IFS=' ' && exec /usr/bin/procmail -f- || exit 75 #~/Maildir/"
そして,ユーザのホームディレクトリに次のような内容の .procmailrc ファイルを作成する。
#
SHELL=/bin/bash
PATH=$HOME/bin:/usr/bin:/usr/local/bin
MAILDIR=$HOME/Maildir/
DEFAULT=$MAILDIR
LOGFILE=$MAILDIR/procmail.log

#To:又はCC:にhiroshi@mail.comという文字列の入っているメールはmyfolderというフォルダに振り分ける。
:0
* ^(To|CC).*hiroshi@mail.com.*
.myfolder/
サブフォルダへの振り分けを指定するには,ディレクトリMaildirを覗いてわかる通り . で区切って,.myfolder.subfolder/ のように書く。

procmailの書き方(レシピ)は,別サイトを参照。

タイマー送信(予約送信)

sendmailコマンドとcrontabを使えば,メールを何日の何時に送りたい,という予約送信ができる。以下はDraft.sendlaterフォルダに入れたメールを平日の指定時刻(引数1で指定)に送るbashスクリプト。BCCにダミーのアドレスでsend@12271220のように送信日時分を指定して送ることもできる。

なお,Thunderbirdなどで送信サーバーを選択できる場合,送信サーバーがこのスクリプトを設置したサーバーでなくても問題はおこりません。つまり色々なサーバーからで送信予約が使えます。

#!/bin/bash
#
# run this by crontab as
# */5 * * * * ~/sendlater 0830

# Draft.sendlaterフォルダのメールを平日の引数1で指定される送信時分に予約送信する。
# BCCに send@12271220
# のようなダミーのメールアドレスをつけると送信日時分を指定できまず。

# holidays, 2017 毎年変更して下さい
hday="010[1-3]|0109|0211|0320|0429|0502|0503|0504|0505|0717|0811|0918|0923|1009|1103|1123|1223|1229|123[01]"

# sendlater folder
dir=~/Maildir/.Drafts.sendlater/cur/
# Sent folder
sent=~/Maildir/.Sent/cur/

# temp file name
files=~/sendlater.lst
tmp=~/sendlater.tmp

### 以下は変更不要 ###############
ls -1 $dir > $files
while read line
do
  if [[ $line =~ T$ ]] ; then
    continue
  fi
  cc=`awk '/^BCC:.*send@/ {print $0}' $dir$line`
  if [ -n "$cc" ]; then
    #BCCのダミーメールアドレスで送信日時分を指定 例 send@12271220
    ts=`echo $cc | cut -d"@" -f2`
    tn=`date +%m%d%H%M`
    tp=`expr $ts + 6`
    if [ $ts -le $tn -a $tn -le $tp ]; then
      echo "bcc" $ts "<" $tn "<" $tp
    else
      continue
    fi
  else
    #引数1で送信時分を指定 #休日は送信しない
    if [[ `date +%u` =~ [67] ]] ; then
      #echo "satday/sunday"
      continue
    fi
    if [[ `date +%m%d` =~ $hday ]] ; then
      #echo "holiday"
      continue
    fi
    tn=`date +%H%M`
    tp=`expr $1 + 6`
    if [ $1 -le $tn -a $tn -le $tp ]; then
      echo "workday" $1 "<" $tn "<" $tp
    else
      continue
    fi
  fi

  echo "sent" $line
  date="Date: `LANG=en_US.UTF-8 date '+%a, %d %b %Y %T'` +0900"
  awk --assign awk_var="$date" '
    /^Date: / {print awk_var; next}
    /^BCC:.*send@/ {next}
    {print $0}
  ' $dir$line > $tmp
  /usr/sbin/sendmail -t < $tmp
# /usr/sbin/sendmail $bcc < $tmp
  awk --assign awk_var="$date" '
    /^Date: / {print awk_var; next}
    {print $0}
  ' $dir$line > $sent$line
  rm -f $dir$line   
done < $files

参考

  1. CentOSで自宅サーバー構築 (http://centossrv.com/) 2008.5
  2. メールサーバ(POP/IMAP)の構築(Dovecot) (http://kajuhome.com/dovecot.shtml) 2014.1
  3. ThunderbirdでDovecotのIMAPに接続すると「サーバとの接続が切断されました」と表示される 2014.2
  4. Dovecot Wiki 2014.2

  5. 2008.07.10: sendmailとspamassassin(http://www.curs-sytes.com/blog/item/157) 2013.10.15現在
  6. SpamAssassinでスパム対策(http://www.miloweb.net/spamassassin.html) 2013.10.15現在
  7. SpamAssassin によるスパムメール対策(http://linux.kororo.jp/cont/server/spamassassin.php) 2013.10.15現在
  8. CentOS メールサーバー構築(sendmail+Dovecot)(http://dev.halhal.info/archives/11) 2013.10.15現在
  9. URL.JP 2014.1.4
  10. sa-update - automate SpamAssassin rule updates 2014.1
  11. Procmailによるメールの自動振り分け (http://linux.kororo.jp/cont/server/procmail.php) 2015.7.15