2006年04月17日

Apache のログのアクセス権の分離

はてなブックマークに登録

DSAS の特徴の一つに,複数のサービスを同じサーバ群で運用する,というのがあります.DSAS は Web サーバだけでも数台〜数十台で構成されますが,これらのサーバは同時に複数のコンテンツのサービスを受け持っています.つまり,A のサーバでは a と b のサービスを動かし,B のサーバでは b と c のサービスを動かす,といった具合です.こうすることで,コンテンツ毎に異なる負荷傾向をならすことができ,突発的な負荷の増大に対しても,速やかな処理能力の増強が可能になります.ただし,問題が一つあります.

ログには,時として個人情報につながる情報が記録されます.ですので,コンテンツのログは担当者以外が読めてはいけません.一方,通常はコンテンツ a と b ではその担当者が,そして時には担当部署もが異なります.つまり,コンテンツ a の担当者が,b のログを読めるのは読めてはいけない,ということです.

一般的な UNIX では,ファイルへのアクセスは,そのファイルの所有者,グループ,それ以外,の三種類のレベルでのみ区別できます.この3種の権限分離でコンテンツ a の担当者からコンテンツ b のログを守るにはどうすれば良いでしょうか.簡単な方法の一つは,次のようになります.

まず前提として,コンテンツ a とコンテンツ b の運用のためのユーザ user_auser_b があります.これらはそれぞれ group_agroup_b というグループに属しています.それぞれのグループに属するユーザは,user_auser_b のみです.
コンテンツ a と b のログのためのディレクトリを,それぞれ以下の所有者/グループとアクセス権でもって作成します.

 drwxr-x---  apache   gourp_a    log_a
drwxr-x--- apache gourp_b log_b

apache というのは,Apache の実行ユーザです.即ち,log_a のディレクトリにあるファイルは apache ユーザは読み書きできて,group_a に属するユーザ = user_a のみが読むことができます.log_b のディレクトリも同じです."それ以外"のユーザに対するアクセス権は --- になっていますから,user_alog_b のディレクトリにあるファイルを読むことはできなくなります.

さて,これで一見目的を達成できたように見えます.実際のところ,コンテンツが完全に静的なものであれば,これでも問題ありません.
しかしながら,大半のコンテンツは動的な要素を含んでいます.即ちプログラムが動作します.そのプログラムは 例えば PHP や CGI であれば apache ユーザで動作します.(CGI の場合,suexec を使えば apache 以外のユーザで動作しますが,それは別の問題を含んでいるので使いません.)そしてそのプログラムを管理しているのはコンテンツの担当者,即ち user_auser_bです.つまり,user_auser_blog_blog_a のディレクトリを読むプログラムを,Apache = apache ユーザに実行させることができるのです.

では,apache ユーザが読めないようにするにはどうすれば良いでしょうか.単純に,apache ユーザの権限から読出し権限 r を落としてみると良いと思うかもしれません.こんな風に

 d-wxr-x---  apache   gourp_a    log_a
d-wxr-x--- apache gourp_b log_b

けれども,log_alog_b の所有者は依然として apache です.とうことは,apache ユーザはこのディレクトリの権限を自由に変更できる,ということです.
では,このディレクトリの所有者とグループを逆転させてみるとどうでしょうか.即ち
 drwx-wx---  user_a  httpd      log_a
drwx-wx--- user_b httpd log_b

(httpd グループは,apache ユーザのみが属するグループとします.)
これらのディレクトリはディレクトリのグループが httpd になっていて,グループに対する権限として書き込み権が与えられていますので,apache ユーザでのログを出力することができます.且つ,これらのディレクトリは apache ユーザの持ち物では無いので,CGI や PHP から権限を変更される心配もありません.しかしながら,アクセスを禁止したいのはこれらのディレクトリ自体ではなくて,このディレクトリの下にできるログファイルです.そしてそのログファイルを作成するのは apache ユーザですので,ログが作られるディレクトリやログファイル自体の権限をいくら工夫しようが,依然として apache ユーザはそれを読むことができるのです.ということで,apache ユーザがログを書き出す限りは,CGI や PHP を経由したログの読み出しを止めることはできそうにありません.

問題は apache ユーザがログファイルを作成するから発生することがわかりました.ですので今回の答えは,ログファイルへの出力は apache ユーザ以外が行えばいい,ということになります.方法はいくつかありますが,DSAS で採用しているのは次の方法です.

Apache のログ出力は,CustomLog ディレクティブで設定します.このディレクティブではログの出力先として,単純なファイルの指定の他に,外部のプログラムを指定することができます.ログの出力先としてプログラムが指定された場合,Apache はログをそのプログラムの標準入力へと書き出します.このプログラムを実行するユーザを,apache 以外にしてやれば,問題は解決できます.プログラムを,起動したユーザ以外のユーザの権限で動作せる方法はいくつかありますが,DSAS では次の用に設定しています.

 CustomLog "|/bin/su log -c rotatelogs log_a/access_log.%Y-%m-%d 86400 +540" combine

(実際は,rotatelogs や ログディレクトリの指定は絶対パスで行います.)
ここで使用している rotatelogs は Apache に付属しているログ書き出し用の外部プログラムで,このような形で引数を与えると,1日ごとにログのローテートを自動的にしてくれます.この rotatelogssu コマンドを使用してログ管理用のユーザ log にて起動し,それぞれのコンテンツのログを出力しています.この場合の log_a のディレクトリの権限は次のようになります.
 drwxr-x---  log  group_a    log_a

このディレクトリ及び作成されるログファイルのオーナは,apache ユーザとは関係のないユーザですので,CGI や PHP から触ることはでき無くなります.
klab_gijutsu2 at 01:55│Comments(0)TrackBack(0)

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント