ラベル dovecot の投稿を表示しています。 すべての投稿を表示
ラベル dovecot の投稿を表示しています。 すべての投稿を表示

2013/10/09

z-pushとの闘い

まずは何も考えずダウンロードしてみる。

http://z-push.sourceforge.net/soswp/

# tar xzf z-push-2.1.0-1750.tar.gz
# cd z-push-2.1.0-1750
# ls
INSTALL  LICENSE  backend  config.php  include  index.php  lib  tools  version.php  z-push-admin.php  z-push-top.php

とりあえずINSTALLを読む。

サーバ要件:PHP5.1以上

ということは、PHP5.1とapacheの環境があればよいということか。

まずはDNS名(app.example.net)を用意する。

続いて鍵+証明書を作り、これをSSLサイトに食わせておく。

# openssl req -x509 -days 365 -newkey rsa:2048 -nodes -keyout app.example.net.key -out app.example.net.crt

インストールは書いてある通りにやってみよう。prefixは/usr/localにしてみる。
# sudo tar xzf z-push-2.1.0-1750.tar.gz -C /usr/local/share
# mkdir /var/lib/z-push /var/log/z-push
# chown apache:apache /var/lib/z-push /var/log/z-push
# vi /etc/httpd/conf.d/ssl.conf
# httpd -t
# service httpd reload

--- /etc/httpd/conf.d/ssl.conf      (before)
+++ /etc/httpd/conf.d/ssl.conf      (after)
@@ -81,5 +81,14 @@
        AllowOverride   all
   </Directory>

+
+       Alias /Microsoft-Server-ActiveSync /usr/local/share/z-push/index.php
+  <directory /usr/local/share/z-push>
+       php_flag magic_quotes_gpc off
+       php_flag register_globals off
+       php_flag magic_quotes_runtime off
+       php_flag short_open_tag on
+  </Directory>
+
  </VirtualHost>
 </IfModule>
というわけで、予想通りはまる。
なんか言ってる。
PHP-MAPI extension is not available

調べてみたところ、一部のパッケージが足りていなかったもよう。
# yum install php-imap php-soap php-process

と思ったら、php-processはPHP5.3のパッケージなのね。
あきらめて、php-*系のパッケージを全部捨てて、php53-*をインストール。

# rpm -e php php-たくさん
# yum install php-process php

やってみたがまだ動かぬ。
php-mapiってどこにあるんだよ!!
とりあえず「php-mapi rpm」で適当に探してくる。

.....fedoraprojectに落ちてたぽい。

# rpm -ivh php53-mapi-7.0.13-1.el5.i386.rpm
エラー: 依存性の欠如:
libicudata.so.36 は php53-mapi-7.0.13-1.el5.i386 に必要とされています
libicui18n.so.36 は php53-mapi-7.0.13-1.el5.i386 に必要とされています
libicuuc.so.36 は php53-mapi-7.0.13-1.el5.i386 に必要とされています
libinetmapi.so.1 は php53-mapi-7.0.13-1.el5.i386 に必要とされています
libmapi.so.0 は php53-mapi-7.0.13-1.el5.i386 に必要とされています

ぬおー。片っ端から探していれちまえ。
# rpm -ivh libmapi-7.0.13-1.el5.i386.rpm php53-mapi-7.0.13-1.el5.i386.rpm
エラー: 依存性の欠如:
libboost_filesystem-mt.so.5 は libmapi-7.0.13-1.el5.i386 に必要とされています
libboost_system-mt.so.5 は libmapi-7.0.13-1.el5.i386 に必要とされています
libical.so.0 は libmapi-7.0.13-1.el5.i386 に必要とされています
libicalss.so.0 は libmapi-7.0.13-1.el5.i386 に必要とされています
libvmime.so.0 は libmapi-7.0.13-1.el5.i386 に必要とされています
zarafa-client = 7.0.13-1.el5 は libmapi-7.0.13-1.el5.i386 に必要とされています

