Category Archives: Security

FileMaker Server 16のREST APIをmacOS上で試用する場合

FileMaker Server 16をまずは手元のMacにインストールして使ってみようという方も多いだろう。ここで、FileMaker Data API(REST API)を使用する場合にPHPのcurlライブラリを使うと、「SSL: CA certificate set, but certificate verification is disabled」というエラーメッセージが返ってくる。httpsでの通信が推奨され、証明書が検証できないと通信をしないということが当然となって来ているが、とはいえ、試用なので自己署名証明書で運用できないかとPHPの様々なパラメータを触ってみたところで、上記のエラーないしは別のエラーが出る。ということで、色々調べてみると、macOSに入っているopensslのバグで、サーバー検証をしないという設定ができないということらしい。homebrewから入れ直す方法など、色々紹介されているが、何をとっても大事になってしまう。

というところで、早速、FileMakerホスティングで有名なエミックの松尾さんが、ルータとなるスクリプトを公開された(一部、修正したい箇所があったので、筆者がフォークしたものもある)。FileMaker ServerのREST APIは、httpで接続してもhttpsにリダイレクトされるが、その背後のNode.jsが開いている3000ポートを目指して接続することで、httpでも処理が進められる。ただ、ヘッダをうまく使って同じホストからの接続しかできないような仕掛けがあるため、「直接3000番ポートに接続する」よりも、ルータスクリプトを使う方が楽である。

ルータは、WebアプリケーションとFileMaker Serverの中間に位置しており、WebアプリケーションがFileMaker ServerへのRESTコールを行う代わりに、ルーターに対して呼び出しを行う。ルーターはhttpsを使わずにFileMaker Serverを呼び出し結果を得て、それをWebアプリケーションに返す。動作としては「プロキシ」であるが、名前がrouterなので、ルーターと呼ぶことにする。

ルーターを利用できるようにするには、ダウンロードしたファイルrouter.phpを、以下のようなコマンドで起動する。ファイルがある場所をカレントディレクトリにして、コマンドを入力する。

php -S 127.0.0.1:8090 router.php

ここで、127.0.0.1は自分自身に接続するIPアドレスであり、コロンに続いてサーバーが利用するポート番号を指定する。他のプロセスが使っていない番号を使う必要がある。なお、使用を止めたい場合は、Terminalの画面でcontrol+Cキーを押す。

筆者が作ったAPIを利用するためのクラスFMDataAPIでルーターを利用したい場合、利用方法のサンプルを示したFMDataAPI_Sample.phpであれば、最初の方にあるインスタンス化している部分を記載のように修正する。パラメータを2つ追加して、8090ポートを使うことと、httpプロトコルを使うように設定すれば良い。他は変更が必要ない。もちろん、8090はルーターを起動する時に指定したポート番号を使う。IPアドレスも、基本的に起動時に設定したものを指定する。

修正前:
$fmdb = new FMDataAPI("TestDB", "web", "password", "127.0.0.1");

修正後:
$fmdb = new FMDataAPI("TestDB", "web", "password", "127.0.0.1", 8090, "http");

一方、FMDataAPITrialにあるスクリプトは、まず、lib.phpファイルにある以下の関数の返り値に、ルータ側のポート番号を指定する。

function targetHost()
{
    return "127.0.0.1:8090";
}

そして、Test2.php以降、プログラムの中のhttpsの記述をhttpに切り替える。callAPI関数の最初の引数が全てhttpsになっているので、httpに書き換える。

$host = targetHost();
$result = callAPI(
    "http://{$host}/fmi/rest/api/auth/TestDB",
    null,
    json_encode(array(
        "user" => "web",
        "password" => "password",
        "layout" => "person_layout",
    )),
    "POST");
resultOutput($result);

なお、phpコマンドで、router.phpを起動する時、127.0.0.1ではなく、localhostで指定した場合、上記の修正箇所のIPアドレスは、全てlocalhostで記述する。127.0.0.1では稼働しないので注意する必要がある。phpコマンドで起動する時に127.0.0.1を指定すると、Webアプリケーション側の設定は、127.0.0.1でもlocalhostでもどちらでも良いようだ。FileMaker Serverはかなり以前からIPv6ベースで動いているのだが、localhostとした場合、どこかで127.0.0.1ではないIPv6のアドレスとして識別しているのではないかと想像できるのだが、詳細は分からない。

ちなみに、FMDataAPIを使ったシステムを運用する時、原則としては正しい証明書でhttpsで運用することが原則だ。もちろん、盗聴されないためというのが大きな理由であるが、ホストを偽ってデータを収集されたり嘘の情報を流されることも防ぐ必要がある。httpsでの運用は、Let’s Encryptで無償で利用できるなど、年々手軽になってきているので、面倒がらずに対応すべきだというのが1つの結論である。

では、PHPを稼働させるWebサーバーとFileMaker Serverが同一のホストであれば、盗聴の心配はないのではないかと言うことになる。Firewallでポートを塞げば、それでいいのではないかと言う話もなくはない。ただ、FileMaker Data APIだけにWebサーバーを使うと言うことはあまりないと思われるので、Firewallの設定はちょっと面倒ではないだろうか。絶対に外部からFileMaker Data APIは利用しないで、サーバー内部に限るのであれば、httpでの運用でも問題はないかもしれないが、必ずサーバーの内部からの利用しかしないと言うことを管理者が人手で保証しないといけなくなる。通常、httpsで運用する手順を踏む方が楽なのではないだろうか。

自己署名証明書の問題も同様だ。サーバー内部に限るのなら、詐称のしようもないと考えることができる。これも、「絶対にサーバーの内部からの利用しかしないと言うことを管理者が人手で保証する」と言うモデルであり、むしろ、そういった人的な縛りよりもhttpsでの運用をする方が問題が発生しにく状況であると言えなくないだろうか?

そう言うことで、httpや自己署名証明書での運用は自己責任が大きいので、FileMaker Data APIでアプリケーションを開発したら、本番はhttpsでの運用を目指すようにすべきである。

なお、筆者の作ったFMDataAPIクラスは、デフォルトは証明書の検証をしない状態で稼働するので、そちらは開発中での利用を想定している。実際に正しい証明書が用意できれば、以下のメソッドを呼び出す。そうすれば、証明書の検証を行うようになる。自己署名でないこと、期限、アクセスしているサーバ名と同一なのかが検証される。

$fm->setCertValidating(true);

すなわち、FMDataAPIクラスは、証明書の検証もメソッドでコントロールできるようになっている。

FileMakerデータベースをOAuth認証で利用する

一部に間違いがあり、修正しました。修正箇所は青字で記載してあります。(2017-06-17)

