カテゴリー別アーカイブ: メール

メールに関すること

Exchange Server が正常終了しなかった場合のデータベース復旧

Exchange Server の入ったサーバが、OSごと固まったり、ハードウェアトラブルで停止した場合の復旧方法を考えてみる。

ひとまずOSを立ち上げなおすことが出来たとして、Exchange Server を起動しようとするとデータベースが dirty shutdown 状態となっており、マウントできない場合がある。

こういう場合にマイクロソフトの提供している手順ドキュメントがあるのだが…
修復済みの Exchange データベースのサポート ポリシーの変更

上記ドキュメントの手順3を進める前にデータベースをマウントする必要がある。しかし手順1、2でデータベースを掃除したにもかかわらず、それでもマウントできないということもある。

実行例:

[PS] C:\Windows\system32> Mount-Database -Identity MailboxDB01 -force
データベース "MailboxDB01" をマウントできませんでした。エラー: Active Manager
 の操作に失敗しました。エラー: データベース操作が失敗しました。エラー:
 操作が失敗し、メッセージが生成されました:
 MapiExceptionDatabaseError: Unable to mount database. (hr=0x80004005, ec=1108)
Diagnostic context:
...

そういう場合はトランザクションログが壊れている可能性が高いので、ログファイルを削除(退避)するとよい。

トランザクションログファイルの状態を示すコマンドとして、eseutil /ml コマンドがある。

[PS] C:\Windows\system32> eseutil /ml D:\Exchange\MailboxDB01\E00

これで壊れているログファイルがどれなのかわかるが、ともかくデータベースと同一ディレクトリにある拡張子.logのファイル(拡張子を隠す設定になっていたら表示すること!)をすべて別フォルダに退避してからマウントコマンドを実行するとよい。

[PS] C:\Windows\system32> D:
[PS] D:\> cd \Exchange\MailboxDB01
[PS] D:\Exchange\MailboxDB01> mkdir backup
[PS] D:\Exchange\MailboxDB01> move *.log backup
[PS] D:\Exchange\MailboxDB01> Mount-Database -Identity MailboxDB01 -force

Postfixのsender_canonical_mapsでヘッダを書きかえてくれない

sender_canonical_mapsを設定したけど、エンベロープFromは書きかわってもヘッダFromが書きかわらない!という場合がある。sender_canonical_classes にもちゃんと header_sender が含まれている(デフォルト)のに書きかわらない。

結論から言うと、local_header_rewrite_clients の設定を見直す必要がある。

デフォルトでは

local_header_rewrite_clients = permit_inet_interfaces

となっていて、サーバのローカルから送信されたメールのみ、ヘッダも書きかえるという動作をする。つまり、メールハブでいくらsender_canonical_mapsを設定しても、他サーバから送信されたメールのFromは書きかえてくれないのだ。

管理しているドメイン(ローカルネットワーク)内のどのクライアント・サーバから送られたメールでもFromヘッダを書きかえ対象としたい場合、管理対象ドメインのIPアドレスをmynetworksに列挙した上で

local_header_rewrite_clients = permit_mynetworks

とする必要がある。

参考:

Postfixで送信者(From:)によってルーティングを変更する

メールのFrom:を見て、条件により nexthop メールリレーサーバを変更する設定をしたい。アウトバウンドリレーサーバに、ライセンス数制限のあるメールセキュリティアプライアンスなどを選択したい場合に使う。

設定項目としては、sender_dependent_default_transport_maps と sender_dependent_relayhost_maps がある。どちらを使っても同等の動作を実現できるが、少し書式が異なる。

1. sender_dependent_default_transport_maps を使う場合

/etc/postfix/main.cf:

sender_dependent_default_transport_maps = hash:/etc/postfix/sender_dependent_transport

/etc/postfix/sender_dependent_transport:

@example.co.jp            smtp:[リレーサーバ1]:25
@sub.example.co.jp        smtp:[リレーサーバ2]:25

メールの送信者が foo@example.co.jp の場合はリレーサーバ1に、bar@sub.example.co.jp の場合はリレーサーバ2に送られる。