えー。zarafa-clientが出てきたってことは、結局zarafaから落とした方がいいの?
でもさっきからEPELのパッケージ使ってるし….よし、ポリシーを緩めてEPEL解禁!
# rpm -ivh epel-release-5-4.noarch.rpm
# yum install php53-mapi
Dependencies Resolved
========================================================================================================================
Package                           Arch               Version                                  Repository          Size
========================================================================================================================
Installing:
php53-mapi                        i386               7.0.13-1.el5                             epel               217 k
Installing for dependencies:
boost141-filesystem               i386               1.41.0-4.el5                             epel                73 k
boost141-system                   i386               1.41.0-4.el5                             epel                25 k
libgsasl                          i386               0.2.29-1.el5                             epel               100 k
libical                           i386               0.48-1.el5                               epel               202 k
libmapi                           i386               7.0.13-1.el5                             epel               904 k
libntlm                           i386               1.0-1.el5                                epel                43 k
libvmime                          i386               0.9.2-0.1.20110626svn.el5                epel               887 k
zarafa-client                     i386               7.0.13-1.el5                             epel               1.3 M
zarafa-common                     i386               7.0.13-1.el5                             epel                22 k
Transaction Summary
========================================================================================================================
Install      10 Package(s)
Upgrade       0 Package(s)
Total download size: 3.7 M

Is this ok [y/N]: 

まぢで?そういうオチ?
とりあえず入れてみる…..入った。
気を取り直してapacheリロード。
# httpd -t
Syntax OK
# service httpd reload

とりあえず500はなくなった。

続いて、config.phpをいじって、imapバックエンドを使うように変更。
--- /usr/local/share/z-push/config.php     (before)
+++ /usr/local/share/z-push/config.php     (after)
@@ -45,7 +45,7 @@
*  Default settings
*/
// Defines the default time zone, change e.g. to "Europe/London" if necessary
-    define('TIMEZONE', '');
+    define('TIMEZONE', 'Asia/Tokyo');
// Defines the base path on the server
define('BASE_PATH', dirname($_SERVER['SCRIPT_FILENAME']). '/');
@@ -90,7 +90,7 @@
define('LOGFILE', LOGFILEDIR . 'z-push.log');
define('LOGERRORFILE', LOGFILEDIR . 'z-push-error.log');
define('LOGLEVEL', LOGLEVEL_INFO);
-    define('LOGAUTHFAIL', false);
+    define('LOGAUTHFAIL', true);


// To save e.g. WBXML data only for selected users, add the usernames to the array
@@ -185,7 +185,7 @@
*  Backend settings
*/
// the backend data provider
-    define('BACKEND_PROVIDER', '');
+    define('BACKEND_PROVIDER', 'BackendIMAP');