FileMaker 16の大きな機能アップの1つは、OAuth対応だ。GoogleのアカウントでFieMakerデータベースへのログイン認証ができるようになったのである。OAuthの大きな特徴は、1度パスワードを入れれば、その後に認証されたことが異なるサービスに対しても継続されることである。これは「パスワードを覚えていて、その都度送り出す」のではなく、認証した事実を別のサーバーにうまく伝達を行うことで、サービスをまたいだ認証の継続を実現している。パスワードのやりとりは最初のログイン時だけになるので、概してより安全な認証方法と言うべきだろう。FileMakerがOAuthにどのように対応したのかを、データベースログインをGoogleアカウントでログインできるようにするための設定を通じて説明する。

FileMakerデータベースへのログイン

FileMakerデータベースをFileMaker Serverで公開したとする。以下はINTER-MediatorのサンプルデータベースをプライベートネットワークにあるFileMaker Server 16で公開した結果を示す。上記のサンプルで改変した点は本文途中で示す。

公開したデータベースをFileMaker Pro/Advancedで開こうとすると、次のようなダイアログボックスが表示され、そして、アカウント名とパスワードを入力して、「サインイン」ボタンをクリックする。

ここで、FileMaker Server 16で、Googleを認証サーバーとして利用するような設定を行い、加えてデータベース側にそのGoogleのアカウントを追加設定すると、サインインのダイアログボックスがでは以下のように、「Google」のボタンが下部に追加される。このダイアログボックスが表示された時には、「Google」ボタンをクリックするだけでOKである。アカウント名やパスワードのテキストフィールドに、Googleのユーザー名やパスワードを入力することは不要である。

そうすると、デフォルトのブラウザが開き、Googleアカウントのログインの「アカウントの選択」の画面になる。ちなみに筆者が複数のGoogleアカウントでログインをしているのでアカウントの選択になるのだが、アカウントが単独の場合には何も出ないかもしれない。あるいはまだログインをしていないのなら、さらにパスワードの入力や場合によってはアカウントの入力も必要だろう。何れにしても、サインインのダイアログボックスで「Google」ボタンをクリックすると、Webブラウザを利用してGoogleでの認証結果を確認する。その時に、Googleのアカウントでログインしていなければログインをするが、ログインして入ればそのまま処理が継続される。

ログインが成功するか、ログインされて入れば、次の図のようなダイアログボックスが表示される。これは認証が成功したことを示しており、データベースを利用するには「FileMaker Pro Advancedを開く」(もちろん、Proの場合もある)ボタンをクリックする。なお、「開かない」にしたら、何もしないので、ここでは必ず「〜を開く」ボタンをクリックする必要がある。

そうすれば、データベースが開かれる。この時、Get(アカウント名)等の取得関数の結果もデータビューアで示したが、ログインしているGoogleアカウントのアカウント名がそのまま見えている。

以上のように全てがうまく設定された状態だと、ログインパネルで、Googleボタンをクリックすることで、パスワードをその場では入力することなく、自動的にデータベースを開き、データベースではGoogleアカウントで誰が使っているのかを識別できる状態になる。あらかじめGoogleアカウントでログインしていれば、何も追加作業は必要ないか、あるいはアカウントの選択の作業が必要になる。 ログインしていなければ、Webブラウザでログイン作業を行う。

OAuthで利用するためのデータベース

FileMakerのデータベースは、ProないしはAdvancedで管理者でログインをして、「ファイル」メニューの「管理」にある「セキュリティ」を選択する。認証を行なったのちに、アカウントの追加をまずは行う。「アカウントの認証方法」の部分には、「Amazon」「Google」「Microsoft Asure AD」の3つの選択肢が増えている。利用するOAuthサービスを選択した上で、ユーザー名は、そのサービスのユーザー名をそのまま指定する。このように、Googleであれば、Googleのユーザー名を指定したアカウントを作っておかなければならない。もし、作っていない場合は、たとえGoogle側のログインが成功していてもデータベースの利用はできなくなっている。一見すると、他のこの種のサービスのように自由にログインできないのは不便と思われるかもしれないが、登録しないと利用できないようにするのがセキュリティ確保の基本である。誰でもログインできる状態というのは、多くのFileMakerデータベースには望まれていない。

アカウントが実際に利用できるようになるには、「アクセス権セット」を選択する必要がある。ここでは既定の「データ入力のみ」を選択しているが、もちろん、このアクセス権セットに、fmappつまり「FileMakerネットワークによるデータベースアクセス」の拡張アクセス権が設定されている必要がある。これは従来からと同様で、FileMaker Serverで公開するデータベースでは必須の設定である。なお、INTER-Mediatorのサンプルデータベースでは、「データ入力のみ」のアクセス権セットには、fmappはチェックが入っていないので、サンプルをそのまま使う場合には注意していただきたい。

アカウントの一覧には、Googleがタイプの項目が増えており、アカウントの列ではGoogleのユーザー名がそのまま見えている。

FileMaker Serverでの設定

FileMakerのAdmin Consoleで作業をする。ログイン後、左側で「データベースサーバー」を選択し、右側で「セキュリティ」のタブを選択する。そこにあるポップアップメニューで「FileMakerと外部サーバーアカウント」を選択する。すると、Amazon、Google、Microsoftの3つの項目が表示されるので、右側のギアのアイコンをクリックして、作業を進める。ここでは、Googleを例にとって説明する。

Googleのギアアイコンをクリックすると、次のようなパネルが表示される。結果的には、ここでGoogle側で得られた2つのコードを入力することになるが、それは、この後に説明する。簡単なようで難しい問題もあるので、それも併せてこの後に説明する。ともかく、2つのコードが得られたら、「保存」ボタンをクリックする。

ちなみに、Microsoftを選択すると、少し違うダイアログボックスが表示される。これらはサービスごとに得られるデータが少しずつ違うと言うことだ。なお、これら3つ以外のサービスはプラグインとして追加は可能となっているが、基本的にはメジャーなサービスの場合はFileMaker社による機能追加を待つことになるだろう。自社でOAuthサーバーを立てているなら、プラグインの開発をしたくなるところだろうが、こちらはFileMaker社による情報待ちの状態だ。

設定終了後、次のようなメッセージがでかでかと表示される。つまり、FileMaker Serverのサービスを再起動すると言うことだ。もちろん、コンピューター自体を再起動してもいいが、macOS、Windowsでの作業方法が、こちらのページに記載されている。

Googleのコードの取得

Admin Consoleで設定をするには、Google側から与えられるコードを取得しなければならない。そのコードは、Google APIのところで取得を行う。以下の手順で「利用規約の更新」が出てくる場合には、もちろん、そこで対応をして進める。

Googleの場合、Admin Consoleの「データベース」のセキュリティ設定のところで出てきた「Google API Console」をクリックすると、以下のような英語のOAuth 2.0のページが出てくる。実際作業は、このページの本文の2パラグラフ目にある「Google API Console」をクリックして進める。

Google API Consoleをクリックすると、以下のページに移動する。こちらを直接開くには、Google Developer Consoleのページにジャンプすれば良い。なお、このページ内容は、それまでにこの機能を使ったかどうかによって大きく違っている。全く初めて使う場合の作業手順も併せて説明しよう。ポイントは、上部に「Google APIs」というバーが出ている点である。

