PHPのimap_openでExchange Server 2007への接続に失敗する

必要があってPHPでMicrosoft Exchange Server 2007のサーバにIMAPの接続をするような設定を行っていたのだけれど、いくらやっても接続に失敗する。最終的にはうまくいったけれど、今後のためにもメモ。

まず失敗したときのPHPコードだけど、これ自体は簡単なもので、

$imap_stream = imap_open('{example.com:143/imap/notls}INBOX', 'user', 'password');
if ($imap_stream) {
    echo "ok\n";
    imap_close($imap_stream);
}
else {
    echo "fail\n";
}

みたいな感じ。これでたとえばphpコマンドから直接実行すると、エラーメッセージには見慣れない

PHP Notice:  Unknown: Kerberos error: Unknown code krb5 195 (try running kinit) for example.com (errflg=1) in Unknown on line 0

のような文字列が出る。一般的なメールソフトやtelnetによるプロトコルの直接操作でも問題ないことは確認済み。いったいなぜなんだと悩んでいたら、認証方式が問題だった。

相手のExchangeサーバにtelnetでつないで、

? CAPABILITY

と実行すると、

* CAPABILITY IMAP4 IMAP4rev1 AUTH=NTLM AUTH=GSSAPI AUTH=PLAIN IDLE NAMESPACE LITERAL+
? OK CAPABILITY completed.

というような結果が返ってくる。で、問題はAUTH=GSSAPIの部分。ExchangeサーバではActiveDirectoryとの連携による認証方式がサポートされている。その認証方式を表すのが、おそらくGSSAPIの部分。これがPHPのIMAPモジュールの認証方式と関係してくる。

PHPのIMAPモジュールでは、Kerberosが有効な状態でビルドされていると、GSS-API認証方式が有効になる。php_imap.cの関連部分のコードを抜き出してみると(バージョンは5.2.11)、

#ifndef PHP_WIN32
    auth_link(&auth_log);       /* link in the log authenticator */
    auth_link(&auth_md5);       /* link in the cram-md5 authenticator */
#if HAVE_IMAP_KRB && defined(HAVE_IMAP_AUTH_GSS)
    auth_link(&auth_gss);       /* link in the gss authenticator */
#endif
    auth_link(&auth_pla);       /* link in the plain authenticator */
#endif

のようになっている。PLAIN認証より先にGSS-API認証が来てる。さらに先ほどのExchangeサーバの応答では、LOGとCRAM-MD5での認証は使えない。とすると、PHPからはGSS-API認証を実行するようになり、その準備がきちんと行われていない場合、認証に失敗して接続ができない、ということになる。先ほどの得体のしれないエラーメッセージも、ActiveDirectoryでの認証に必要なKerberosの設定ができていないということを示していたみたいだ。

問題を解決するには、たとえばESAdminにあるような形でkerberosの設定とクライアントの認証を行って、チケットを取得しておく必要があるようだ。エラーメッセージのkinitはまさにチケット取得のためのコマンドである。調べてみたら、kinitはCentOS 5ではkrb5-workstationというパッケージに含まれていた。

でも、残念ながら今回は、自分で管理しているActiveDirectoryサーバじゃないので、Kerberosの設定に必要なRealmその他の情報が全くわからない。仕方がないのでPHPのIMAPモジュールを、Kerberosを外した状態で再コンパイルした。Kerberosを外して再コンパイルするには、CentOS 5の場合、IMAPモジュールが使うlibc-clientの設定が関係してくる。CentOS 5の標準のlibc-clientパッケージのように、もしこれがKerberosを有効な状態でコンパイルしてあると、PHPのconfigureがそれを検知して、configureのオプションにwith-kerberosをつけろと要求してくる。回避するためには、 /usr/include/imap/linkage.h の中の

extern AUTHENTICATOR auth_gss;

を削除しておかなければいけない。削除した上で、configureオプションにwithout-kerberosをつけてIMAPモジュールを作ればよい。こうしてできたIMAPモジュールをインストールしてから接続を試せば、さっきのサーバではPLAIN方式しか有効ではないので、それで認証を行ってきちんとログインできるようになる。

rpm, yum でエラーが出た

rpmを実行したら突然こんなエラーメッセージが表示されました

  rpmdb: PANIC: fatal region error detected; run recovery

どうやらコマンドは失敗した様だし、これ以降はrpmもyumも必ずこのメッセージが表示されるようになってしまいました

原因はrpmのデータベースファイルが破損しているためとのこと

データベースファイルは/var/lib/rpm/__db.00*なので、これらを別の場所に退避しておいて

$ rpm --rebuilddb

このコマンドを実行してあげるだけで解消できました

実際はこのコマンド実行しても大丈夫ですよね?って聞こうとしたらそのまま直してもらっちゃったんですけどね。。

SSL越しにtelnetっぽく操作してみたい!

telnetを使うと、HTTPやSMTP、POP3なんかのインターネット上の主要なプロトコルを直接手動で実行して操作することができるけど、SSL上ではtelnetは使えないので、例えばHTTPSやSMTP Over SSLなんかはそのままじゃ試せない。でも、たまにそれがやりたくなるときがあって、そういうときはOpenSSLが入っているなら

$ openssl s_client -connect server:port -quiet