この設定は、default_transport (デフォルト値: smtp) をエンベロープ From: によって上書きするというものである。上記のような書き方もできるし、master.cf で別の transport を定義しておき右辺に使うことも可能。

2. sender_dependent_relayhost_maps を使う場合

/etc/postfix/main.cf:

sender_dependent_relayhost_maps = hash:/etc/postfix/sender_dependent_relayhost

/etc/postfix/sender_dependent_relayhost:

@example.co.jp           [リレーサーバ1]:25
@sub.example.co.jp       [リレーサーバ2]:25

これは relayhost の設定を From: によって上書きするという機能なので、テーブルの右辺は relayhost を書くときの形式でなければならない。つまり、 transport:host:port の形式ではなく、host:port だけの形式となる。

ただし、「この情報は relay_transport、default_transport および transport(5) テーブルで上書きされます。」とのことなので、transportテーブルを併用する場合は思った通りに動作しないかもしれない(そこまでは手元で試していない)。

milter-greylist で GeoIP を使えるようにする

Ubuntu 標準パッケージの milter-greylist は libGeoIP をリンクするようにコンパイルされていないので、GeoIP (IPアドレスベースの国別判定) をポリシーに利用することが出来ない。そこで Ubuntu ソースパッケージを微修正してリビルドすることで GeoIP を使えるようにする。また、ついでにPostfixへの対応を入れておく。

必要なパッケージのインストール

myserver1:~$ sudo apt-get install build-essential quilt debhelper autotools-dev bison flex
myserver1:~$ sudo apt-get install libgeoip-dev libspf2-dev libmilter-dev

ソースパッケージのダウンロード

myserver1:~$ apt-get source milter-greylist

パッケージ情報ファイルの編集

GeoIP をリンクするように、パッケージ情報ファイルを編集する。

rules ファイルを編集し、configure オプションの中に –with-libGeoIP \ を追加する。configure 実行時に libGeoIP を探してくれるようになる。

myserver1:~$ cd milter-greylist-4.3.9
myserver1:milter-greylist-4.3.9$ vi debian/rules
override_dh_auto_configure:
    dh_auto_configure -- \
    --with-user=greylist \
    --sysconfdir=/etc/milter-greylist \
    --with-conffile=/etc/milter-greylist/greylist.conf \
    --with-dumpfile=/var/lib/milter-greylist/greylist.db \
    --with-libspf2=/usr \
    --with-libmilter=/usr \
    --with-libGeoIP \  ←ここを追加
    --enable-postfix \  ←ここを追加
    --enable-dnsrbl \
    --disable-rpath \
    LDFLAGS=" -Wl,-z,defs -L/usr/lib/libmilter " \
    CFLAGS=" -fno-strict-aliasing "

また、controlファイルを編集して、Build-Depends 行に libgeoip-dev を追加する。

myserver1:milter-greylist-4.3.9$ vi debian/control
Build-Depends: quilt, debhelper (>= 8), autotools-dev, libmilter-dev, bison, flex, libspf2-dev, libgeoip-dev

パッケージバージョン番号を変更するために、changelogも編集する。内容は適当。

myserver1:milter-greylist-4.3.9$ vi debian/changelog
milter-greylist (4.3.9-101) unstable; urgency=low

  * Build with --with-libGeoIP
  * Build with --enable-postfix

 -- My Name <myname@example.com>  Mon, 30 Jun 2014 10:00:00 +0900

バージョン番号を元のパッケージより大きくしておかないと、apt-get upgrade した時に公式パッケージで置き換えられてしまう。ここでは 4.3.9-1 から 4.3.9-101 にしておいた。

ビルド

編集が終わったら、実際にビルドする。

myserver1:milter-greylist-4.3.9$ dpkg-buildpackage -us -uc

インストール

.deb パッケージが出来上がったら、公式パッケージをアンインストールして入れ換える。

myserver1:milter-greylist-4.3.9$ sudo apt-get purge milter-greylist
myserver1:milter-greylist-4.3.9$ sudo dpkg -i ../milter-greylist_4.3.9-101_amd64.deb

設定

milter-greylist を入れ換えたら、/etc/milter-greylist/greylist.conf に geoip の記述が使えるようになる。例えば自宅のサーバでは、CN からメールを受け取る予定が無いのでこれをブラックリストに入れてみる。