/**********************************************************************************
*  Search provider settings

んで、imap側のconfig.phpもいじる。
--- /usr/local/share/z-push/backend/imap/config.php     (before)
+++ /usr/local/share/z-push/backend/imap/config.php     (after)
@@ -46,13 +46,13 @@
// ************************

// Defines the server to which we want to connect
-define('IMAP_SERVER', 'localhost');
+define('IMAP_SERVER', '127.0.0.1');
// connecting to default port (143)
-define('IMAP_PORT', 143);
+define('IMAP_PORT', 993);
// best cross-platform compatibility (see http://php.net/imap_open for options)
-define('IMAP_OPTIONS', '/notls/norsh');
+define('IMAP_OPTIONS', '/tls/norsh');

// overwrite the "from" header if it isn't set when sending emails
// options: 'username'    - the username will be set (usefull if your login is equal to your emailaddress)

で、iPhone側でExchangeアカウントをセット。
やってみるが"Connection Serfer Failed."などと言って一歩も動かない。
アカウント追加時の認証チェックは通っていたぽいので、パスワード周りは間違っていないはず。。。

しかし動かず。
とりあえず、いろんなところのデバッグフラグをONにしてみる。

--- /usr/local/share/z-push/config.php (before)
+++ /usr/local/share/z-push/config.php (after)
@@ -89,7 +89,7 @@
     define('LOGFILEDIR', '/var/log/z-push/');
     define('LOGFILE', LOGFILEDIR . 'z-push.log');
     define('LOGERRORFILE', LOGFILEDIR . 'z-push-error.log');
-    define('LOGLEVEL', LOGLEVEL_INFO);
+    define('LOGLEVEL', LOGLEVEL_DEBUG);
     define('LOGAUTHFAIL', true);

--- /usr/local/share/z-push/config.php  (before)
+++ /usr/local/share/z-push/config.php  (after)
@@ -52,7 +52,7 @@
 define('IMAP_PORT', 993);

 // best cross-platform compatibility (see http://php.net/imap_open for options)

-define('IMAP_OPTIONS', '/tls/norsh');
+define('IMAP_OPTIONS', '/tls/norsh/debug');

 // overwrite the "from" header if it isn't set when sending emails
 // options: 'username'    - the username will be set (usefull if your login is
equal to your emailaddress)

しかしまだ動かない。
webでアクセスしてみても、しばらく待ってから再度認証を求められ、その直前に下記のようなログが出る。
/usr/local/share/z-push-2.1.0-1750/backend/imap/imap.php:99 imap_open(): Couldn't open stream {127.0.0.1:993/imap/tls/norsh/debug} (2)

気づいた。オレオレ証明書じゃん。
というわけで、接続オプションを変更。
--- /usr/local/share/z-push/config.php  (before)
+++ /usr/local/share/z-push/config.php  (after)
@@ -52,7 +52,7 @@
 define('IMAP_PORT', 993);

 // best cross-platform compatibility (see http://php.net/imap_open for options)

-define('IMAP_OPTIONS', '/tls/norsh/debug');
+define('IMAP_OPTIONS', '/tls/norsh/novalidate-cert');

 // overwrite the "from" header if it isn't set when sending emails
 // options: 'username'    - the username will be set (usefull if your login is
equal to your emailaddress)
まだ動かない。
imap_open()でコケると言っているが、dovecotのログがぜんぜんにぎやかじゃない。どーゆーことだ???
ということは、認証かセッション確立でこけてると予想。
imap_open()を使って直接たたいてみる。

imap_open("{127.0.0.1/tls/norsh/novalidate-cert}INBOX", $username, $password);


しっかり60秒待ってからエラーが表示された。
うーん、セッション確立の影響だなぁ。

で、下記のように変えてみた。
--- /usr/local/share/z-push/config.php  (before)
+++ /usr/local/share/z-push/config.php  (after)
@@ -52,7 +52,7 @@
 define('IMAP_PORT', 993);

 // best cross-platform compatibility (see http://php.net/imap_open for options)

-define('IMAP_OPTIONS', '/tls/norsh/novalidate-cert');
+define('IMAP_OPTIONS', '/ssl/norsh/novalidate-cert');

 // overwrite the "from" header if it isn't set when sending emails
 // options: 'username'    - the username will be set (usefull if your login is equal to your emailaddress)

StartTLSによるSSL確立ではなく、最初からSSLで突っ込むようにしてみた。
お!動いた!!



というわけで、今回の反省。
いろんな環境を整理して調査にあたる必要がありますね。
  • imapのSSL状態。 どっちが直接の原因となるかは分からないけど、iPhoneでUse SSLを有効にしてるため、もしくはdovecot.confで「protocols=imaps」としているため、のいずれかもしくは両方の理由により、imap_open()のフラグに「/ssl」が必要。「/tls」ではだめ。
  • 証明書。 自前でやる場合はそんなにお金かけてられないので、往々にしてオレオレ証明書を利用することに。dovecotから見れば、z-pushは当然普通のクライアントなので、当然証明書はチェックされます。なので、人的介入無しに証明書エラーをくぐり抜ける必要があります。
  • ログはよく観察すること! いろんなログ(今回の場合はapache/dovecot/z-push)を見ましたが、特定のログだけを見ていても気づかないことが多いです。それぞれのコンポーネントがどのように連携しているのか?イベントが発生したタイミングで、どのログが流れてどのログが流れないのか?このあたりをちゃんと考慮してログを見ると、どこの部分でエラーが発生しているかのアタリがつけやすくなります。
というわけで、おしまいっ

2010/12/24

Thunderbirdがすごい。だけど.....

少し前にうちのメールをIMAP化し、昔使っていた別のメールクライアントのメールを取り込むべくインポートをやっていたわけなんですが、 Thunderbird、すごいですね。メールボックスをまたいでメッセージを移動できるし、移動元がPOPで移動先がIMAPだとアップロードまでしてくれます。これで、iPhoneからでも会社からでも自分の家でも全部同じメールが見られる~

と思っていたら、どうもメールの表示順序がおかしいのです。メールヘッダにあるタイムスタンプは確かに維持されているんだけど、表示順序が「Thunderbirdに取り込まれた順」になっている。昨日のメールよりも新しい位置にインポートしたメールがあるわけで、iPhoneで見るときに「最新の100通」を見るとインポートしたメールで埋まってる.....これでは使い物になりません。

で、調べてみると、IMAPサーバに保存されているメッセージのファイル名が「インポートしたときのUNIX秒」になっているっぽい.....これを直せばどうにかなるかな。

というわけで、こんなスクリプトを組みます。要は、各メッセージのファイル名に入っているUNIX秒を、Dateヘッダが示すUNIX秒に差し替えてリネームするわけです。


#!/bin/sh

cd ~
for dir in `find ~/Maildir -type d -name cur`; do
cd $dir
pwd
for file in `ls`; do
dater="`grep ^Date: $file | head -1 | sed -e 's/^Date://; s/ (JST)$//; s/Thr/Thu/'`"
dates=`date -d "$dater" +%s`
new=`echo $dates@$file | sed -e 's/@[1-9][0-9]*\././'`
echo -n "$file -> $new : "
if [ "$file" = "$new" ]; then
echo not renamed.
else
mv -i $file $new
echo renamed.
fi
done
done


コツをいくつか。
・Maildir形式での各メッセージは確実にユニークなファイル名を持つようになっているので、1ファイルずつ処理できます。ファイル名の命名規則については下記で解説されています。
http://cr.yp.to/proto/maildir.html
・head -1が入っているのは、マルチパートのメールとかだとDateヘッダが複数入っているので、一番最初のだけを持ってくる必要があるからです。他の言語を使えばオブジェクトで扱えるのですが、そこまでは要求していないのでこれで十分。
・ThrをThuに変えているのは、dateコマンドのフォーマットとして認識してくれないからです。メールソフトの中には、木曜日の短縮形をThuではなくThrで記述するものもあるみたいですね。

もちろんここにくるまでにちゃんとデバッグしてますよ。mvだけコメントアウトしておけば何度でもプレビューできるので便利です。ついでに、テスト実行時には標準出力「だけ」を捨てておくと、エラーの有無がわかりやすくて便利です。こういうとき、標準エラー出力って便利だな、と思います。

で、imapのサービスを止めて、いざ実行!

Thunderbirdを立ち上げてみると....お!うまくいってる!
しかしログにこんな記述が!
「△△△フォルダから0000通のメールを削除しました」....えええ!!!!

よく見ると、ローカルのメール(実質的なキャッシュ)をリモートフォルダ(つまりIMAP上のオリジナルメール)に合わせている挙動でした。リモートのメールが消されているものと勘違い(汗

改めてiPhoneから見てみたところ、期待したとおりに表示されているようです。

2010/06/10

smtp-authの認証バックエンドをdovecotにしてみる

postfixでsmtp-authを利用するのに、以前の知識ではsaslpasswdを使った認証方法しか知らなかったんですが、どうも認証バックエンドにdovecotが使えるようなので、それを試してみました。

というのも、パスワード管理をするのに、dovecotとsaslpasswdで別なのも気持ち悪いし、ましてやアカウント情報となると、これにさらにpostfixが加わるので、いちいち設定なんぞしていられない状況なわけです。
とりあえずpostfix側の設定(必要な部分)はこんな感じです。smtpd_sasl_typeでdovecotを選択し、smtpd_sasl_pathで問い合わせ先を(後で作る)dovecotのソケットに向けます。あと、 smtpd_recipient_restrictionsでちゃんと制限もちゃんとかけておかないと、儀式だけのsmtp-authになっちゃいますの でご注意(笑)。
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $mydomain

んで、dovecot.confの側はこんな感じ。ファイルソケットを作って待ち受けるのがミソですね。この環境では認証データベースをpasswdにし ているので、他の認証バックエンドを使いたい方は、適宜調整するといけるかもしれません。
auth default {
mechanisms = plain login
passdb shadow {
args = /etc/shadow
}
socket listen {
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}