Google APIsと書かれた右側の部分では、初めて使う場合には「プロジェクトを選択」と表示されるので、それをクリックする。すでに何かで利用してプロジェクトが存在する場合には、とにかくプロジェクト名が見えているのでそれをクリックする。すると、以下のように、プロジェクトの一覧パネルが表示される。パネル右上の「+」をクリックすると、プロジェクトが新たに作成される。ここで、FileMaker Server向けにプロジェクトを1つ作っておく。

プロジェクトの作成時に必要なことは、プロジェクトの名前を設定することである。名前は適当に設定する。なお、プロジェクトIDはこの後は特には使用しない。

プロジェクトを作成すると、そのプロジェクト名がGoogle APIsの右に見えていることを確認して、左側で「認証情報」を選択する。すると、「認証情報を作成」というボタンが見える。ここで、ボタンをクリックして「OAuthクライアントID」という項目を選択する。

なお、ここで以下のようにメッセージが見えているGoogleアカウントでは、必要なコードを生成する権限が与えられていない。例えば、組織で作成されたアカウントではコード生成が許可されていない場合があるので、その場合は個人でアカウントをするなどして、コード発行を行う必要がある。組織のアカウントの場合は、その組織の管理者が、クライアントIDの発行を制限していることが一般的な原因だろう。

 「OAuthクライアントID」を選択した後、同意画面の作成を促す表示が出てくれば、それに従って以下のページで必要な情報を入力する。本来はこの「同意画面」がユーザーに示されて、そしてサービスを利用できるようにするという流れをOAuthでは採用している。しかしながら、FileMakerではこの同意画面を利用していないようで、「ユーザーに表示するサービス名」だけを設定して「保存」ボタンで保存すれば良い。

その後にアプリケーションの種類を選択するページが表示される。ここでは、「ウェブアプリケーション」を選択する。すると、名前などを入力する項目が表示される。ここで、名前は適当に設定するとして、もう1つは「承認済みのリダイレクトURI」を入力しなければならない。このURLは、例えば、FileMaker Serverに接続するためのホスト名が「fmstest.msyk.net」ならば、「https://fmstest.msyk.net/oauth/redirect」を指定する。ホスト名の部分だけがサーバーによって違い、他の部分はどのサーバーでも同様だ。なお、:443はあってもなくても良い。ちなみに、ここにmacOSの共有名(Macintosh.local)や、IPアドレスではうまく動作しない。ドメインを含む利用可能なホスト名をきちんと設定し、そのホスト名でサーバーに接続できる環境になっていなければならない。

「作成」ボタンをクリックすると、生成されたコードがパネルに表示される。こちらからコピーして、Admin Consoleの該当するフィールドにペーストすれば良い。なお、コードは後からでも参照は可能である。

うまくいかない場合の対処

手順は以上の通りだが、FileMakerのドキュメントにも書いてある通り、FileMaker Serverを、きちんとしたドメイン名のURLのホストで公開する必要がある。macOSの共有名の場合、ブラウザからのアクセスが正しくできない場合もある。IPアドレスだけではhttpsでアクセスしているはずはないので、Googleの側で登録が進まない。自分でドメインを持っている方は、何らかのテスト項目を作るなどしてともかくドメイン名を含むホスト名を用意する。

例えば、サインインのダイアログボックスで、Googleボタンをクリックした場合に次のようなページが出たとする。ここで詳細を表示すると、redirect_uriに見えるように、https://MacBookPro.localというホストにアクセスしようとしている。もちろん、この名前は共有名である。ブラウザでは共有名でもOKのはずなのにと思うかもしれないが、単にそのURLにブラウザからアクセスするのではなく、裏ではもっと色々複雑なことを行なっている。筆者の場合には、msyk.netというドメインを所有しているので、fmstest.msyk.netが利用できるようして、検証を行なった。IPアドレスは、実は10.0.1.102というプライベートアドレスだが、自宅環境ではそれで運用可能なので問題はない。

ここで、上記のrequest_uriのURIがどのように自動生成されるのか分からず、対処がなかなかできなかった。実際には、FileMaker Pro/Advancedがrequest_uriを「サーバーへ接続した時に使うホスト名」から生成しているようだ。macOSの場合、自動的にBonjour名が左側に出てきてアクセスをしがちであるが、それだと、上記のrequest_uriには共有名が含まれてしまう。サーバーのドメイン名(つまりFQDN)で接続するサーバーを選択できるように、例えば、お気に入りのホストにドメイン名を登録して、そこからデータベースを選択して開くようにすれば良い。以下の図のように、fmstest.msyk.netでデータベース選択ができるように、お気に入りのホストの登録を行なった。もちろん、自動的に識別される名前がホスト名であれば、それを選択すればOKである。

OAuth対応をどう考えるか

以上のように、Google側の使いこなしが必要になるものの、OAuth対応は確かに便利だろう。アカウントそのものの管理を外部に任せることができるのである。ただし、社員全員がGoogle Appsなどでアカウントを持っていれば便利は便利なのだが、データベース個別にそれぞれのアカウントを登録しなければならない。これは、テキストファイルで読み込みはできないため、自動化のスクリプトなどを使用することになると思われる。ともかく、Googleにアカウントを作ればデータベース側を変更しなくても新しいアカウントから使えるようになる…と言う状況は作れない。機能としては素晴らしいが、運用を考えた時に、手間になる部分も見えてくる。ログインしたアカウントのドメイン名がある名前であれば、自動的に登録されて定義されたアクセス権セットを利用するような仕組みがあることで、管理負荷を軽減できると考えられる。

FileMaker Data APIもOAuth対応している。その意味ではWeb対応しているのだが、WebDirect経由ではOAuth対応はなされていないこれは先のバージョンを待つしかないだろう。WebDirectについては当初は対応していないと記載していたが、GOからのアクセスも含めて対応はしている。エミックの松尾さんに指摘をいただいたが、恐らく正しい証明書であればHTTPSであればOAuth認証ができ、自己署名の証明書であればできないということではないかと思われる。なお、http://…だと、Googleで登録ができなかった。この件、簡単に検証ができないのではあるが、手元で検証した時の違いとなると署名書の違いしか考えられない。

[IM] OAuth2あるいはOpenID対応

Google AppsのOAuth2対応について、Using OAuth 2.0 to Access Google APIsに説明されています。この認証方式をサポートしました。したがって、OAuth2対応およびOpenID対応と言えるかと思います。Google以外のプロバイダについては今後、確認します。まずは、認証できるようになっているので、その使用方法を説明します。

OAuth認証するクライアント

まず最初に、ページをOAuth対応にした場合にどんな感じにページ表示されるのかを示します。認証を必須にすると、INTER-Mediator内蔵のログインパネルが表示されそこに「OAuth認証」というボタンが登場します。ここで、ボタンをクリックします。

