サーバー管理者入門
■UNIXサーバーの状態を調べるためのコマンドたち
●psコマンド
psコマンドを使って、立ち上がっているプロセスを調べることができます。
[補講]Windowsの場合はタスクマネージャでモニタすることができる。
Wormやバックドアを発見することが可能です。ただし、アタッカーも巧妙にpsコマンドを改竄したものをインストールしていくことがあります。そこで、TripwireやMD5チェックサムが役に立つでしょう。
●vmstatコマンド
vmstatコマンドを使って、メモリの使用量を調べることができます。avmはアクティブになっている仮想メモリの容量、freはフリーリストの容量です。
procsのwが0でないときは、プロセスでディスクスワップが起きていることを示しています。0になっていなければ、メモリの増設を検討するべきです。しかし、運用中の場合はプロセスが過剰に起動していることもあります。
また、徐々にfreが減少していき、wが0でなくなった場合は、プログラムでメモリリークが発生しているかプロセスが壊れている可能性があります。この場合は、動作しているプログラムをチェックするか、サーバーを再起動してプロセスを立ち上げなおすなどの対応を取る必要があります。
●dfコマンド、duコマンド
dfコマンドを使って、ディスク残量を調べることができます。
MRTGで表示されるディスク容量のグラフが変化した場合は、dfコマンドで調査します。さらに大きなサイズのファイルを探すにはduコマンドを使います。
●iostatコマンド
iostatコマンドは、ディスクアクセスのデータを調べることができます。
●dmesgコマンド
dmesgコマンドは、ディスクの損傷の有無を調べることができます。例えば、「adX: HARD READ ERROR
blk# XXXXXXX status=XX
error=XX」というメッセージ行が表示されたら、ディスクが物理的に故障している可能性があります。また、ディスクに不具合が見つかると、/var/log/messagesにエラーメッセージが記録されることもあります。なぜならば、ディスクの不具合はカーネルのエラーとして検出されるからです。
# dmesg | grep "READ ERROR"
# cat /var/log/messages | grep "READ ERROR"
IDEのディスクで運営されているWebサーバーでは、このメッセージが検出されるようになると、CPUのロードアベレージが上がり、2日〜1週間後にディスクがクラッシュしてしまいシステムが停止する可能性があります。
毎日サーバーにログインしてdmesgコマンドを実行するのは面倒なので、cronで1日1回実行されるようにしておくとよいでしょう。
もし、ディスクが損傷していることが判明したら、新たなシステムをインストールしたHDDを用意します。
1:マシンを停止します。
2:新しいHDDを繋げてそこから立ち上げます。その際、障害があったディスクも接続しておきます。
3:障害ディスクをマウントする。
4:損傷を受けてないな復旧できる限りのファイルを新しいシステムのHDDの方へコピーします。
5:もし、読み込めないファイルがあったらバックアップから復旧することになります。
RAID1を構築していればもっと楽に復旧できます。PCIカード型RAIDコントローラを使うと安上がりですが、お金に余裕があればホットスワップに対応しているIDE接続型RAIDユニットを購入した方がよいかもしれません。
●fsckコマンド
fsckコマンドは、ディレクトリやファイルシステムの不整合を調査するためのコマンドです。このコマンドにより、対話的にチェックできます。
このコマンドを実行するときは、シングルユーザーモードで行うことをオススメします。なぜならば、他のプロセスがファイルシステムの書き込み中になってしまうと、不整合と認知してしまうからです。
●不完全なウェブコンテンツを探す
Apacheのエラーログから、リンク切れを調べることができます。
# more error_log
Perl version
5.003-03は、上限を設けると、上限を超えた時点で「panic:POPSTACK」というメッセージをエラーログに大量に生成することがあります。このエラーログによってオーバーフローしないように注意してください。
CGIがどうしても重くて困るという場合は、CGIプロセスの分離という方法があります。これを実現化させるには、リバースプロキシを用います。別のサーバーを用意してCGIプログラムだけを別に実行させてWebサーバーの重さを回避する方法のことです。
1:www.test.jpというWebサーバーとは別に、cgi.test.jpというサーバーを用意する。cgi.test.jpには、Apache、Perlをインストールしておく。
2:cgi.test.jpのhttpd.confファイルを編集して、http://cgi.test.jp/cgi-bin/以下をアクセス可能にする。
3:www.test.jp/cgi-bin/以下の環境をそのままcgi.test.jp/cgi-bin/以下にコピーする。CGIの実行ファイルをコピーするだけでなく、実行権限を忘れずに設定してください。
4:www.test.jpのhttpd.confファイルのserver-statusの部分を設定する。
5:cgi.test.jpはインターネットに直接公開されていなくても、www.test.jpを通じたProxyサーバーによってアクセス可能です。よって、セキュリティを確保するためには、cgi-binのアクセスはwww.test.jpからのみに制限する必要があります。cgi-binの.htaccessファイルにIPアドレス制限を施すために、次のように記述しておく。
-----
Order Deny,Allow
Satisfy all
Deny from all
Allow from .test.jp
-----
6:これで、完了です。
●システムコマンドの情報を記録する
例:FreeBSDの場合
ディレクトリ/bin、/usr/binにシステムで使用されるコマンドが格納されているので、次のコマンドで記録(システムコマンドの最終アクセス日、修正日、作成日)を取っておくとよいでしょう。
# ls alRu /usr/bin > /floppy/access-time.log
# ls alRc /usr/bin > /floppy/modify-time.log
# ls alR /usr/bin > /floppy/create-time.log
このようにFDに記録をとっておけば、アタッカーによるログ改竄の際に逃れることができます。
■UNIXサーバーアクセスを調査するコマンドたち
●wコマンド
wコマンドは、サーバーのCPU負荷であるロードアベレージ、ログインしているユーザーをチェックすることができます。load
averagesは、CPUのプロセス処理に待ちが出ると、プロセス切り替えにCPUリソースが使われて平均値が急騰してしまう傾向があります。PCサーバーの場合は、通常時は1.00以下で運用することが望ましいです。
●topコマンド
wコマンドでload
averagesの値が高いことが判明したら、次はtopコマンドを使いCPUの使用率をチェックします。
特にユーザーが設置したCGIがCPUに負荷をかけていることがあります。ただし、topコマンドだけではCGIのPerlプログラムを特定することができません。そこで、次のように入力します。
# ps axu | grep perl
このコマンドの結果で滞留しているPerlプログラムが判明します。プロセスIDも分かるので、killコマンドを使い、プロセスを停止します。もちろん、ユーザーに問題となっているCGIを停止した旨をメールで報告しておきましょう。
●psコマンド
ps axu|grep httpd|wc -lと入力して、Apacheのプロセス数が確認できます。
httpd.confのMaxClients(同時に接続できるクライアントPC数の上限)に比べて余裕があるかどうかをモニタします。
[補講]ApacheはデフォルトでMaxClientsは150です。詳細は特別講座<Webサーバー編>>Apacheのカスタマイズを参照せよ。
●netstatコマンド
Apacheのデーモンhttpdが子プロセスを大量に生成している場合には、特定のIPアドレスからのアタックがないかを調査した方がよい。ここでいうアタックはApacheのプロセスからの応答が終わらないうちに、次々にアクセスしてコネクションをはかろうとすることです。このコネクションに対して、Apache側は子プロセスを生成して、つまりプロセス数を増やして対応します。しかし、Apacheは生成する子プロセス数には上限があるので、最終的に新規コネクションがいずれははれなくなり、正規(アタックとは全く関係ない人)がページを閲覧できなくなってしまいます。
netstatコマンドを使えば、特定のIPアドレスからコネクションが多いかどうかを調べることができます。
# netstat -an | cut -c 45-66 | cut -f 1-4 -d . | sort | uniq -c
| sort -r
もし、特定のIPアドレス(aaa.aaa.aaa.aaa)からのアクセスが急騰しているのを発見して、対処したいときは次のようにすればよい。
# route add net aaa.aaa.aaa.aaa 127.0.0.1 blackhole
このコマンドで、aaa.aaa.aaa.aaaへの通信宛先をサーバー自身(127.0.0.1)に変更します。これで受信サーバーが送信側に送る送信許可を示すACKビットが立っているパケットをaaa.aaa.aaa.aaaに返送せずに、コマンド応答もサーバー自身から出ないようにできる。ただし、routeコマンドの実行はサーバーが再起動されれば解除される。もし常時アクセスを拒否したければ/usr/local/etc/rc.dの中にシェルスクリプトを作成して、サーバーが立ち上がるたびに、起動するように設定しておくとよいだろう。
[補講]Apacheはデフォルトインストールだと、ポート管理は自分で行いinetdを使わないのでこのような対処方法ができる。よって、ポート管理でinetdを利用しているsendmailやftpでの対処方法は異なる。
■Webサーバーのアクセス数を調べる
例えば、10月10日のアクセス数を調べるには次のように入力すればよい。
# grep 10\/Oct access_log | grep html | wc -l
■スパムメールの踏み台にされていないかを調べる
●tail -f
Spammerに踏み台にされると、大量のメールを送信するので、メールサーバーの負荷が高くなります。
よって、メールサーバーの管理者はスパムの踏み台にされていないかどうかをチェックする必要があります。
# tail -f /var/log/maillog
「tail
-f」コマンドを実行して、ファイルが動的に書き込まれる場合、追加分を表示します。「to=」のところに馴染みの無いアカウントが出てきたら要注意です。社員がサーバーを不正利用しているか、メールサーバーが誰かに不正中継されていると考えられます。また、「from=<>」となっていれば、送信元を詐称している意図が画されていることもあります。ただし、設定によっては、システムのエラー情報を「from=<>」という形で、ルートアカウント宛てに送信することがあるので一概には言えません。
もし見つかったら、特別講座<メールサーバー編>>スパムメールの拒否を参照して対策をとる必要がある。
●MRTGで発見する
スパムメールで急激にメール送信数が増えると、sendmailが子プロセスを生成します。よって、MRTGでsendmailプロセスの数をモニタしていれば発見できることがあります。
■サーバー管理表を作成する
ノートで次のようなサーバー管理表を作成しておくと、いざというときに便利です。
ホスト名
|
IPアドレス
|
ロケーション
|
OS
|
バージョン
|
サービス
|
バージョン
|
www.akademeia.info
|
xxx.xxx.xxx.xxx
|
ラック番号XX
|
Linux
|
XX
|
Apache
|
x.x.x
|
php
|
x.x.x
|
qmail
|
x.x.x
|
■事例1
昔々、あるところにサーバー管理者Aさんがいました。
彼は社内でPCにちょっと詳しいというだけで、やりたくもないサーバー管理者という仕事をやらされる羽目になりました。先日、上司はコンピュータに関して何も分かっていないのに、「これからの時代はITだ!ホームページというやつ作ってもらえないか? なんとか頼むよ」と言われて、渋々引き受けたのでした。
プログラミングに関しては仕事でも使っているので、ある程度できましたが、ネットワークに関してはサッパリでした。家ではADSLでインターネットに繋いで夜中チャットで遊んだり、WinMXで違法なソフトウェアをダウンロードして一喜一憂する生活をしていただけです。
そこで、とりあえずGoogleで検索して少し調べてみると、ホームページを公開するにはWebサーバーというものが必要だと分かりました。レンタルサーバーを借りるという手もありますが、ちょっと背伸びして会社の専用線にWebサーバーを設置することに決めました。そのWebサーバーのOSを決定する必要があります。彼はWindowsしか触ったことが無かったので、UNIXは選択から外しました。彼は最近のLinuxブームをわき目で見て、「負け組みOSは精々がんばれよ」と心で思っていたのです。次に、httpdを用意しなければならないことは先ほどの検索で知っていました。Windowsで動くhttpdは様々存在しますが、彼はIISというhttpdを選択しました。
IISのインストールと設定は思ったよりも簡単で、無事会社のホームページを公開することが出来ました。
そんなある日、何気なく会社のトップページにアクセスしたら、いつものWebページではなく、次のような白バックに赤文字のWebページが表示されました。

