仙石浩明の日記

2006年4月6日

DB サーバのセキュリティ向上策 (4)

前回は、 DB サーバへの通信を監視して、 UNIX でのユーザ権限と DB ユーザ名が一致する時に限り 通信を許可する方法について説明しました。

アクセス元となるクライアント側のマシンならば、 どのユーザがアクセスしているか容易に調べられるので、 通信の監視もアクセス元で行なった方が簡単です。

しかしながらこの方法では、 データセンタ内の全てのサーバで通信の監視を行わなければならず、 やや繁雑です。 また、UNIX でのユーザ権限ごとのアクセスコントロールを 実現する方法として、 前回は各ユーザごとに専用の UNIX ドメインソケットを用意し、 そのパーミッション設定でコントロールする方法を紹介しましたが、 当然のことながら DB アクセスを行うクライアントプログラムが UNIX ドメインソケットをサポートしていなければなりません。

DB サーバへの通信の監視をアクセス先、 つまり DB サーバー側で行うことができれば、 クライアント側は監視が行われていることを意識する必要がなくなります。 つまり前回説明した「入口規制」によるアクセス制限ですね。 クライアント側から見れば、 普通に DBサーバへ TCP 接続するだけなので、 どのようなクライアントプログラムでも利用可能でしょう。

この入口規制を実現するには、 どのユーザ権限でクライアントプログラムが動いているのか、 DB サーバ側から調べる必要があります。 しかしながら、TCP 接続ではサーバ側は送られてきた パケットを受け取るだけなので、 そのパケットを誰が送信したかまでは関知しません。 そこで、通信相手が誰なのか調べる方法を定めたのが、 RFC1413 で提案された IDENT プロトコルです。 IDENT プロトコルは、 受け取った TCP パケットに記録されている 送信元の IP アドレスとポート番号を手がかりに、 相手が誰かクライアント側へ問い合わせます。

IDENT プロトコルは、あまり使われなくなって久しいので、 まず簡単に紹介しましょう。

ホスト CLIENT からホスト SERVER の 12345番ポートへアクセスした 場合について考えます。 その接続状況は次のように netstat コマンドなどで確認できて、

SERVER % netstat
Proto Recv-Q Send-Q  Local Address  Foreign Address  State
tcp        0      0  SERVER:12345   CLIENT:45486     ESTABLISHED

この場合だと、CLIENT の 45486番ポートから SERVER の 12345番ポートへの TCP 接続が確立している (ESTABLISHED) ことが分かります。

このとき、SERVER は CLIENT に IDENT 問合せをすることによって、 CLIENT のどのユーザが TCP 接続の相手か調べることができます。

SERVER % telnet CLIENT 113
Connected to CLIENT.
45486,12345                                 … (1)
45486 , 12345 : USERID : OTHER :sengoku     … (2)
Connection closed by foreign host.

(1) が SERVER から CLIENT への問合せで、 送受信双方のポート番号の対を送信しています。 これに対し、(2) が CLIENT から SERVER への応答で、 TCP 接続の相手が「sengoku」であることが分かりました。

このように、通信相手が誰か手軽に確認できる便利なプロトコルなのですが、 相手ホストが信用できなければ当然 IDENT 応答も信じることはできません。 不特定多数のホストからの通信を受け付ける場合は、 IDENT 問合せを行なっても「正直な」応答が返ってくるとは期待できないわけで、 少なくともインターネット上ではあまり使われなくなったようです。

しかし データセンタのラック内のサーバであれば、 当然管理者が決まっているでしょうから、 全てのサーバで正しく IDENT 応答を返すように徹底することは容易です。 したがって、 IDENT プロトコルを使った入口規制を実施することができます。

まず DB サーバを、UNIX ドメインソケットでのみアクセスを受け付ける ように設定します。 このソケットは、local ユーザが勝手にアクセスしたりしないよう、 DB サーバを実行するユーザ権限でのみ読み書きできるように 設定しておくとよいでしょう。

次に、特定のポートで listen し、接続を受け付けたら この UNIX ドメインソケットへ中継するプログラムを、 DB サーバを実行するユーザと同じユーザ権限で走らせます。 この中継プログラムは、 中継する際に接続元ホストに対して IDENT 問合せを行ない、 IDENT 応答で得たユーザ名と、 通信を監視することによって得られた DB ユーザ名が 一致しない場合は通信を遮断するというわけです。

このような仕掛けにより、 クライアント側のユーザは、 仕掛けを意識することなく DB サーバにアクセスすることができます。 そして、 何かのはずみに別の DBユーザのパスワードを知り、 その DBユーザになりすましてアクセスしようとしても 通信は遮断されます。

Filed under: システム構築・運用 — hiroaki_sengoku @ 12:25

No Comments »

No comments yet.

RSS feed for comments on this post.

Leave a comment