技術・開発

openLDAPのPerl Backendをいじってハマった話

話の発端としてはtagomorisさんのページを見た某社の方より、こんな感じのものを作って欲しいんだがというご相談を頂きまして着手しましたところ、非常にドハマりしましたので後に続くかもしれない方々にメモメモ。

オンラインドキュメントも相変わらず”LATER”のままです。どこかに更新されたドキュメントがあるんじゃないかと期待して探し回ってみましたがダメな感じです。もう忘れ去られた感がアリアリしております。何かしらの参考資料を探してみても、これと言って見当たらず、”LISM”というPerl Backendを利用したOSSの統合認証のソフトウェアがあり、良くぞ作ったなあという感もありまして参考にさせてもらいました。ただAdminツールにディスコン気味のEthnaが必要とかで、このままではインストールも困難だったりする。

openLDAP関連の書籍も、すでに書店では事実上2冊しかない。入門LDAP/OpenLDAP―ディレクトリサービス導入・運用ガイドLDAP -設定・管理・プログラミング-だ。前者はまだ何とか使えるものの、後者は発行が2003年だ。また、どちらもopenLDAPそのもののインストール、設定がメインで、バックエンドの作成にはちっとも触れられていない。洋書も何冊かチェックしてみたが、これといって参考になりそうなものもなく。

「man 5 slapd-perl すると、ちょっと詳しく書いてある。興味がある人は読んでみよう、というか、読まないと何もできない。またOpenLDAPの tarball を展開した中の servers/slapd/back-perl/SampleLDAP.pm がサンプルなので、読んでみるとなんとなく雰囲気がわかる。(雰囲気しかわからない。)」の状況からは一歩も進んでいない状況です。

とにかく試して、動きを見るのが一番という事で、SampleLDAP.pm を動かしてみることに。

ソースからビルドする場合には –enable-perl をつければOK。ディストリビューションの配布パッケージによっては、これが有効になっていたり、なっていなかったりするので、お使いの環境のパッケージを調べてみてください。(ちょっと脱線するが、id2entry.dbが無いというバグに私もハマった。お気を付けください。あとディストリビューションによっては、make dependしたときにPerlのモジュール不足で止まる事があります。結構、心が折れそうになりますがガンバ!)

で、slapd.conf には、次のように書く。

############## perl backend #############
database        perl
suffix          "dc=example,dc=com"
rootdn          "cn=Manager,dc=example,dc=com"
rootpw          xxxxxxx
perlModulePath  /path/to/handler/module/dir
perlModule      SampleLDAP

この場合、 /path/to/handler/module/dir に SampleLDAP.pm ファイルをコピーする。後は普通のopenLDAPの操作と同じで ldapaddでLDIF情報追加し、ldapsearchで検索する事が出来る。おそらくはここまでは問題なく進むと思うのだが、時々slapdが落ちる現象が確認される。ldapsearchを叩いていると時々反応が無くなる瞬間があるのだが、slapdのプロセスを見ると見事に落ちている。

いろいろ調べてみた結果、SampleLDAP.pmにはbind()の記述が無く、slapdがこのリクエストを受けると落ちるという事が分かる。取りあえず、SampleLDAP.pm の一番最後にでも次のようにダミーでもbind()を入れておくと落ちなくなることが分かる。

bind(){
     return 0;
}

SampleLDAP.pm の動きについてはコードを見てもらえればわかるが、持っている情報をどっと吐き出す感じの動きになっている。ただ、検索のフィルター条件にちょっと込み入った文字列を指定してもslapdが落ちたりするので、結構シビア。うーん・・・
(この後もコードをいじっていると、「なぜこれで?!」といった、結構、理不尽に落ちることが多かったので、こまめに動作チェックをされることをお勧め。謎のプロセス停止が頻発する場合には、configureする際に –with-threads=no をつけると安定するかもしれない。)

私の場合には、後続のデータソースから認証情報を引っ張ってきて、これを使って認証させるわけです。スキーマーがposixAccount位なら、LDIFに入れるべき情報を全部データソースの中に突っ込んで、リクエストがあるたびにそれを参照して応答を作るか、パフォーマンスの問題が出てきそうならキャッシュの仕組みを作るとかで対応できると思う。search(), bind()のなかで認証情報を確認して、それぞれLDIF形式で応答内容を作ればOK。

