[サーバー管理法] Apacheログから時間別のIPアドレスのコネクト数を取得

2016年11月22日

Tips サーバー テクノロジー 日記

この間、いきなりブログサーバーがアクセスできなくなりました。 もしかするとDOS攻撃などの可能性も考えられたので、アクセス数を調査してみたので、その時のコマンドを備忘録で書いておきます。 この記事はLinux(Debian)を基準に書かれています。 Linuxの他のディストリビューションは、各種ログ・ファイルのパスやファイル名が違っている可能性があるので、適宜置き換えて対応してください。

防止策について考える

今回疑われたDOS攻撃とは、特定のサーバーに対して負荷をかけるために、大量のコネクションを行う事で知られていますが、サーバーがチューンナップされておらず、デフォルトで使っていると、大体のサービスはある一定のアクセス数でダウンしてしまうことがあります。 これを防止するには、サーバーを冗長化させたり、負荷分散できるようにバランシング構成に変更するのがいいのですが、それにはハードウェアコストもかかるし、運用メンテナンスコストも膨れ上がります。 まずはその前に、サーバー内のモジュールチューンナップを行うことが一番先にやることでしょう。 インフラエンジニア出ない人が勘違いしやすいのが、ApacheやSQLモジュールの最適設定値を求めがちなんですが、これらの最適値はサービスの特性によってまっtかう別の設定になるので、インフラエンジニアの人は、そういう特性を見極めて最適値を求めるように考えるようにしましょう。 分かりやすくApacheの最適値を求める考え方は以下のとおりです。
・アクセス先がHTMLファイルの静的ページである場合は、keepAliveをOFFにして、使い捨てセッションパケットを放出するだけに徹底する ・画像が多いページを表示する場合は、コネクション過多に陥りやすいので、maxClient数を極限まで増やす ・SQL連携が重要なページは、keepAliveをONにしてMaxKeepAliveRequestsを大きくする
他にも、SQL以外でも、CGIのプログラム比率が大きいページや、他サイトのAPIなどを多様しているページなど、考え方としては、1回のコネクションに対して、サーバーのIOプロセスと、プログラム負荷がどうなっているかを見極めないといけないと言うことです。 具体的には、1回のアクセスにおける容量をちゃんと計算して、最大どのくらいの負荷まで大丈夫かというハードウェア限界値と、ネットワーク帯域の上限値を計算しておかなければ行けないということなんですね。 難しいですが、仕事でやるのであれば、必須なのでがんばりまし ょう。

Apacheのアクセスログ確認

実際に攻撃を受けた場合などは、それを調査する必要があるので、よく対応するコマンドを記載しておきます。

時間別のIPアドレス数を表示

$ grep '\[20\/Nov\/2016:05' /var/log/apache/access.log|awk '{print $1}'|sort|uniq -c|sort -n grep部分の日付は2016年11月20日のAM5時を表しているので、この値を変えると、対象日時のIPアドレス数が得られます。 特定のIPアドレスから桁違いなアクセス数がある場合は、そのIPアドレスをFWなどでブラックリストに入れるととりあえずの対応は完了です。

日別のIPアドレス数を表示

$ grep '\[20\/Nov\/2016' /var/log/apache/access.log|awk '{print $1}'|sort|uniq -c|sort -n 上記プログラムの時間部分を無くすと日別の集計ができます。 月別の場合は、Nov/2016だけにするだけでいいので、なんとなくやり方は分かってもらえると思います。 常習IPアドレスを特定しておきましょう。

アクセスファイル別の総数を表示

$ grep '\[20\/Nov\/2016:05' /var/log/apache/access.log|awk '{print $7}'|sort|uniq -c|sort -n このコマンドで、アクセスファイルの一覧とアクセス数が表示されます。 IPアドレスでさらにgrepすると、どのページが狙われたのかが分かります。

リファラ別アクセス数を取得

$ grep '\[20\/Nov\/2016:05' /var/log/apache/access.log|awk '{print $11}'|sort|uniq -c|sort -n どのページから遷移してきたかが分かり、アクセス元を特定できます。 でも、DOSで攻撃の要な場合はリファラを持たない事が多いので、"-"という値が一番膨れ上がっているかもしれませんね。

ブラウザ別のアクセス数を表示

$ grep '\[20\/Nov\/2016:05' /var/log/apache/access.log|awk '{num=split($0,arr," ");ua="";for(i=1;i< =num;i++){if(i>11){ua=ua" "arr[i];}}print ua;}'|sort|uniq -c|sort -n 少し長いプログラムになってますが、awkの区切り文字が意図しない箇所で区切られてしまうので、一度splitしてから、それ以降の文字列を取得して、結合して、表示しています。

サーバー管理の考え方

サーバー管理は、ほとんどがコマンドラインで対応する作業が多いので、こうした自分なりの調査コマンドをメモしておいて、内容を少し変えるだけで対応できるようにしておくと、非常に仕事効率がアップするので、超オススメです。 1ラインコマンドは、わざわざshellやawkなどのプログラムファイルを作らなくてもいいので、便利すぎる仕様です。 何も見なくてもコマンドを打ち込めるようになるのが一番いいのですが、色々な作業をしていると忘れちゃうのは仕方がないと自分に言い聞かせて、メモ帳にたくさんこうしたコマンドを貯めるようにしてます。 便利なコマンドを知っている人は是非たくさん教えてもらいたいですね。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