shot2712

初めて利用するときには、次のように、認証アカウントから何を取り出すのかを表示するメッセージが出てきます。ここで「許可」をクリックします。なお、複数のアカウントでログインしている場合には、さらにどのアカウントでログインするのかを問い合わせるページもこの前に表示されます。

shot2713

そして、認証されます。おなじみのサンプルのページです。ログインユーザーは、ここでは意図的にプロバイダーによって提供される一意な名前とプロバイダー名を@でつないであります。

shot2714

認証のデータベースを見てみると、そちらに新たにユーザーが追加されています。つまり、外部にあるユーザーの認証ではありますが、いったん、利用しているデータベースのauthuserテーブルに、ユーザーを作り、もっぱらauthuserテーブルのユーザー情報を利用して、認証を行います。一定時間で無効化しますが(今日現在未実装)、それまでは、OAuth認証直後にランダムに生成したパスワードをクライアントに通知して記憶させ、INTER-Mediator自身の認証処理を行うことで、都度都度OAuthサーバーとのやりとりはないようにします。

shot2715

Googleでのアカウント発行

GoogleのOAuth2を利用するためには、アカウント発行が必要です。このアカウントは、アプリケーション、つまり、INTER-Mediatorで作るページに対するアカウントです。ページの利用者はこれらの情報は不要ですし、見えるようにする必要はありません。

まず、Googleデベロッパーのコンソールページに移動します。ここで、「プロジェクトを作成」をクリックします。このページは、もしかすると、2つ先のような画面になっているかもしれません。その場合はページの中にある新規プロジェクトを作成するようなボックスがあるので、それをクリックします。

shot2701

プロジェクトの作成で指定するのはプロジェクト名のみです。もちろん、開発者が把握できる名前を指定して、「作成」ボタンをクリックします。

shot2702

このようなページになります。追加したプロジェクトが1つのボックスになっています。また、左側に見えるように、このページが「ホーム」です。初めての利用であれば、このページに行きますが、以前い何か利用していた場合ではこの限りではありませんので、臨機応変に対処しましょう。ここまでで、ともかく1つのプロジェクトを作成してください。

shot2703

プロジェクトのボックスの右下にある「V」マーク部分をクリックすれば、内容が開きます。ここで、「プロジェクトの詳細」をクリックします。

shot2704

左側のナビゲーションで、APIと認証にある、「認証情報」をクリックします。認証情報というパネルが出るので、「認証情報を追加」をクリックします。

shot2705

ドロップダウンから、「OAuth 2.0クライアントID」を選択します。

shot2706

このような画面になります。「同意画面を設定」をクリックします。ここの同意画面は、最初に認証するときに見える画面です。

shot2707

メールアドレスはGoogleアカウントのメールアドレスが設定されています。サービス名を適当に記述しますが、この名前がタイトルになります。その他は「省略可」であるので、認証の動作には影響しません。入力をして「保存」ボタンをクリックします。

shot2708

アプリケーションの種類は「ウェブアプリケーション」を選択します。そして、「名前」は一覧の中で識別する名前を適当に指定します。そして、承認済みのJavaScript生成元には入力せず、承認済みのリダイレクトURLに、ここではINTER-Mediatorに含まれている/Auth_Support/OAuthCatcher.phpのURLが示されています。実際に利用するときには、このファイルのコピーを作るなどしてもかまいませんが、このまま利用してもかまいません。ログインパネルの「OAuth認証」ボタンをクリックすると、Googleが指定する「トークンリクエスト」のURLに移動し、ユーザーの特定や取得可能な情報のアクセス許可をページ上で求めます。その後に、「承認済みのリダイレクトURL」にリダイレクトするときに、アクセストークンが引数として渡され、INTER-Mediatorはそれを元に、OAuthユーザーをデータベースに作成します。

shot2709

「作成」ボタンを押すと、クライアントIDとクライアントシークレットが表示されます。これらはparams.phpファイルにコピペをします。コピペの方法は後で説明します。(ご安心ください。このIDとシークレットはすでに無効化してあります)

shot2710

OKをクリックすると、発行したアイアウントが一覧されるページになります。ここから、削除や追加、あるいは変更などのアカウントの管理もでき明日し、同意画面の変更などもできます。

shot2711

INTER-Mediatorで作成するファイル

OAuth認証を使いたいページでは、まず、定義ファイルに基本的な設定を行います。例えば、以下のファイルは、Samples/Sample_Auth/MySQL_definitions.phpの記述です。IM_Entryの第2引数に、authenticationキーで連想配列を指定します。とりあえず、クレデンシャルの記録方法(ここではセッションストレージ)とレルム(ここでは「Sample_Auth/MySQL_definitions」)を指定します。レルムは単に同一認証を受け付ける領域名とと考えてください。