全体にわたって、Perl-backendだからといって、何か便利ライブラリとかあるわけでもなく、ほとんど素でslapdからデータが引き渡されるので各LDAPコマンドごとに処理ロジックを実装していく必要があります。特に面倒なのはsearch()のFilterStringの部分の処理で、あの癖のある形式での条件指定をひも解かないといけないのですが、これといったツールもなく面倒です。slapdからの応答を作成するのに関しては Net::LDAP::LDIFが役に立つでしょう。きっと。

(さらにsambaをサポートしようとすると、Perl-Backendだけで解決しようとすると、かなりヒイヒイいう事になります。私は諸般の事情で諦めざるを得ず、裏にPerl-Backendではないslapdを併用してリクエスト/応答をPerl-Backendで中継する方法を取りました。)

認証というと最近はActiveDirectoryの方が断然利用されていて、openLDAPも影が薄くなりつつありますが、何かの事情で使う事があればご参考になればいいなと。

canvas fingerprintingなどによる訪問者追跡の技術

最近、Canvas Fingerprintingに言及している記事をよく見かけるようになりました。例えば、”クッキーより怖いcanvas fingerprintingって何?迂回方法は?“(Gizmode)。これは一言でいえば、ブラウザを識別・特定するために利用される、既存のCookieに代わるブラウザ識別情報の保存の仕方なわけです。「怖い」かといえば、追跡を望まない場合にCookieをブロックする方法では防ぐ事が出来ないという意味では「怖い」ですが、ブラウザを通じて個人情報が抜き取られるわけではなく、その意味においてはCookieと同レベルの安全度ではないかと思います。(この辺り、もし誤解あれば教えてください。)

この手の技術については、Webサイトの訪問者を追いかける側から見れば、AppleのSafariブラウザが「サード・パーティー・クッキー」の受け入れを拒否する設定をデフォルトにした辺りからニーズが高まった印象があります。特にMac Book/Mac Book Airの人気が高まり、サイト訪問者に占めるMacユーザーの割合が増えてくる一方で、「サード・パーティー・クッキー」を利用した計測を利用するサイトにしてみれば、ページビュー数などは数えられるものの、再訪問が識別できないので、訪問者数の精度が落ちるというわけです。さらに言えば、ネット広告技術の向上が著しい時期でもあり、リターゲティング広告やリアルタイムビッティング(RTB)など、サイト間での訪問者識別情報の共有が必須になってきています。

そこで「サード・パーティー・クッキー」に依存しない計測方法が模索され、ブラウザで利用できる保存領域やサーバー側で設定できる通信上の任意に設定できるデータ領域が対象になり、その一つとしてHTML5のCanvas API機能が着目されました。このような領域はCanvas以外にも存在し、例えばほぼデフォルトで導入されているFlashプラグインを利用して、「Flash Cookie」のようなものを作ればCookie以上にデータを保存できる仕組みが実装できるわけです。

このような技術を集めたものが2010年にSamy Kamkar氏が発表した「Ever Cookie」と呼ばれる技術です。利用できそうな記憶領域にブラウザ識別のIDを埋め込み、ブロックされたとしても、どれか1つでも残っていればデータを復旧できるという代物です。FlashやSilverlightの記憶領域を利用して情報を共有し、同一PCでブラウザを変えても、同じ訪問者と識別出来たりするというものです。他にもブラウザの各種の属性情報のパターンを見て特定する技術などがあるようです。

訪問者側でも「DoNotTrack」ヘッダーを利用した追跡可否の意思表示が出来るようになるなど、ポリシーや法規制などの側面があり、サイト側からの追跡を牽制できる一方で、計測技術的な観点でいえば、まだまだやれる事が多いこともあります。

なお、Canvas Fingerprinting技術を使って追跡を行っていると名前が挙がる「AddThis」という、ソーシャルメディアでの共有ボタンのガジェットを提供するガジェットがありますが、この動きをブロックするために、Adblock PlusDoNotTrackMeが対応しているようです。ただCanvas APIへのアクセスをブロックするものではないため、Canvas Fingerprintingそのものをブロックするのは困難ではないでしょうか。

追跡を極力避けるとすればJavaScriptや各種プラグインをOFF設定にし、ブラウザのシークレット・ウィンドウ・モードの利用などで、それなりにブロック出来ますが、いまどきのサイトの閲覧には非常に不便を強いられるのではと思います。

※どの程度の識別ができるのかは、HTML5 Canvas Fingerprinting あたりのサイトを見てみれば面白いのではないかと。

※上級者はTorなどを使った匿名化などにチャレンジするのだと思いますが、こんな記事もあったりしますので、こちらもイタチごっこなのではないかと。

 

 

