自宅サーバのeximから,iPhoneにpush通知はできるのか.できた! exim+dovecot+z-push

結論から言うと,MDA(Mail Delivery Agent)に気をつければ,MTA(Mail Transfer Agent)はどうでも良いようです.
今まではeximで伝統的なmbox形式で一ユーザ一ファイルでメールコンテンツを管理していて,読み出しは伝統的popプロトコル
poppa3dで動かしていたので,それとの互換性は保ちたいと思いました.
dovecotはmbox形式をサポートしているので,eximのmbox形式をdovecotimapで読み出すことには問題が無さそうでした.
しかし,imapの設定をしても,iPhoneで通知されない!
imapプロトコルにも詳しくないし,iPhoneの動作も知らないし,z-pushに挑戦してみました.

Z-Push | Open source push technology


まずメールサーバ側の設定.
imapサーバはdovecotが入っているとします.
Dovecot
pop3 to imap - なぜか数学者にはワイン好きが多い
dovecot.confには,特に特別な設定はしていません.

MTAとしてはeximが入っているとします.
こちらは迷惑メール防止に長年に渡るカスタマイズが入っているのですが,書ききれないので内容は省略します.
Exim Internet Mailer
exim+SpamAssassinでspam撃退かつTLS認証対応 - なぜか数学者にはワイン好きが多い

そしてz-pushはphpのプロダクトなので,Webサーバの設定を触ります.
nginx何かを試したかったのですが,時間が無かったので慣れに慣れきったapacheで行きました.

SSLの証明書ファイル,秘密鍵ファイルは,FreeBSDがデフォルトで自動的に/etc/ssl/以下に作るものを買ってに流用します.
なので,httpd-ssl.confの2箇所を書き換えます.

#SSLCertificateFile "/usr/local/etc/apache22/server.crt"
SSLCertificateFile /etc/ssl/ca-certificate.pem
#SSLCertificateKeyFile "/usr/local/etc/apache22/server.key"
SSLCertificateKeyFile /etc/ssl/ca-privatekey.pem

それを反映させるため,http.confはhttpd-ssl.confを取り込むように変更.

#Include etc/apache22/extra/httpd-ssl.conf
Include etc/apache22/extra/httpd-ssl.conf

他にもhttpd.confは,phpを普通に認識させる設定や,Microsoft Exchangeだと思ってアクセスに来たものをz-pushに飛ばすような設定を入れます.

LoadModule php5_module libexec/apache22/libphp5.so

Alias /Microsoft-Server-ActiveSync /usr/share/z-push/index.php

AddType application/x-httpd-php .php .phtml


AllowOverride None
Options None
Order allow,deny
Allow from all

z-pushは,Zarafaじゃなくてimapを見に行くようにします.config.phpの修正.

// The data providers that we are using (see configuration below)
// define('BACKEND_PROVIDER', "BackendZarafa");
define('BACKEND_PROVIDER', "BackendIMAP");

iPhone側の設定は,「ホーム」→「設定」→「メール/連絡先/カレンダー」→「アカウントを追加...」で,

メール:<使うメールアドレス>
サーバ: ←サーバ名だけで構いません.アクセスする「サーバ名://Microsoft-Server-ActiveSync」というのは,サーバの設定でExchangeを選んだ時点で自動的に補完されるようになります.後述のapacheログ参照
ドメイン:カラでも良い
ユーザ名:
パスワード:
SSLを使用:オン

これくらいまで設定して,ブラウザから

https://www.example.com/Microsoft-Server-ActiveSync

にアクセスすると,ユーザ名とパスワードを聞いてくるので,IMAPのものを入れると,次のように
アクセスできたけどエラーだよ,と出ます.

その時,z-pushのログには

05/04/2013 23:13:10 [99949] [INFO] [<ユーザ名>] Version='2.0.7-1690' method='GET' from='192.168.0.99' cmd='' getUser='<ユーザ名>' devId='' devType=''
05/04/2013 23:13:10 [99949] [INFO] [<ユーザ名>] User-agent: 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)'
05/04/2013 23:13:10 [99949] [WARN] [<ユーザ名>] Unknown:0 Unknown: SECURITY PROBLEM: insecure server advertised AUTH=PLAIN (errflg=1) (8)

apacheのログには

192.168.0.99 - <ユーザ名> [05/Apr/2013:23:13:10 +0900] "GET /Microsoft-Server-ActiveSync HTTP/1.1" 200 948 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)"

と出ます.

iPhoneからメールを読み込むと,z-pushのログには

05/04/2013 23:18:07 [99951] [INFO] [<ユーザ名>] Version='2.0.7-1690' method='POST' from='192.168.0.99' cmd='Ping' getUser='<ユーザ名>' devId='ApplF17K2N10DTWH' devType='iPhone'
05/04/2013 23:18:08 [99949] [INFO] [<ユーザ名>] Version='2.0.7-1690' method='POST' from='192.168.0.99' cmd='Sync' getUser='<ユーザ名>' devId='ApplF17K2N10DTWH' devType='iPhone'

pingやsyncのコマンドが飛んだり,apacheのログには同じくz-pushに送るpingやsyncのコマンドが出ています.

192.168.0.99 - <ユーザ名> [05/Apr/2013:23:18:07 +0900] "POST /Microsoft-Server-ActiveSync?User=<ユーザ名>&DeviceId=ApplF17K2N10DTWH&DeviceType=iPhone&Cmd=Ping HTTP/1.1" 200 27
192.168.0.99 - <ユーザ名> [05/Apr/2013:23:18:08 +0900] "POST /Microsoft-Server-ActiveSync?User=<ユーザ名>&DeviceId=ApplF17K2N10DTWH&DeviceType=iPhone&Cmd=Sync HTTP/1.1" 200 70

push通知はされるし,バッジも出るし,頑張れば予定表やToDOも出来るようになるのでしょう.