Practicalなシェルスクリプトの解説書 (α版)

[ Prev | Top | Next ]

ケース2:ファイルパーミッションの管理

一般的なセキュリティを確保するためのルールの中には「権限を持つユーザーにのみ必要な情報を提供する」という考え方があります。 サーバー自体にログインさせないという選択肢もありますが、セキュリティ上の問題の多くは内部の関係者から発生しているのが実情です。 システム管理者自身が責任を取らされる状況を回避するためにも、システムに妥当なルールを設ける事は必要です。

その他に複数のアプリケーションが連携する場合に、CSVファイルなどの形式で相手側アプリケーションのディレクトリにコピーするスクリプトを準備する場合があるかもしれません。 アプリケーション開発者からファイルを置いたのに参照することができないという問い合せを受けたこともあります。 開発者とはいってもWindows上での経験が主で、UNIX系OSでの経験が不足している状況にもよく遭遇します。

ログファイルを圧縮する

システムのログファイルであれば "logrotate" を使えば解決しそうですが、 自作のアプリケーションが出力したログファイルを圧縮するスクリプトを作成してみました。

#!/bin/bash
BASEDIR="$(dirname $0)"
find "${BASEDIR}/../logs/" -type f -name '*.log' | while read file
do
  newlog="${file}.$(date +%Y%m%d.%H%M)"
  mv "${file}" "${newlog}"
  touch "${file}"
  gzip "${newlog}"
done

このスクリプトはメンテナンスのために、サーバープロセスが日に1回定期的に実行するようになりました。

遭遇する問題

障害が発生したのでログファイルを解析する必要があり、サーバーにログインし昨日のログファイルを確認しようとしました。

$ cd logs
$ gzip -cd system.log.20091212.1234.gz
gzip: system.log.20091212.1234.gz: Permission denied

確認したところ "system.log.20091212.1234.gz" の権限が"root"ユーザーのみが確認できる状態でした。

-rw------- 1 root www-admin 22 2009-12-12 12:35 system.log.20091212.1234.gz

考えられる対応

この状況の対策を2つ考えてみます。1つはrootユーザーになりファイルを確認します。もう一つは生成されるログファイル全体に読み取り権限を付与します。

解決案の1つ目、rootユーザーになる場合、 "su" を使うか、最近では "sudo" が好まれます。 これは "sudo" がrootユーザーのパスワードを教えることなく、root権限でコマンドを実行できるためです。 また実行できるコマンドの制限やログの取得もできるため、不注意によるコマンドの打ち間違いを防ぐといった事はできます。

もう一方のログファイルに読み取り権限を与える方法は、ファイルが作成される前後のどちらかで行なう事ができます。 今回は迅速なログファイルの確認を優先する考えから、ファイルが作成されるタイミングで -rw-r--r-- となる権限を与える方法を考える事にします。

umask内部コマンドの使い方

環境変数に対する説明のところで、実行するプログラムに引き継がれるという説明をしました。 シェルスクリプトもシェルやcrontabから起動されるプログラムですから、実行元の環境を引き継いだ上に実行されます。 新規に作成されるファイルの権限を -rw-r--r---rw------- に変更する仕組みが "umask" です。

シェル上で "umask" を実行すると、現在の設定値が表示されます。

$ umask
0022

設定値が"0022"の場合には、新規作成ファイルの権限は"0666"から引き算された権限、 -rw-r--r-- になります。 よりセキュリティを高めたい場合には"0066"を設定し、必要に応じて明示的に許可を出さない限りは、第三者がファイルを読めないようにしてしまう事ができます。

今回問題になったスクリプトでは、設定値が"0066"だったためにこのような問題が起りました。 修正は先頭部分で1行追加し、以下のようになりました。

#!/bin/bash
umask 022
BASEDIR="$(dirname $0)"
...

セキュリティの観点だけをみれば、 umask 066 をデフォルトで適用し、必要に応じて許可を出す形が良いと思います。 いずれにしてもシェルスクリプトの中では目的に応じて "umask" を適切に設定する事をお勧めします。

一般的なファイル権限

UNIX系OSで使われるファイルのセキュリティには次の2種類があります。

1番目は古典的なUNIXから存在し、ファイル権限の管理の仕組みとして一般的なものです。 シンプルですが、その分 "find" コマンドの "-perm" オプションで確認する事も容易です。

2番目のACLはWindowsのNTFSでも見られますが、一般的なUNIXでも拡張属性を利用した機能として最近では一般的になりつつあります。 ACLは適切な権限がファイルに付与されている事を確認する仕組みが一般的ではなく、「ユーザーAがファイルFを参照できない事」を後から証明しようとすると、ACLに登録されているグループを総当たりで調べるなど、使い方によっては自動化するためにちょっとした規模のスクリプトを作成する必要がでてきます。

ACLは便利ですが、セキュリティのルールとして「定期的に適切な権限が付与されているか検証する」といった項目があった場合には、少し混乱を招くでしょう。 ルールを設定する事も管理者の仕事ですが、それが検証可能かどうかも考えてみてください。 あまり真に受けずになぜそういったルールが存在するのか、その理由を考えてみると妥当な落とし所に落ち着くと思います。


Created: 2009-12-12, Last modified: 2010-03-19

2009,2010 © Yasuhiro ABE <yasu@yasundial.org>

Valid XHTML + RDFa RDFa it (RDF/XML)!

正当なCSSです!

Creative Commons License www.yasundial.org by Yasuhiro ABE is licensed under a Creative Commons Attribution 2.1 Japan License. Permissions beyond the scope of this license may be available at http://www.yasundial.org/info/license.html.