複数PCの操作で”Mouse without Borders”が便利すぎる。

作業のためにノートPCを2台並べて使っているのですが、いちいち、キーボードを入れ替えたり、マウスを持ち帰るのは大変に面倒なのです。キーボードに関してはBluetooshキーボードで複数のPCの切り替えができるものもありまして、一時期、そのようなモデルを利用していたのですが、マウスはどうにもならない。USBの抜き差しやBluetoothでのつなぎ直しが面倒なので、色の違う同じモデルの2つのマウスを並べて、都度持ち替えていたのですが、これはこれでスペースを取るわけです。

そんな状況の私を救ってくれたのは、Microsoftの“Mouse without Borders”でした。(ちなみに自分はWindowsをメインに利用してます。)技術的にはネットワーク経由でマウスの動作を伝え合うというものですが、マルチディスプレイの場合と同様に画面の端から動かすと、隣のマシンにマウスカーソルが動く!さらには、クリップボードが共有されていますので、あるPCでコピーした文字列をクリップボード経由で、別のPCにペーストすることもできます!また、ファイルをつかんでドラッグ&ドロップするとPC間でファイルをコピーする事ができます!

というわけで、複数のマシンをさながらマルチディスプレイでPCを使う場合のように、1つのキーボード&マウスで操作できるわけです。これは便利!
Microsoft Garage Mouse without Borders
http://www.microsoft.com/en-us/download/details.aspx?id=35460

表示は英語ですが、インストールは比較的容易です。詳しい説明は以下のページに詳しいです。

マウス / キーボード を、複数のパソコン間で共有する!「Mouse without Borders」
http://www.gigafree.net/internet/remote/mousewithoutborders.html

FirefoxとGoogle Chromeのブックマークを同期する方法

作業の際には、それぞれ一長一短あるため、FirefoxとGoogle Chromeの両方を使っています。そこでWebサイトを見ていて気になるページをブックマークしていくと、それぞれのブラウザでブックマークがどんどん差が出てきます。

FirefoxもChromeも独自の同期の仕組みがあって、それさえ設定しておけば複数のPC間やスマートフォンとの間でブックマークの同期をしてくれます。これはこれで非常に便利なのですが、Firefoxで作業しているときにブックマークしたサイトを見ようとして、見つからないとChromeを立ち上げて、改めてブックマークリストをチェックするという、非常に面倒な作業が発生します。

そこで勝手に裏で同期をしてくれるサービスとして、以前はfoxmarkというサービスを使っていたことを思い出し、改めて調べてみましたが、それが名前を”Xmarks”に変え、さらにはLastPassというパスワード管理会社に買収されるという経緯がありますが、サービスは継続していました。

https://www.xmarks.com/

細かい段取りはサイトをご覧いただければ分かると思いますが、まず最初に自分のアカウントを作成する必要があります。その後、各ブラウザにプラグインをインストールしていきます。

その後、各ブラウザにて認証と同期の設定を行っていくわけです。その際に注意が必要なのは、サーバー上にあるブックマークの記録と、設定操作をしているブラウザとの関係ですが、初回は単純にローカルのブックマークをアップロードするだけですが、2つ目のブラウザ以降は①ローカルを消してサーバーからダウンロードする②サーバー上のブックマークを削除してアップロードする。③サーバー上の記録と差分を取る。のいずれかから選択するわけです。①②であれば問題ないわけですが③の処理を選ぶと、大量にブックマークがあると、結構、ぐちゃぐちゃになります。これも徐々に整理していけば良いといえば良いのですが、数が多いと大変面倒な作業となります。

このあたりはやってみないと分からない所でもありますので、事前にブックマークをexportしてバックアップを取っておき、いざという時に戻せる準備をしておいた方が良いです。

私の場合には面倒になってしまったので、Chrome側でどうしても取っておきたいブックマークをFirefox側に手動で移した後、初回設定はFirefox側をアップロード&Chrome側をダウンロードすることで同期を始めました・・・

最初のブックマークが多い場合には、整理がちょっと面倒ですが、一度設定してしまえば、後は気にすることも無くなるのでお勧めです。

MariaDBのConnectストレージエンジン

MariaDBの最新バージョン10.0系では、多岐に渡るストレージエンジンをサポートしていますが、その中でもユニークなConnectストレージエンジンを紹介します。

動作概要

