いますぐ実践! Linuxシステム管理

[バックナンバーのトップへ] [Linux システム管理のトップへ]


いますぐ実践! Linux システム管理 / Vol.180 / 読者数:1526名

こんばんは、うすだです。

4月に注文した子どものベッドが昨日(土曜日)届きましたので、 昨日今日と休日を使って、模様替えを実施しております。

いままで、各人の所有物が、無秩序かつ無造作に、各所に点在していたのですが、 これを機に、はっきり分けようということになりました。

それはよいのですが、とりあえずクローゼットの物を出して見たところ、 物が多すぎてどのように処理すればよいかわからず、 信号が故障している交差点のように、収拾がつかなくなっております。

というわけで、日曜日の22時現在、まだ廊下に物が溢れかえっています。
(たとえば玄関は、物が積み上がっていて出入りできなくなっています。)

こんな状態で、片付けの手伝いをせずメルマガを書いていていいのだろうか、 この惨状を放置して明日会社へ行っていいのだろうか、という疑問を抱きつつも、 メルマガをすっぽかすわけにいかないため、後ろめたさ満開で書いております。

明日起きたら、 小人さんがきれいさっぱり片付けてくれやしないかと幻想を思い浮かべながら、 今回もはりきってまいりたいと思います。

今回のお題 - テンポラリファイルに注意する

前回は、シェルスクリプトを記述する際に注意すべき点について、簡単にご紹介しました。

Vol.179 - セキュリティを考慮してシェルスクリプトを書く
http://www.usupi.org/sysad/179.html

しかし、肝心のテンポラリファイルにたどり着けませんでした。
ですので、今回は、テンポラリファイルを作成する際に注意すべき点を、 ご紹介したいと思います。

テンポラリファイルだけで間が持つのか、ハラハラしながらご覧いただけますと幸いです。

(いまさらですが)テンポラリファイルとは?

スクリプトでは複数の処理を行いますので、 処理の途中で何らかのデータが生成されるように思います。

このようなデータを、次に処理するコマンドへ渡すときには、引数に指定したり、 パイプで渡すなどして、極力残さないようにしたいところです。

しかし、 コマンドに複数のデータ(たとえば処理内容とデータなど)を渡す必要があるときや、 複数のコマンドの出力結果をまとめる必要のあるときなど、 ファイルに出力せざるをえないケースが生じます。

そのようなときのために、スクリプトの実行中にだけ生成される刹那的なファイルが、 テンポラリファイルです。

たとえば、複数のコマンドの実行結果をまとめてメールで通知したい場合には、 以下のように、 テンポラリファイル(下記スクリプトの TMPFILE)を利用してメールを送信します。

  #!/bin/sh
  PATH=/sbin:/usr/sbin:/bin:/usr/bin
  export PATH
  TMPFILE=/tmp/this_is_dangerous_filename
  echo "*** syslog" > $TMPFILE
  grep ntp /var/log/messages >> $TMPFILE
  echo "*** peers" >> $TMPFILE
  ntpq -c peers >> $TMPFILE
  Mail -s "[ntp] status" root < $TMPFILE
  rm -f $TMPFILE

ですが、上記の場合、テンポラリファイルと同名のシンボリックリンクがありますと、 思わぬファイルに上書きしてしまう恐れがあります。
(…という話は、前回ご紹介しております。)

じゃあ、シンボリックリンクでないことをチェックすればOK! と言いたいところですが、チェックの仕方によっては隙ができてしまいます。
(詳しくは、↓もうちょっと下にある宿題の答えをご覧ください。)

テンポラリファイルを安全に作成する

というわけで、テンポラリファイルを安全に作るにはどうすればよいかと言いますと、 うってつけのコマンドが存在します。

それは、mktemp というコマンドです。
mktempコマンドは、指定したテンプレートに従ったファイルを作成して、 そのファイル名を出力します。

たとえば、テンプレートに /tmp/foo-XXXXX を指定しますと、 X の部分をランダムな文字(アルファベットもしくは数字) に置換したファイルを生成します。

  $ mktemp /tmp/foo-XXXXX
  /tmp/foo-EBzIb

もちろん、生成されたファイルは、シンボリックリンクだったりすることはなく、 安全に生成されたファイルです。

ですので、先の危険なスクリプトは、 たとえば以下のように書き換えるとやや安心できます。

  #!/bin/sh
  PATH=/sbin:/usr/sbin:/bin:/usr/bin
  export PATH
  TMPFILE=`mktemp /tmp/this_is_maybe_safe_XXXXXXXX`
  echo "*** syslog" > $TMPFILE
  grep ntp /var/log/messages >> $TMPFILE
  echo "*** peers" >> $TMPFILE
  ntpq -c peers >> $TMPFILE
  Mail -s "[ntp] status" root < $TMPFILE
  rm -f $TMPFILE

 

ちなみに、mktemp() という関数が libc にありますが、 こちらは危険なため使ってはいけないことになっています。

というのも、mktemp() はファイル名を戻すだけですので、 その後 open() システムコールなどでファイルを作るまでの間、 隙ができてしまいます。

ですので、C言語などでテンポラリファイルを作る際には、 open も行ってくれる mkstemp() などの関数を使う必要があります。

テンポラリファイルのパーミッションに注意する

さて、テンポラリファイルを安全に作るということの他にも、 気をつけるべきことがあります。

それは、テンポラリファイルのパーミッションです。

たとえば、root の権限で、 /etc/shadow の一部をテンポラリファイルに記録する必要が生じたとします。
しかし、そのテンポラリファイルのパーミッションが、 root 以外のヒトも読めるようになっていますと、 テンポラリファイルが生成される一瞬を狙って、情報が読まれてしまうかもしれません。

そんなときには、シェルの組み込みコマンドである umask を使用して、 生成されるファイルのパーミッションをあらかじめ設定しておきます。

umask の引数には、chmod コマンドと同じ形式のモードを指定します。
ただ、umask の場合、引数はマスクになります。
つまり、ファイルを生成する際、許可したくないビットに 1 を指定しておきます。
…といってもわかりにくいと思いますので、以下に例を示します。

  $ umask
  0022
  $ touch /tmp/foo
  $ ls -l /tmp/foo
  -rw-r--r-- 1 usu adm 0 2010-06-07 00:38 /tmp/foo

最初、引数なしで umask を実行しています。引数なしで実行しますと、 現在のマスク値を出力してくれます。
この場合、マスク値は8進数で 22 ですので、 同じグループの人とと赤の他人な人は、書き込みが許可されません。 実際にファイルを生成しますと、所有者のみ書き込みが許されたモードになっています。

  $ umask 077
  $ touch /tmp/bar
  $ ls -l /tmp/bar
  -rw------- 1 usu adm 0 2010-06-07 00:39 /tmp/bar

こちらは、umask の引数に、8進数で 77 を指定しています。
これは、同じグループの人も他人も読み書き実行すべて許可されないというマスクです。 ですので、実際にファイルを生成しますと、 所有者のみが読み書きできるモードになっています。

 

幸い、mktemp コマンドで作成したファイルは、umask を設定していない場合でも、 自分自身しか読み書きできないようにしてくれます。

  $ mktemp
  /tmp/tmp.pb6w1jzaTT
  $ ls -l /tmp/tmp.pb6w1jzaTT 
  -rw------- 1 usu adm 0 2010-06-06 23:42 /tmp/tmp.pb6w1jzaTT

じゃあ別に気にしなくていいじゃん、と突っ込まれてしまいそうですが、 テンポラリファイルに限らず、 パーミッションには常に気をつけるべきだと解釈していただければ、 微かな意義が見出せるのでは…と思います。

おわりに

以上、シェルスクリプトでテンポラリファイルを扱う際に気をつけるべきことを、 ご紹介しました。

シェルに限らず、スクリプトを書く機会は、少なからずあると思います。
そんなときには、前回と今回のことを、ちらっとでも思い出していただけますと、 幸いです。

また、シェル以外のスクリプトを書く際には、 なるべく自由度の低いほうを選択するようにしてください。

たとえば、なるべく厳格なモードで実行したり、機能の低い関数を選んで使う、 といったことです。
(たとえば Perl の場合、taint mode で実行(perl -T)したり、 open ではなく sysopen を使う、といったことが推奨されています。)

宿題の答え

前回の宿題は、

  隙のあるスクリプトを作成して、一瞬の隙を突いてみましょう。

でした。

元ネタは、前回の本題のシンボリックリンクのところですが、 書いてある通りそのままでは shadow ファイルが壊れてしまいます。ですので、 擬似的に試したいと思います。

root 権限で実行される不注意なシェルスクリプトが、出力するログを、 ここでは /tmp/careless_log とします。
そして、上記ログではなく、/tmp/real_file というファイルに上書きをされるよう、 仕込んでみたいと思います。

まず、隙のある不注意なシェルスクリプトを、以下に示します。

  #!/bin/sh
  LOGFILE=/tmp/careless_log
  [ -f $LOGFILE ] && mv -f $LOGFILE ${LOGFILE}.0
  echo "`date` : done" > $LOGFILE

3行目で、古いログがあれば、バックアップ(/tmp/careless_log.0)として保存し、 4行目でログを出力しています。

このスクリプトを、仮に careless.sh という名前で保存したら、 ログファイルを生成しておくため、1度実行しておいてください。

  $ chmod +x careless.sh
  $ ./careless.sh
  $ ls -l /tmp/careless_log*
  -rw-r--r-- 1 usu adm 50 2010-05-19 23:09 /tmp/careless_log

次に、一瞬の隙を突く、 ひたすらシンボリックリンクを作ろうとするだけのシェルスクリプトを、 以下に示します。

  #!/bin/sh
  LINK_SRC=/tmp/real_file
  LINK_DST=/tmp/careless_log
  while [ 1 ]; do
      ln -s $LINK_SRC $LINK_DST > /dev/null 2>&1
  done

こちらは、ln コマンドでシンボリックリンクを永遠に作成し続けます。
これを、evil.sh という名前で保存したら、バックグラウンドで実行してください。

  $ chmod +x evil.sh
  $ ./evil.sh &
  [1] PID

そして、先ほどの careless.sh を実行しますと…。

  $ ./careless.sh
  $ ls -l /tmp/careless_log* /tmp/real_file
  lrwxrwxrwx 1 usu adm 14 2010-05-19 23:12 /tmp/careless_log -> \
  /tmp/real_file
  -rw-r--r-- 1 usu adm 50 2010-05-19 23:09 /tmp/careless_log.0
  -rw-r--r-- 1 usu adm 50 2010-05-19 23:12 /tmp/real_file

…ああ、いきなり成功してしまいました。
(シンボリックリンクである careless_log に対してログが書き込まれました。)

こちらの環境では、5回ほど試して、いずれも上記のようになりました。
ですが、状況によってはうまくいかないかもしれませんので、 そんなときは何度か試してみてください。

そして、やり終えたら、以下のように後始末をしておきましょう。

  $ kill %1
  $ rm /tmp/careless_log* /tmp/real_file

今回の宿題

今回の宿題は、

  mktempコマンドが安全であることを確認してみましょう。

です。

とはいえ、ファイル名を推測しつつ一瞬の隙を突く、 というのはハードルが高すぎるように思います。

ですので、あらかじめ、可能性のあるファイル名のシンボリックリンクを作成しておき、 mktemp を実行したときに、ファイル名がかぶらないことを確認したいと思います。

あとがき

セキュリティに関するスキルは、経験すればたくさん得られますが、 経験してから知っていては遅いというジレンマもあるように思います。
(知らなかったことを経験するということは、不正侵入や情報漏洩などを許してしまう、 ということになってしまいますよね…。)

ですので、セキュリティの本を読んで勉強することがメインになると思いますが、 そうしますと、今度は、 本を読むだけでは実感がわかないという問題が生じるのではないかと思います。

しかし、そんなジレンマを払拭する、実際に経験して学べるサイトというものが、 世の中には存在するようです。

Web Application Exploits and Defences
http://jarlsberg.appspot.com/

おお、英語の情報も仕入れているのかと思われた貴兄がいらっしゃるかもしれませんが、 もちろん、直接仕入れたわけではございません。

攻守で学ぶWebセキュリティ実践チュートリアル「Jarlsberg」
http://journal.mycom.co.jp/articles/2010/05/28/jarlsberg/?rt=em&t=pl&n=0119

…はい、上記の通り、マイコミジャーナルから得た情報です。
このサイトでは、脆弱性のあるサービス(もちろん確認するだけ用です)を提供しており、 こうするとヤバいよということを教えてくれます。

具体的には、各脆弱性について、まず Hint にヒントが、 そして Exploit and Fix に答えと修正方法が書かれています。
これらは、クリックしないと中を参照できないようになっていますので、 自分で答えを考えて確かめてから、実践することができます。

わたしはまだ XSS(Cross-Site Scripting)しか試せていませんが、 溢れた物を片付けることができたら、残りを試してみたいと思っています。

 

ところで、さっきリビングに行ったら、よめが、 物に埋もれながら TV を見ていました。

いかなるときでも、あせらず冷静に判断できるということは、 すばらしいことだと思います。わたしも、あせらないで当メルマガ (と某雑誌の原稿)を仕上げたいと思います。
(ちなみに、TVを見ていたのは一瞬だけでした。わたしの感じている後ろめたさは、 さらに強まったような気がいたします…。)

 

今回も、ここまで読んでいただき、誠にありがとうございました。
次回は、6月20日(日) の未明にお会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」- これから栗の絵を考えます…夜は長いなぁ…。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://usupi.org/k/ (モバイル栗日記)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本