というようにコマンド実行してやると簡単という話。server, portはそれぞれ接続先のサーバとポートを指定する。接続ができたら、後はいつものtelnetと同じ。-quietオプションをつけておくとよけいな出力を抑制できるので普段はこれつけてるけど、証明書の情報とかも全部見たければオプション使わなければOK。

Pleskで複数アカウントからのFTP接続

Pleskを使って、複数のアカウントからFTP接続でデータをアップロードしたい!
と思い、自分のPCにインストールしてあった無料版Pleskを使って実験してみました。

どうも、普通にFTPアカウントを作成していく項目はないようで、各ドメインごとに1つ
FTPアカウントを作成することになっていました。

Clients > クライアント名 > Add New Domain >

無料版ということもあり、Pleskで 1ドメインまでしか管理できない為、この方法では
複数のFTPアカウントを作成することができません。

そこで、サブドメインを使ってみることにしました。

Clients > クライアント名 > Domain名 > Subdomains > Add New Subdomain >

幸いなことに、無料版ではサブドメインの制限がないようで、目的の複数FTPアカウントを
作成することができました。

と、よく考えてみると、FTPアカウントだけ使いたいのに、サブドメインが作成されてしまう
ことになります。目的としては満たしているのですが、しっくりこないので別の方法を
探していると、Web Users という機能が見つかりました。

Web Users は、UNIXのアカウントとして管理されるユーザーで、この機能を使えば、
ドメイン内に複数のFTPアカウントが作成できることになります。

Clients > クライアント名 > Domain名 > Web Users > Add New Web User >

Web User を1アカウント作成してみたところ、Add New Web User のアイコンがグレーに。。。
無料版の Plesk では、Web User にも制限があったようです。

とりあえず、Web User の機能が目的にぴったりということで、実際に設定を予定して借りている
使えるねっとの共有サーバーを確認してみました。
やはり、無料版のPleskとは違い、Web User も複数作成できるようでした。^_^
それぞれの Web User アカウントを作成し、データをアップロードすることができました。
Web Userのアップロード先は、通常公開用として使用されている httpdocs などとは違い、
web users フォルダ内に個々の Web Userごとのフォルダ内にアップロードされるため、
ドメインで作成しているホームページに Web user のアカウントのアップロードデータが
混じる心配もなく、安心して使えそうです。

一般ユーザーでRPM Build

以前mecabのRPMを作ったとき、そういえばrootではなくて一般ユーザーでRPMを作ったなあと今更ながら思い出したので、やり方をメモしておくことにした。

RPMの作成は、rootでやるときは、rpm-buildのRPMパッケージが入っていればそのまま作業するだけだけど、root権限があるが故に、ヘタするとまずいファイルを消してしまったり、上書きしてしまったりする恐れがあるので、できれば一般ユーザーでビルドするのが好ましい。でも一般ユーザーの場合、rootで使える /usr/src/redhat 以下のディレクトリへのアクセス権限がないため、ちょっとばかり準備が必要だ。今回は今使用中の使えるねっとのVPSでやってみた方法で書いてみる。

まずはユーザー作成、というところだけど、このVPSではドメインをPleskで作ったときにシステムアカウントが同時に作られる、かつ、それにシェルを割り当てられるようなので、それをそのまま使うことにした。Pleskのドメインの設定のシステムアクセスのところで /bin/bash を選ぶだけ。アカウント・パスワードはFTPと同じになるっぽい。試しにSSHで接続したら問題ないようだ。ってことはSFTPも使えるということか。って、あれ?SFTPってアカウントにシェルなくても使えなかったっけか?今度設定変えて試してみよう。FTPじゃなくてSFTPが普通に使えるならその方がいいし。

ちょっと脱線したけど、とりあえずユーザーについてはこれでよしとして、次にRPM作成環境を準備する。さっき作ったアカウントでログインした先では、ウェブに公開する領域外のディレクトリとして private があるようなので、ここに作ることにする。ここに以下のようにディレクトリを作ってみた。

private/
  rpms/
    BUILD/
    RPMS/
    SOURCES/
    SPECS/
    SRPMS/

rpms を作ってから、その下に BUILD とかのディレクトリを作っただけ。階層構造としては、これでOK。

残りはさっき作ったディレクトリ群をRPM作成時に使うように指定するだけなんだけど、そのためにはアカウントのホームディレクトリに .rpmmacros を作らなければいけない。が、さっそく作ろうと思ったら、パーミッションがないということではじかれる。そこでホームディレクトリ自体の権限見たら、なんとrootにしか書き込み権限がない。こりゃまいった。どうしようかと考えて面倒になったので、そこだけrootで作ることにした。いったん作ってしまえば、変えることもあまりないだろうし。ということで以下のような内容の .rpmmacros ファイルを、rootでホームディレクトリに作成。

%_topdir /var/www/vhosts/saba-kan.net/private/rpms

%_topdir という変数に、さっき作ったディレクトリ群のトップのパスを指定するだけ。これで準備完了。このユーザーで好き放題RPMを作ったり再作成できるようになった。もちろん、できたRPMをインストールするときはroot権限が必要だけど。

Plesk特有のアカウントを使わないのであれば、単にビルド用のユーザーをuseraddコマンドで作って、できたホームディレクトリ以下に同じことすればOK。

Older entries >>

start.txt · 最終更新: 2009/09/03 18:13 by mizuni
CC Attribution-Noncommercial-Share Alike 3.0 Unported www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0