アプリケーションは従来のDBと同様にMariaDBにアクセスします。MariaDBはあらかじめ定義された設定に従って、外部のDBまたはファイルにアクセスしてデータ操作を行い、結果をアプリケーションに応答します。

 

 テーブル定義の例

MS-AccessにODBC接続して”Customer”テーブルを作成する場合
create table Customer (
  CustomerIDvarchar(5),
  CompanyNamevarchar(40),
  ContactNamevarchar(30),
  ContactTitlevarchar(30),
  Address varchar(60),
  City varchar(15),
  Region varchar(15),
  PostalCodevarchar(10),
  Country varchar(15),
  Phone varchar(24),
  Fax varchar(24))
engine=connect table_type=ODBC block_size=10 tabname='Customers'
Connection=‘DSN=MS Access Database;DBQ=C:/Program Files/Microsoft Office/Office/1033/FPNWIND.MDB;';

ODBCのカタログ関数を利用して、リモートDBのテーブル定義を参照する場合

create table Customer engine=connect table_type=ODBC  block_size=10 tabname='Customers'
 connection='DSN=MS Access Database;DBQ=C:/Program Files/Microsoft Office/Office/1033/FPNWIND.MDB;';
CSVファイルを参照する場合
create table people (
  name char(12) not null,
  birth date not null date_format='DD/MM/YY',
  children smallint(2) not null)
engine=CONNECT table_type=CSV file_name='people.csv'
header=1 sep_char=';' quoted=1;

例えば上記の場合では、”people.csv”は

Name;birth;children
 “Mike";17/05/01;3
 “John";12/08/03;2

この場合、select * from people; のように、SQL文を使ってCSVファイルを参照することが出来ます。

また、以下のようにinsert文でデータを追加することも可能です。

insert into people (name,birth,children) values('John','31/03/2013',1);

次のように通常のテーブル”address”とのJOIN処理も可能。

select * from people, address where address.name=people.name;

このようにMariaDBの内部に格納されているデータ、ならびに外部のデータも含めて、統合的に利用できるというユニークな機能です。ETLツールなどによるデータの連携処理などを待たずにリアルタイムで参照できるという点も強みと思います。

さらに詳細について知りたい型はMariaDBのKnowledge Baseに詳しいですのでご参照ください。

MariaDBの安定版 Ver. 10.0がリリース

以前にシステム導入の際に、データソースが多岐に渡るケースがあり、どうやってつなげようかと考えていた際に、MySQLのFederated Storage Engineを使おうかと検討していたのですが、開発も事実上止まっていた事もあり、それよりはMariaDBのConnect Storage Engineの方が良いかもと調べていたことがありました。結局は当時、β版だったこともあり採用には至りませんでしたが、先月3/31についにGA版がリリースされています。

 そもそもMariaDBって

MariaDBはMySQLからのforkプロジェクトとしてスタートしたDB。MySQLが米Oracleに買収されたことを契機に、オリジナル開発者のMichael “Monty” Widenius氏らが中心となり、2009年に開発プロジェクトを立ち上げました。現在は非営利団体のThe MariaDB Foundationの下で開発が進んでいます。また、Redhat, Fedora, openSUSE, Slackwareなど多くのLinuxディストリビューションでMariaDBの採用が進んでいます。

2つの系統

MariaDBには5.5系と10系の2つのバージョンが存在します。もともとMySQLと互換を目指して構築されており、MariaDB 5.5はMySQL5.5を元に独自機能の追加や安定性確保のための多くの改善が取り入れられているバージョンです。設定ファイルの書式なども含めて、利用者側からみた機能の違いは軽微で、ほぼ互換性を有しています。さらにMyISAMやInnoDBなどのMySQL標準のストレージエンジンに加え、XtraDB, Ariaなどのストレージエンジンも利用可能になっています。

MySQL 5.6では大規模なリファクタリングが行われました。このためRHELとCentOSのような関係性ではないですが、MySQLをベースにしてMariaDB独自の改良を継続することは難しくなったため、5.5をベースにして、5.6から新機能の選択的な追加、ならびにMariaDB独自の機能追加を行う方針となり、バージョン番号も一気に10.0まで引き上げられました。

MariaDBでは、MySQLと比較して、クエリー・オプティマイザーの性能が向上、サポートするストレージエンジンの追加、Information schemaからユーザーや表、索引の統計情報が参照可能になるなどのメリットがあります。またSQLレベルでは、REGEXPがマルチバイト対応になった違いはありますが、ほぼ互換。通信はMySQL, MariaDBともに同じ通信プロトコルなので、従来のMySQLのドライバーをそのまま利用してMariaDBと接続できます。このため、MySQL→MariaDBへの移行はきわめてスムーズに行えると思います。

MariaDB 10の新機能

MySQLとの互換性が重視されている5.5系と異なり、MariaDB 10では積極的に新機能の導入が進められています。レプリケーション、NoSQL、シェーディングなどの機能が強化されました。レプリケーションでは、スレーブ上にある複数のクエリを並列実行できる並列レプリケーションや、スレーブが複数のマスタを持つことが出来るマルチソースレプリケーションが導入されています。これにより分散したデータに対しての包括的なビューを作ることが出来ます。

ユニークな機能としては、外部にあるデータに動的にアクセスするためのCONNECTストレージエンジンが導入されています。かつてFederatedストレージエンジンと呼ばれていたものの後継にあたるわけですが、ログファイルなどの非構造データやCSVやXMLファイル、ODBCデータベースなどにアクセスでき、MariaDBを通じて間接的に各データソースを参照できます。従来はETL等を導入する必要がありましたが、データが混在する環境でのデータ分析には便利な機能でしょう。

Twilio Smart Communication Award 2014で最優秀賞!

“Twilio”というサービスをご存知でしょうか?APIを通じて電話・SMSをかけたり(送ったり)電話を受けて、それを元に何らかの処理を行うためのサービスです。日本ではKDDI Webコミュニケーションズ社がサービスを提供されています。

“API”というところがミソでして、アプリケーションからメッセージングの手段として、簡単に電話が利用できるわけです。これまで、アプリケーションからの通知の手段としては、主にテキストメッセージとしての電子メールが主流だと思います。たとえば、機械の故障などが起こって通知を行う場合には、あて先に通知メールを送るというのが、よくある実装ですが、その代わりに電話をかけることも出来ます。さらには「サービス業者に連絡する場合、1を押してください」というような案内をして、業者に電話をつなぎ直すといった芸当も可能です。多くの人がスマートフォンを持つようになり、電子メールやLINEといったテキストメッセージによるコミュニケーションが主流のご時勢で、「いまどき電話?」という声も無くもないのですが、即時性・緊急性を要する場合や、機器操作に不慣れなお年寄りなど、まだまだ音声での通話というものにもニーズがあるように見受けられますので、非常にユニークなサービスだと思います。

4/5,6にTwilioを利用したサービスを開発する「ハッカソン」というイベントが行われました。書類審査を通った20チームが時間内にサービスを実装するというコンペでした。”実践クラウド”社のチームの助っ人として参加したところ、まさかの決勝進出。

そして、4/9に“Twilio Japan Summit+Smart Communication Award 2014”が開催されまして、3チームのプレゼンが行われました。プレゼンの途中でWiFiが切れてアプリが動かなくなったり、通知のSMSが想定より大幅に遅れて届くなど、ハプニング続出でしたが、まさかの最優秀賞を頂くという、これまた意外な展開でした。(合わせてSkyland Venture様の企業賞も頂きました。)

Twilio自体は良く出来たAPIだなあと、つくづく思いました。何らかのプログラミング言語の知識は必要ではありますが、当日まで知識が無かったところから始めて、数時間触っている程度のレベルで自動音声応答のサービスや、通知メッセージを電話で伝えるサービスなどは作れてしまいます。以前に同様のサービスの実装をした事がありましたが、電話会社の方からサービス仕様を調整して、多くのパターンの応答音声を予め録音し・・・のような作業が必要で、開発にかなりの時間を要しましたが、同じレベルのものが数時間で出来てしまうことを考えると驚きです。

日本でのサービスでの難点は、応答音声がメカメカしいというか、まだ不自然な感じでした。これは今後の改善に期待するとして、今回はハッカソンでは、このイベントのために提供頂いたエーアイ社の“AITalk”を利用しました。こちらも指定のAPIに読み上げさせたいテキストを送ると、音声ファイルが返ってくるというものです。この音声ファイルをTwilioに送って通話で応答させるという実装にしました。若干ぎこちない所もありますが、機械的な合成音声にしては自然に聞こえる優れものです。(こちらは、決勝デモの際に披露する時間が無かったのが残念です。)

お誘い頂いた実践クラウドの久光社長に改めて御礼を申し上げるとともに、一緒に作業したチームメンバーや、関係者の皆様に改めて感謝したいと思います。
また電話を利用したサービスをご検討されている方につきましては、ご相談頂ければと思います。