「何だ? ハックド・バイ・イプシロン・・・? イプシロンによってハックされた? ハックされた!? 」
そうです。IISのhotfix(修正パッチのようなものと思ってもらってよい)を適応していなかったのです。その結果、悪意あるアタッカーにトップページを改竄されてしまったのです。
どうしてよいのか分からなくなってしまったAさん。5分ほど頭を抱えているところに、同僚のBさんに「どうしたんだ? 元気ないけど。」と声をかけられ、我に返りました。焦ったAさんは「何でもないよ。ちょっと考え事しているだけ」と冷静を装い答えました。
「このまま上司にばれたら、クビになりかねない」と思ったAさんはセキュリティに強い友人のCさんに電話をかて、今までの経緯を話し、3万円で調査・復旧してもらう約束してもらいました。
Cさんは到着するとすぐに、次の手順で調べ始めました。
1:IISのバージョンを調べます。
この例では5.0を使用したことが判明しました。
2:IISのログにアタックログが残るはずなので、ログから「cmd.exe」を検索します。
案の定、検索に引っ掛かる行がありました。通常、httpdのログには「cmd.exe」という文字列は存在しないため、これが存在するということはアタックされたということです。
20/12/2002 12:00 attacker.com W3SVC1 WWW-2k www.victim.com
80 GET /scripts/../../winnt/system32/cmd,exe
/c+dir+c:\ 200 800 900 32 www.victim.com Mozilla/4.0
(compatible; MSIE 5.0; Windows 98; DigExt)
このアタックはIIS UNICODEバグを突いたものです。詳細は特別講座<IIS UNICODE
Exploit編>を参照せよ。
このアタックが成功すれば、ターゲットのマシン(www.victim.com)のCドライブ内のファイルが列挙されます。
おそらく、セキュリティスキャナーまたはこのバグを持つホストを広域スキャンする専用ツールを使ったと思われます。
3:「cmd.exe」を含む行を丹念に調べていくと、cmd.exeのコピーとしてsh.exeを作成し、そのsh.exeを使って適当なHTMLファイルで上書きして、トップページを改竄したとわかりました。
ログから、NetCatなどのバックドアは設置されていませんでした。
4:勝手に作られたsh.exeを削除し、さらにIISのパッチとして提供されているhotfixを適応しました。これで一応完了です。
5:このアタックを利用して、コマンドを実行した場合、その権限はIUSER_COMPUTERNAMEのアカウントになります。このアカウントはEVERYONEに与えられる権限と同等であって、特別な管理権限はありません。
しかし、EVERYONEグループはデフォルトで%SystemRoot%/system32ディレクトリ内のコマンドを全て実行できる権限があります。
よって、%SystemRoot%/system32ディレクトリ内の実行ファイルからEVERYONEグループの実行許可を削除した方がよいでしょう。
実際に、サーバー管理者が管理する場合は、コンソールでコマンドを実行すればよいのです。
6:さらに、wwwroot以下のファイルのアクセス権限を最小限のアカウントに限定することで、少しセキュリティを高めることができます。
Aさんはやっと胸をなでおろしたようです。一件落着。おしまい、おしまい。
■参考文献
- 『新米管理者のためのサーバが重くて困ったとき読む本』
- tempestさん誤植指摘Thanks!
情報源 セキュリティアカデメイア
|