myserver1:~$ sudo vi /etc/milter-greylist/greylist.conf

greylist.conf の中身:

geoipdb "/usr/share/GeoIP/GeoIP.dat"
...
racl blacklist geoip "CN"

Ubuntu のパッケージリビルド (Ubuntu 14.04 LTS に milter-manager をインストール)

※以下は古い内容です。既に Ubuntu 14.04 用 milter manager パッケージが配布されています。

Ubuntu 14.04 が出たのでさっそくサーバを置き換えようとしたのだけれど、milter-managerのパッケージがまだ用意されていないので、saucyのファイルを借りてパッケージをリビルドしてみた記録。

1. 下準備

ビルド環境に必須なパッケージと、milter-managerがビルド依存するパッケージをインストールする。

$ sudo apt-get install build-essential debhelper
$ sudo apt-get install libglib2.0-dev ruby1.9.1-dev cdbs

2. 13.10 (saucy) 用ファイルのダウンロード

$ wget http://jaist.dl.sourceforge.net/project/milter-manager/ubuntu/stable/pool/saucy/universe/m/milter-manager/milter-manager_2.0.2-1.diff.gz
$ wget http://jaist.dl.sourceforge.net/project/milter-manager/ubuntu/stable/pool/saucy/universe/m/milter-manager/milter-manager_2.0.2-1.dsc
$ wget http://jaist.dl.sourceforge.net/project/milter-manager/ubuntu/stable/pool/saucy/universe/m/milter-manager/milter-manager_2.0.2.orig.tar.gz

3. ビルド

saucy用のパッケージファイルから、特に何の変更もしなくてもビルドできた。

$ tar xzf milter-manager_2.0.2.orig.tar.gz
$ cd milter-manager-2.0.2
$ gzip -cd ../milter-manager_2.0.2-1.diff.gz | patch -p1
$ dpkg-source --before-build .
$ dpkg-buildpackage -us -uc

4. インストール

dpkgコマンドでインストールする。

$ cd ..
$ sudo dpkg -i libmilter-client0_2.0.2-1_amd64.deb libmilter-core0_2.0.2-1_amd64.deb libmilter-manager0_2.0.2-1_amd64.deb libmilter-server0_2.0.2-1_amd64.deb milter-manager_2.0.2-1_amd64.deb ruby-milter-client_2.0.2-1_amd64.deb ruby-milter-core_2.0.2-1_amd64.deb ruby-milter-server_2.0.2-1_amd64.deb

※アンインストールしたい場合は以下の通り。

$ sudo apt-get purge libmilter-client0 libmilter-core0 libmilter-manager0 libmilter-server0 milter-manager ruby-milter-client ruby-milter-core ruby-milter-server

※ローカル .deb ファイルを apt-get コマンドでインストールしたい場合は、以下のページを参考に。
ローカルに置いたdebファイルをapt-get installでインストールする

手っ取り早くbase64エンコードしたい

nkf の -M オプションは、先に変換が入るためバイナリファイルのエンコードには使えない。nkfはテキストメール前提なので、JIS(ISO-2022-JP)にいったん変換してからエンコードするということらしい。
バイナリファイルを nkf -MB でエンコードして nkf -mB で戻すと全然違うファイルが出来上がる。
$ nkf -MB < 1.zip > 1.b64
$ nkf -mB < 1.b64 > 2.zip
$ md5 1.zip 2.zip
MD5 (1.zip) = 42558acff029a174684f9cf3772c9847
MD5 (2.zip) = 288077e040f5787d3767c72956ae6bf2

nkfではなく、base64コマンドを使うことできちんとエンコードできる。
$ base64 -b 72 < 1.zip > 1.b64
$ base64 -D 1.b64 > 2.zip
$ md5 1.zip 2.zip
MD5 (1.zip) = 42558acff029a174684f9cf3772c9847
MD5 (2.zip) = 42558acff029a174684f9cf3772c9847

上記はMac OS Xのシェル上で実行した結果。
Linux(GNU coreutils)のbase64コマンドは、デコードオプションが -D ではなく -d なので注意。