SadServers No.「Saskatoon」解説: アクセスログ解析によるトラフィック分析
はじめに
Webサーバーの運用において、アクセスログの解析は日常的な業務の一つです。今回は、特定のIPアドレスからの過剰なアクセスを検出するという、セキュリティ監視の基本となる作業に取り組みます。この作業は、デスクトップLinuxユーザーが普段行うパッケージの解析と本質的に同じアプローチで解決できます。
問題の概要
あるWebサーバーで、アクセスログファイル(/home/admin/access.log)から最も多くのリクエストを送信しているIPアドレスを特定する必要があります。これは、潜在的な不正アクセスやDDoS攻撃の初期段階を検出する上で重要な作業です。
制約条件:
- root権限は不要
- 結果は/home/admin/highestip.txtに保存
- 解答の正しさはSHA1チェックサムで検証
デスクトップLinuxユーザーの視点からの考察
Arch系ディストリビューションを使用していると、システムログの解析は日常的な作業です。例えば:
- systemd-journalのログから特定のサービスの問題を調査する
- pacmanのログから過去のパッケージインストール履歴を確認する
これらの作業で使用するテキスト処理コマンドとパイプラインの考え方は、今回の課題にそのまま応用できます。
解決手順の詳細
1. ログファイルの構造確認
まず、ログファイルの形式を確認します:
head -n 3 /home/admin/access.log
83.149.9.216 - - [17/May/2015:10:05:03 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
83.149.9.216 - - [17/May/2015:10:05:43 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-dashboard3.png HTTP/1.1" 200 171717 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
83.149.9.216 - - [17/May/2015:10:05:47 +0000] "GET /presentations/logstash-monitorama-2013/plugin/highlight/highlight.js HTTP/1.1" 200 26185 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
出力結果を見ると、これはApacheのCombined Log Format形式であることがわかります。1行目を詳しく見てみましょう:
83.149.9.216 - - [17/May/2015:10:05:03 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
この形式は以下の要素で構成されています:
リモートホストのIPアドレス(83.149.9.216)
identエントリ(-)
リモートユーザー(-)
アクセス日時([17/May/2015:10:05:03 +0000])
リクエストライン("GET /presentations/...HTTP/1.1")
ステータスコード(200)
転送されたバイト数(203023)
リファラー
ユーザーエージェント
このような詳細なログ形式は、デスクトップLinuxでも~/.mozilla/firefox/*/places.sqlite
などのブラウザ履歴データベースで見られます。ただし、今回の課題ではIPアドレス(最初のフィールド)のみに着目すれば良いことが分かります。
2. データの抽出と集計
テキスト処理コマンドを組み合わせて、IPアドレスの出現回数を集計します:
awk '{print $1}' /home/admin/access.log | sort | uniq -c | sort -nr | head -n 1 | awk '{print $2}' > /home/admin/highestip.txt
このコマンドラインは、以下の処理を順に行っています:
-
awk '{print $1}'
:各行の最初のフィールド(IPアドレス)を抽出 -
sort
:IPアドレスをソート(uniqの前処理) -
uniq -c
:重複を集計 -
sort -nr
:数値順(-n)で逆順(-r)にソート -
head -n 1
:最も数の多い行を抽出 -
awk '{print $2}'
:IPアドレスのみを取り出す
これは、例えばpacman.log
から特定のパッケージの操作履歴を抽出する時と同じような処理の流れです。
3. 結果の検証
最後に、結果の正しさを確認します:
sha1sum /home/admin/highestip.txt
システムの仕組みについての理解
テキストストリーム処理
UNIXの「すべてはファイル」という思想により、ログファイルも単なるテキストストリームとして扱えます。これは、journalctl
の出力やpacman.log
など、システム上のあらゆるログファイルに共通する考え方です。
パイプラインによるデータ処理
複数のコマンドをパイプで接続することで、データを段階的に処理していきます。これは、メモリ効率が良く、大きなログファイルでも効率的に処理できる方法であることがわかりました。
学んだこと・重要なポイント
テキスト処理の基本技術
- awkによるフィールド抽出の有用性
- sortとuniqの組み合わせによる集計処理
- パイプラインによる効率的なデータ処理
データ検証の重要性
- チェックサムによる結果の検証
- 中間結果の確認による処理の正確性担保
効率的なワンライナーの構築
- 必要最小限のコマンドでの処理実現
- メモリ使用量を考慮したストリーム処理
おわりに
この課題で行ったログ解析の手法は、デスクトップLinuxの日常的な使用で培った技術がそのまま活かせる良い例です。テキスト処理コマンドの基本を理解していれば、環境が変わっても同じ考え方でデータ分析やトラブルシューティングを行うことができます。
参考情報
- man ページ: awk(1), sort(1), uniq(1), sha1sum(1)
- GNU Coreutils Documentation
- Apache Log Files Documentation
この記事が、SadServersの問題解決の参考になれば幸いです。