IM_Entry(
    array( /* コンテキスト定義 */
    array(
        'authentication' => array(
            'storing' => 'session-storage',
            'realm' => 'Sample_Auth/MySQL_definitions',
        ),
    ),
    array('db-class' => 'PDO'),
    2
);

Googleに関連づける情報は、params.phpファイル側に記述できます。これらは、定義ファイルでは記述できないのが現在の仕様です。それぞれ、以下のように、決められた変数名に値を指定します。最初はプロバイダーで現在は「Google」のみサポートしています。続いて、クライアントIDトクライアントシークレットを、Googleのデベロッパーコンソールのページからコピー&ペーストします。最後のリダイレクトのURLは、「承認済みのリダイレクトURL」と同じURLを指定します。

$oAuthProvider = "Google";
$oAuthClientID = '1084721348801-jv3hvi4shcmr4j7unuhioq8k2mm47n6s.apps.googleusercontent.com';
$oAuthClientSecret = 'hV5TZD8x108K1Zac4RfZopur';
$oAuthRedirect = 'http://localhost:7001/Auth_Support/OAuthCatcher.php';

まだ完成というまでには至っていませんが、ともかく、認証できるところまでを作りました。タイムアウトのタイミングや、カスタマイズポイントなどを作りこみたいと思いますが、ご意見があれば、Facebookのグループでよろしくお願いします。

[IM]LDAP認証の実装がだいたいできてきました

INTER-Mediatorには、自分自身でユーザーテーブルを持つ認証(ビルトイン認証)が可能です。そして、データベースエンジンのユーザーによる認証(ネイティブ認証)もすでにサポートしています。次に取り組むのはやはりLDAPです。ただ、MySQLにはLDAP接続のプラグインがあり、そういう手法を使えば、ネイティブ認証の一環としてLDAP認証を実現することができます。しかし、通常とは異なるデータベース運用が必要になりますし、MySQLとPostgreSQLで動作に違いがあるとまた大変です。SQLiteはそういう統合はできません。LDAPについては、単に認証の確認だけだと、要するに認証バインドをするだけのことであり、PHPではさほど難しくはないので、データベースエンジンと独立してLDAP認証の仕組みを搭載しました。

LDAPサーバに対する設定

まず、LDAPサーバ情報は、params.phpファイルに、変数で記載する方法にしました。LDAPでの認証時は、ユーザーはユーザー名だけを与えるのではなく、ユーザーレコードのDN(Distinguished Name)を指定する必要があります。たとえば、OS X Serverで、ホスト名がhomeserver.msyk.netの場合、

uid=msyk,cn=users,dc=homeserver,dc=msyk,dc=net

というのがユーザーを特定するDNとなります。ここで、dc…以降は「検索ベース」、cn=usersは「コンテナ」とします。さらに、OS X Serverはuidという属性名でユーザー名を指定しますが、これもActive Directoryでは違うこともあって、結果的に上記のユーザー名「msyk」以外の部分をすべて、変数で与えて、DNを構成するようにしています。サーバーのURL、ポート番号も合わせて、結局、params.phpファイルに以下のように記載をすることにします。

$ldapServer = "ldap://homeserver.msyk.net";
$ldapPort = 389;
$ldapBase = "dc=homeserver,dc=msyk,dc=net";
$ldapContainer = "cn=users";
$ldapAccountKey = "uid";

なお、$ldapServer変数に設定されている文字列の長さが0以上なら、LDAP認証を試みるように動作します。これらの変数部分を全部コメントにすると、LDAP認証に関しては何も行わず、以前の通りの動作になるようにしました。

PHPのLDAPライブラリの機能を使って認証するとしたら、その認証のためのバインドはサーバーからLDAPサーバーに送られます。ということは、クライアントからサーバーに対して、ユーザー名とパスワードを送り届けないといけません。これは、ネイティブ認証の仕組みを利用しますが、そのために、鍵ペアを生成して、params.phpファイルに記述します。以下の部分です。もちろん、最初から入っている鍵ではなく、コメントに書いている方法で自分が使用する鍵に置き換えてください。もちろん、クライアントに送られるのは、公開鍵です。

$generatedPrivateKey = <<<EOL
-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBAKihibtt92M6A/z49CqNcWugBd3sPrW3HF8TtKANZd1EWQ/agZ65
 :
jU6zr1wG9awuXj8j5x37eFXnfD/p92GpteyHuIDpog==
-----END RSA PRIVATE KEY-----
EOL;

ネイティブ認証との混合動作

そして、LDAPアカウントでのログインは簡単にできました。ただし、1回の認証バインドに0.2〜0.3秒ほどかかります。同一のサブネットです。たとえば、フォームのサンプルだと、1ページの合成にデータベースアクセスを15回ほど行うので、5秒くらいのアクセス時間の増加になります。これは、ちょっと長いです。また、単に認証ができたとしても、グループ設定との連動等といった問題があります。

そこで、LDAPアカウントで認証が成功したら、ビルトイン認証で使うテーブル(authuserテーブル)に、そのLDAPのアカウントの情報をレコードとして追加することにしました。1回成功したら、ビルトイン認証テーブルにユーザーを追加し、パスワードもわかっているのでハッシュ化したパスワードを保存します。そのために、ビルトイン認証を行って失敗するとLDAP認証を行うという流れにしました。ビルトイン認証とLDAP認証は切り替えるのではなく、この順序で両方行います。
しかし、その追加したユーザーがいつまでも使えるのは問題で、タイムアウトさせないといけません。そこで、結果的にはビルトイン認証のテーブルにDateTime型のフィールド「limitdt」を追加する必要が発生しました。現在の実装では、そのフィールドの有無で落ちることはないようにしてありますが、LDAPを使う場合には追加したフィールドの定義がされていないといけません。

こうしてユーザーのレコードを作っておくと、グループへの登録ができます。ユーザー名で識別され、1度登録すると消されないので、主キー値は保持されるはずです。タイムアウトすると、LDAP認証を試みます。ただ、この部分、現在実装中で、うまくいったりいかなかったり、一進一退ですが、ある程度のところまで動くようになっています。ちなみに、MoodleもLDAP認証をサポートしますが、ログインを1度することで、ユーーザーレコードが作られる仕組みになっており、やはり同じような仕組みをINTER-Mediatorでも実装しています。

認証処理の流れ

初めて、LDAPアカウントでログインしようとするとき、ビルドイン認証のテーブルにはそのユーザーはありません。したがって、ビルトイン認証では失敗しますが、その後のLDAP認証で成功します。このとき、新たにビルトイン認証のテーブルに、そのユーザーのレコードを作りパスワードのハッシュと期限を記録します。クライアント側には認証のための情報が残されているので、この次の通信時からは、自動的にビルトイン認証が成功します。したがって、1画面作るのに20回の通信処理が必要でも、最初の1回だけがLDAP認証されます。

次の通信処理が、LDAP認証のタイムアウト以内の期間なら、ビルトイン認証が成功して終了します。そのとき、limitdtフィールドも現在の時刻に更新します。しばらくクライアントを利用しないなどでタイムアウトになると、ビルトイン認証は失敗しますが、引き続くLDAP認証が成功するように、クライアントでは、LDAP認証とネイティブ認証に必要な情報が残されています。そして、1度LDAP認証に成功すると、次回以降はまたネイティブ認証がタイムアウトまで成功します。

認証に必要な情報はクッキーに保存することもできるので、翌日にまた認証を継続させることもできます。

今現在、動作が怪しいのは、LDAP認証のパスワードを変えたときです。まず、この方法だと、LDAP認証のタイムアウトの時間が来るまでLDAPでの認証は行われないので、その期間は変更前のパスワードが通ります。これは、とりあえず、仕方ないことの1つとしておきます。そして、タイムアウトしてLDAP認証すると、当然ながら以前のパスワードでは認証が通らないので認証エラーとなり、ログインパネルが表示されます。ここで、新しくなったパスワードを入力すると、また同じように動作するというのが期待する動作です。このあたりの挙動が現状、今ひとつな感じです。

FileMakerはサポートせず

なお、LDAP認証は、PDOのみで、FileMaker Serverはサポートしません。どうしようかと思ったのですが、Admin Consoleでの設定で「外部サーバーアカウント」をクライアント認証で使えるようにしておけば、ネイティブ認証で事実上、Active Directory、Open Directoryは利用できます。LinuxのLDAPは使えないけど、FileMakerのクライアントで使えないで、Web側だけで使える仕組みまでのサポートは必要かどうか疑問ですので、FileMakerはINTER-Mediator組み込みのLDAP認証はサポートしないということにしたいと思います。

第三者を介在せずに「抽選」を行う方法

Facebookに記事を書いたように、機材の販売先を決める抽選が必要になりそうです。第三者に立ち会ってもらって公正にするということは可能でしょうけど、それでも不正の確率は0になりません。頼まれた方もいい迷惑(笑)。なんかいい方法がないか考えました。こんなのはどうでしょう。

基本的な手法

  1. 当せん決定者は、何か1文字を思い浮かべるが、公表しない
  2. 複数の抽選参加者は、何か1文字を思い浮かべて公表する
  3. Unicode のエンコードで、決定者の文字に一番近い参加者が当せんとする

しかし、いろいろ問題があります。決定者が、参加者の公表よりも後になって、思い浮かべた文字を変えてしまうということをしても検出する方法がありません。つまり、決定者は、誰かが当せんするように、意図的に文字を思い浮かべ、それを事前に思い浮かべたものとしてしてしまうと不正が成立します。

では、決定者が文字を思い浮かべた時点で、第三者に伝達する方法があります。しかし、これは決定者と第三者、あるいは参加者と第三者が、裏で結託していると、やはり不正が成立します。

不正を防止する手段

しかしながら、以下のような、ダイジェスト(あるいはハッシュ)を利用する方法をすれば、第三者の介在なしに、不正ができないと考えますがどうでしょう。

  1. 当せん決定者は何か1文字を思い浮かべる:その文字をcとする
  2. 当せん決定者は、別の適当な文言を思い浮かべる。何文字かは公表しない:文章をsとする
  3. s+cのダイジェストd1を求めて公表する
  4. sのダイジェストd2を求めて公表する

こうして2つのダイジェストを求めますが、当然ながら、決定者はファイル等で、sとcを残しておきます。これらのファイルや文字列が、最終決定までに漏えいしないことが前提です。

2つのダイジェストを公表したのちに、参加者は、期限までに「自分が思い浮かべた1文字」を公表します。他人の表明を見ての変更もありとしてもいいかと思います。

最初cのダイジェストを求めればいいかと思ったのですが、Unicodeで1文字程度なら、全部チェックで比較的短時間でわかってしまうという懸念があります。もちろん、公表から10分以内という手もありますが、セキュリティホールの確率が下がるだけです。そこで、不定長の文字列と組み合わせることを考えつきました。

データの作成例

以下は、具体例です。sha1は、「openssl sha1 (ファイル名)」で得られます。公開/非公開は、参加者の表明が終わるまでの間の扱いです。

s="サンプルテキストです:"(非公開)
c="A"(非公開)
sのsha1→34591a094e22f43fb1ba99426265383993599c96(公開)
s+cのsha1→1c19e4ce3a0d49b6dff756e2bf62bdd605355051(公開)

ここで、公表するのはsha1のダイジェスト値のみです。従って、この2つのバイナリデータから、「A」を推測するのは難しいです。cのダイジェストならば数万回程度の試行で元の文字列が分かるかもしれないけど、上記のd1とd2は「不定数の文字列のダイジェスト」なので、ブルートフォース攻撃の必要アタック数は桁違いに高くなります。決定者がAないしはsを変えてしまって、同一のダイジェスト値を得るのは、ほぼ無理と考えれば、不正が入る余地はありません。もちろん、sha1ではなく、sha512などを本番では使うべきでしょうね。

sもcも決定前には未公開なので、参加者は偶然に当ててしまった場合でも、当たったかどうかは分からないはずです。

なお、抽選者が3人以上の場合、「文字コード上で一定以上の距離を空ける」というルールは必要でしょうね。例えば、ある人が「F」と言ったとします。別の2人が「E」と「G」と宣言して、最初の人の当せん確率を限りなく0にすることが可能です。つまり、別の2人が結託している状況です。まあ、これは監視されている上なので、普通はやらないとは思いますが、厳密にはそのルールが必要かと思います。

抽選者にとって、確率は同一になるかどうか? ここはアイデアが固まっていません。抽選者にとってはcは未知なので、Unicodeのコード空間上、どこにあるかは分からないという点では均一なのかもしれません。しかし、cが空間の端の場合とど真ん中の場合で抽選者に影響はあるのかどうかという点も気になります。cを複数設定して、参加者の1文字は一番近いcを採用するといったようなランダム化は必要なのかもしれません。しかし、この問題は、ちょっと難しそうなので、cは1つということにします。

いかがでしょうか?

[IM]MediaAccessクラスと新たな拡張点(2)

こちらの文書の続きです。

FileMakerのオブジェクトフィールドを参照する

オブジェクトフィールドはデータベースごとに扱いが異なり、統一的にはやりにくい処理ではあります。MediaAccessクラスでは、FileMaker Serverをターゲットにオブジェクトフィールドに対応する機能を作成しました。

FIleMakerはFXを経由し、XML共有の仕組みを使います。テキスト型や数値型は、基本的にテキストでフィールドにあるデータが得られます。一方、オブジェクトフィールドはオブジェクトそのもののデータではなく、フィールドのデータに応じた以下のような「テキスト」が得られます。

/fmi/xml/cnt/photo.jpg
http://server:16000/…

PDFは完全なURLで、FileMaker Serverに16000ポートで接続して取り出すことが可能です。JPEGなどの画像の場合は、URLのパスに相当するものが得られますが、たとえばIMGタグのSRC属性にそのまま指定が可能な文字列になります。

いずれにしても、両方ともURLであると解釈すればいいわけです。この仕組みはFileMaker Serverに限らず、一般的なアクセスにも使えます。つまり、media=URLと指定をした場合は、そのURLにアクセスしたデータをMediaAccessクラスが取得し、さらにクラスを呼び出した元にそのデータを返します。/fmi/xml/cntで始まる物だけは特別にURLであるという処理が組み込まれています。また、URLかどうかはそれ以外には、httpあるいはhttpsで開始するものかどうかで判定しています。

MediaAccessでのアクセス権

認証が成立したらすべて参照可能となり、成立しなければ参照不可という単純なものなら非常に話が早く、前に説明したmedia-tokenの仕組みで事は足りるのです。なお、データはCRUDの4つの側面がありますが、メディアに関しては「編集」というのはWeb世界ではかなり難易度が高い世界であり、MediaAccessクラスはほぼ参照のみのサポートになっています。

ここで、メディアそのものがログインしたユーザごとのアクセス権を持たせたい場合が出てきます。レコードについては、特定のフィールドにユーザ名やグループ名を入力することで、そのユーザやグループに所属したユーザでないと参照や更新ができない仕組みを持っています。フィールドのデータはそれでいいのですが、メディアは実体はレコードと別に有ります。ここで、個々のメディアをコンテキストのレコードと結合させ、レコードごとのアクセス権をメディアにまで及ぼす仕組みを組み込みました。

まず、IM_Entry関数の2つ目の引数(オプション引数)に、キーが’media-context’で値がコンテキスト名(コンテキストのnameキーに対する値)を与えます。すると、メディアはこのコンテキストにある特定のレコードの、1つのフィールドのようなふるまいになります。

‘media-context’ => ‘context-name’,

実際にメディアにアクセスするパスは次のような形式にします。つまり、コンテキスト名、レコードの検索条件をパスに入れます。最初のfilesは特に意味はなく、相対パスの最初のキーワードです。context-nameは、media-contextの値と同じでなければなりません。そのコンテキストのkeyキーに対する値、つまり主キーがpidであるなら、たとえば、field=valueは、pid=312 のような値になります。

context.php?media=files/context-name/field=value/filename.png

ここでもし、media-root-dirが /var/www/media であるなら、実際に

/var/www/media/files/context-name/pid=312/finename.png

という絶対パスの画像ファイルが存在する必要があります。コンテキストの定義には、レコード単位のアクセス権設定があれば、メディアに対するアクセス権の認証の確認を行い、ユーザを特定します。pid=312のレコードがそのユーザにアクセス権があるのかどうかを確認することによって、アクセスの可否を決めます。従って、適当にpid=316などとパスを変えても、その条件で検索されたレコードが他のユーザに対する権利があるものであれば、400番台のレスポンスを返してデータは返しません。認証の確認を行い、そのユーザに対するアクセス権がないものは出力しないという仕様によりアクセス権は定義した通りに適用されます。

pid=312を、age=45のようにできると言えばできますが、おそらく、そういうディレクトリは存在せず、漏洩にはならないでしょう。

ファイルのアップロードのコンポーネントは、コンテキスト名やレコード検索条件のパスを自動的に作成するようにも作られています。

とまあ、ここまで書いたところで、ソースに間違いを発見! また、グループ名をフィールドに入れる場合はまだ実装していなかったことも思い出しました。今のところ、メディア関連処理は、開発している側で「必要の合った」状況しかうまく動かない可能性があります。ぜひとも、いろいろ試してフィードバックをください。

(まだ続く)

Booking.comを騙るメール

来ました。予約した覚えはないのですが、1泊で1800ドルとはゴージャスなものです。ただ、よくあるタイプの別のサイトへの誘導は明示的ではなく、HTML内にあるのリンクはちゃんとbooking.comに行きますね。しかし、金額は書いてあるけど、どこのホテルか書いていない。そんな予約はありえないでしょう。このメールアドレスで昔booking.comを使った可能性もあるのですが、なんとアカウントは作られていませんでした。まあ、これでほとんど安心なのですが、念のためアカウントを作ってみたのだけどやはり予約は入っていません。また、添付するzipを展開するとexeが入っていたので間違いなく、嘘メールでしょう。あと、巧妙なのは、本物のBooking.comの広告メールと同じような時間に配布しているところですね。

だけど、ClamXavだとマルウェアと判定はしませんでした。Booking.comには似たような警告はありますが、このメールではなく、1年ほど前の別のもののようです。ということで、警告の意味も含めてブログに記載します。1ヶ月ぶりの書き込みがこんな話題ですんません。

スクリーンショット 2013-08-06 14.52.52 スクリーンショット 2013-08-06 14.53.09

DHCPセキュリティ弱い説:続編

先日、このブログに、「DHCPはセキュリティが低い!?」を書いたところ、けっこう反応がありました。現状、「セキュリティが弱い」というコンセンサスがないにもかかわらず、固定IPで運用しているという場面は決してない訳ではないということで、Twitterでもレスポンスをいただきました。

しかし、そんな情報がどこから出て来たのだろうかとふと疑問に思い、いろいろ検索をしてみました。まずは、マイクロソフトの「DHCPのセキュリティ情報」です。最初に『DHCP と関連プロトコルでは、次のようなセキュリティ上の問題が判明しています。』と前置きをして、以下のようなことが記載されています。タイトルだけ抜粋します。

  1. DHCP が認証されていないプロトコルです。
  2. DNS サーバーに対するサービス拒否攻撃を、DHCP サーバーを介して実行できます。
  3. 承認されていない Microsoft 以外の DHCP サーバーが DHCP クライアントに IP アドレスをリースできます。

1の認証を経ないプロトコルであるというのはその通りです。ただし、認証を行う方法はあります。これは後で説明をします。2については、一般的なDHCPの問題ではなく、ホスト名とIPアドレスの対応をActive Directoryにレコードとして追加するダイナミックDNS特有のセキュリティ問題です。一般のDHCPには関係ありません。3についてはADに承認したDHCPという仕組みを利用できますが、当然ながらADとは関係ないDHCPを立てる事は可能なのです。文章を読むと、別に誤解をさせることは何も書いていません。しかしながら、前置きのところだけを見て、それだけで判断してしまう人もいるんじゃないでしょうか。

日本の学会誌についても、検索してみました。たとえば、「IPアドレス自動割り当て方式(DHCP)におけるセキュリティの実現方法」網淳子, 岡本利夫(1995年電子情報通信学会総合大会 B-829)という論文があります。この論文は、認証なしにIPアドレス配給ができるDHCPのニセモノサーバの存在を検知する方法を提案しています。その部分を引用すると『ところが、現状のDHCPはセキュリティの面で不充分であり、権限のないサーバーが勝手に立ち上がって誤ったアドレスや経路の情報を流したり、悪いホストが他のホストになりすまして情報の横取りをする可能性が高い。』となっています。省略すると「DHCPはセキュリティ面で十分じゃない」となるかもしれませんが、この論文はニセサーバの問題を論じているのです。固定IPで運用するべきとはどこにも書いていません。

他に見つかったのは「特集 モバイルコンピューティングを支えるシステム技術/移動透過な通信を実現するプロトコル(寺岡文男)」(電子情報通信学会誌 Vol.80 No.4 pp.344-349)というものがあり、ABSTRACTの引用をすると『DHCPはネットワークパラメータの自動設定を行うプロトコルである。Windowsにも実装されて広く利用されているが、認証の機構がなく、セキュリティに問題がある。』と書かれています。この記事では場所を移動する状況での通信方式についてのことが書かれていますが、DHCPのセキュリティについて論じたものではありません。認証をしないという仕組みについての喚起として記載されています。

いずれも間違えたことはもちろん書いていません。しかしながら、断片的に読んで結論を出してしまう人にかかれば、「DHCPはセキュリティ的に問題がある」ということになってしまいます。

ちなみに、現在において、DHCPの認証はできるかどうかというと、「簡単に」できます。1つはDHCPサーバに応答してもいいホストのMACアドレスを登録する方法です。ワイヤレスでも使われる場合もあります。使うPCのMACアドレスを逐一設定しないといけないので、管理の手間はかかりますが、確実な方法として使われています。ただ、MACアドレスの登録なんてどうやるの?と思う方もいらっしゃるでしょうけど、現在はいちばん安物のブロードバンドルータでも、管理ページを開けばこの設定は出てくるのじゃないでしょうか。サーバOSでのDHCPでは設定できて当然です。この機能が使えないという状況は、実際には皆無に等しいでしょう。

さらにより確実な方法として、802.1Xという手法があります。ただし、認証のためのサーバの設置や、場合によってはデジタル証明書の発行などの作業が必要になり、簡単には行きません。しかしながら、高いレベルのセキュリティを使うところでは利用されているソリューションです。

では、認証をしないDHCPで、どんな工夫があるのかも紹介しましょう。会社などでは、カードキーで社員証にもなっているカードをリーダに読み込ませないと、オフィスに入れない環境ならば、「オフィスにいるのは社員あるいは承認された人である」という理屈が成り立ちます。それがほぼ100%実現されるのであれば、認証をしないDHCPでも問題はないでしょう。

カードキーがないようなところでも、前に書いたように、普通は基本的なセキュリティ、つまりよそ者が簡単には入れないようになっているので、概ね問題ないと考えるのが一般的です。よそ者がネットに簡単につなげるようなところでは、ネットワーク以前に財布や家具がなくなります。また、検索して見つけた記事で「我が家のインターネットはDHCPではセキュリティ的にまずいでしょうか」という答えに「ネットの心配をする前にまずは鍵を直しましょう」という回答がありましたが、まさにその通りですね。

DHCP危険説は一種の都市伝説かもしれません。もちろん、プロトコル的な問題点はあるのですが、これまでにも説明してきたように、それらの問題点は実際には問題にはなっていませんし、認証をさせるという解決策もあります。おかしな伝説がまことしやかに流れることがないように願う次第です。

DHCPはセキュリティが低い!?

このところ、「うちは固定IPです」というのをよく聞きます。ネットワークの設定を業者に依頼したときに、「DHCPはセキュリティ的に問題があるから固定IPにしましょう」と言われるそうです。もちろん、買ってきたマシンのセットアップが面倒ということもありますが、ところによっては、パソコンが増えるたびにIPアドレスを業者に指定してもらって設定しているとか。どうも、それでメンテナンス料を取っているのじゃないかと思われる節があります。

いくつかのサイトを見たところ、DHCPが脆弱であるという理由は、次の通りです。

  • どんな機材にでもIPアドレス等インターネット接続に必要な情報を渡すため、誰でも接続できる。
  • 不正アクセス時に誰がアクセスしたか分からない。

前者は、「悪意を持った人が簡単に接続できる」みたいな書き方をしていれば、まあ、みなさん、恐れるのは無理も無いかもしれませんが、よく考えると、この理屈には問題があります。

一般に、ネットワークと言えば、ワイヤレスないしはEthernetでしょう。ワイヤレスは接続自体にパスワードをかけるのが現状では一般化しているので、「社内の人しか使えない」みたいに言えなくはありません。まあ、そこも突っ込みどころありますが、ここではEthernetにフォーカスしましょう。

仮に、ある事務所で、EthernetでDHCPを使っていたとします。そうすると、もちろん、事務所外の人がそこにPCを持ち込み接続すると、インターネット接続できます。DHCPの問題点はそこだというわけですね。これは、Microsoftの技術文書にも書いてあります。

もちろん、MACアドレス(Ethernet ID)をDHCPサーバに登録するという方法で、外部の人の接続は阻止できますし、Active Directoryは確かにDHCPやDNSとの連動で阻害はできるので、いわゆる普通のDHCPより安全であることは言えるでしょう。では、一般的なDHCPが安全ではないと決めつける事ができるのでしょうか?

一般の事務所で、部外者が勝手に入ってきて、Ethernetにつなぐという行為があったとき、事務所の人は無視をしますか? 普通、どなたですか? ご用事はなんでしょうか? くらい聞きますよね。人の出入りが激しく部外者がいつでも出入りしている…というところがあったとしても、それは、Ethernetを設置するのが間違いで、普通はワイヤレスだけにします。部外者がEthernetを勝手に使えるような事務所があったとしたら、きっと、普通の悪者は「インターネットにつなごう」と思う前に、「財布を盗もう」とか「家具をぱくってやれ」くらい考えるでしょう。知らない人が入ってきて、勝手にお茶をわかそうとしたら、普通は排除しますよね。それと同じで一般には事務所のEthernetは人の目で監視されているはずです。そうではないとしたら、ネットワークのセキュリティ以前の問題です。

しかし、それでも、例えば、深夜に忍び込んでアクセスできるということもあるかもしれません。ネットワークを勝手に使ってデメリットはあるでしょうか? 勝手にファイルサーバの中身を盗まれたり、消されたりするという心配もあるでしょう。しかしながら、これは「すべてのサーバはユーザ名とパスワードの入力が必要」としておくことで、防ぐことができます。面倒臭いからと言って、誰でも読み書きできるファイルサーバを立てていれば、もちろん危険ですが、そういうサーバ管理はDHCP以前の問題で、そういう運用自体が危険です。重要な情報はともかく認証が必要としておけば、何も心配することはありませんし、不正アクセス自体をほぼ100%排除できるわけです。排除できれば、誰がやったのかを調べる必要はありません。これはDHCP以前に、ネットワークのセキュリティを確保するために必要なことです。

そうしたら、深夜に忍び込んだ悪者は、単にインターネットでGoogle検索するくらいしかやることはありません。月額固定の通信料だとしたら、ほとんど被害はないでしょう。だいたい、それ以前に、椅子とかロッカーとか盗まれますね。

さらにさらに、固定IPにすれば、インターネット接続できないと思っている人も居るかもしれませんが、固定IPのネットワークにつないで、ある程度ルータやDNSのアドレスに目星をつける事もできます。Mac OS Xだと、とりあえず可能なようです。やり方は、「ping 10.255.255.255」「ping 192.168.255.255」といった末尾が255のグローバルPINGでいろんなネットワークアドレスを試します。その後に「arp -a」とすれば、だいたい、応答があったホストのIPは分かります。後は、経験と勘でどれがルータか分かりますし、DNSサーバのホストもポートスキャンで分かります。不正アクセスしようという輩は、この手の手法はよくご存知でしょうから、「固定IPにしたら、インターネット接続できない」ということ自体間違いです。

思うに、こういう「DHCPはだめ」というのは、後々のメンテナンス費用で稼ごうとしている業者の作戦なのではないかと考えます。DHCPでちゃんと動けば、後は何もしなくてもOKとなると、メンテナンス費用をかせげません。IPをつどつど業者からアサインしてもらう上では、確かに業務としては発生しますが、なんだか、倫理的にぎりぎり、あるいは一線を超えてないでしょうか。

そういうわけで、DHCPは便利ですから、DHCPを使いましょう。言い換えれば、DHCPを取り入れたネットワーク管理ができるようになりましょう。家庭で当たり前のように使われているDHCPですが、事務所で使えないことにもっと疑問を持つべきです。

それでも、不安と思う方は、次のように考えてみてください。固定IPにしたときの設定の手間やIPアドレスの管理といった仕事が増えるコストは、DHCPにすることによるその損失(仮にあるとすれば)より、高くなっていませんか? 典型的な、セキュリティにかける費用が損失を上回る失敗プランなのです。いわば、保険金の払い過ぎってイメージでしょうか。