こんにちは、クラウド事業部の倉岡です。
Apacheのアクセスログ解析に手間をかけていませんか?
サーバー運用において、アクセスログから問題の原因を特定したり、不正アクセスを早期に発見することは重要な作業ですが、毎回手動でログを調査するのは非効率です。
そこで今回は、Apacheのログ分析を自動化し、手間を大幅に削減できるシェルスクリプトを作成しました。
このスクリプトを使えば、特定のIPアドレスやリクエスト数の多いサイトを簡単に抽出でき、トラブルシューティングの効率が格段に向上します。
本記事では、スクリプトの概要から作成手順、実行方法までを詳しく解説しますので、サーバー運用の効率化を図りたいエンジニアの方は、ぜひ参考にしてみてください。
事前準備
対象のサーバー
Amazon linux 2
Amazon linux 2023
centOS
上記のOSでshellが動くように作成しました。
Apacheログフォーマットの解説
Apacheのログフォーマット設定は以下のようになっています:
1LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
各項目の意味は以下の通りです:
- %h:クライアントのIPアドレス
- %l:RFC 1413によるクライアント識別子(ほとんどの場合、 が表示されます)
- %u:認証されたユーザー名(未認証の場合は )
- %t:リクエストが受信された日時
- %r:リクエストの最初の行(メソッド、リソース、HTTPバージョン)
- %>s:サーバーが返したHTTPステータスコード
- %b:レスポンスのバイト数(ヘッダーは含まれない)
- %{Referer}i:リクエスト時のリファラ情報
- %{User-Agent}i:リクエストに含まれるユーザーエージェント情報
- %I:リクエストの入力バイト数
- %O:レスポンスの出力バイト数
このログフォーマットは、クライアント情報、リクエスト内容、レスポンスの詳細を網羅しており、トラブルシューティングに非常に役立ちます。
デフォルトとは少し異なる形式をしており、vhost設定をして複数のサイトをアクセスログを一つにまとめているところはこのように設定すると良いと思います。
ログは例としてこのように出力されます。
112.123.456.789 example.co.jp - - [06/Jan/2025:04:05:02 +0900] "GET /contact/ HTTP/1.1" 200 6231 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
作成手順
スクリプトの作成・解説
このスクリプト accesslog-check-httpd.sh は、Apacheのアクセスログを解析して、アクセスの多いIPアドレス、アクセス先のサイト、リクエストメソッドの統計を出力します。
スクリプト内容
1#!/bin/bash
2
3# PATHを明示的に設定
4export PATH=/usr/bin:/bin:/usr/sbin:/sbin:$PATH
5
6# 引数で指定された時間を取得(デフォルトは現在時刻)
7HOUR_OFFSET=${1:-0}
8DAY_OFFSET=${2:-0}
9LOG_PATH=${3:-"/var/log/httpd/access_log"}
10
11echo "ログファイル: $LOG_PATH"
12
13# 指定された時間に基づいた時刻を計算
14CURRENT_TIME=$(date --date="${HOUR_OFFSET} hour ${DAY_OFFSET} day" '+%d/%b/%Y:%H')
15
16# アクセスの多いIPを抽出
17echo "最もアクセスの多いIP一覧 (時刻: $CURRENT_TIME):"
18TOP_IPS=$(grep "$CURRENT_TIME" "$LOG_PATH" | awk '{print $1}' | sort | uniq -c | sort -rn | head)
19
20# 出力結果を表示
21echo "$TOP_IPS"
22
23# ログからアクセスの多いサイト一覧
24echo "ログからアクセスの多いサイト一覧:"
25grep "$CURRENT_TIME" "$LOG_PATH" | awk '{print $2}' | sort | uniq -c | sort -rn | head
26
27# 各IPアドレスについてリクエストメソッドを表示
28echo "各IPアドレスのリクエストメソッド統計:"
29echo "$TOP_IPS" | awk '{print $2}' | while read IP; do
30 echo "IPアドレス: $IP"
31 grep "$CURRENT_TIME" "$LOG_PATH" | grep "$IP" | awk '{print $7}' | sort | uniq -c | sort -rn
32 echo "----------------------------------"
33done
34
35# ESTABLISHED状態のHTTPD接続元IPの集計
36echo "ESTABLISHED状態のHTTPD接続元IP一覧:"
37netstat -antp | grep ESTABLISHED | grep httpd | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | head
38
スクリプトの各セクション解説
- PATHの設定
- スクリプトの実行環境で使用するコマンドのパスを明示的に設定しています。
- 引数で指定された時間の取得
- $1 と $2 で時間と日付のオフセットを指定でき、デフォルトは現在時刻です。
- アクセスの多いIPアドレスの抽出
- 指定した時刻のログから、最もアクセスが多かったIPアドレスを抽出し、アクセス数の多い順に表示します。
- アクセスの多いサイト一覧の抽出
- ログからアクセス先のサイト情報を抽出し、アクセス数の多い順に表示します。
注意:1つのサイトのみをアクセスログに出力している場合は、ここの部分は意味がないので該当部分は削除して使うことをお勧めします。
- 各IPアドレスのリクエストメソッド統計
- 各IPアドレスごとに、どのリクエストメソッド(GET、POST、HEADなど)が使われたかを統計として表示します。
- ESTABLISHED状態のHTTPD接続元IPの集計
- 現在ESTABLISHED状態にあるHTTPD接続元のIPアドレスを集計し、接続数の多い順に表示します。
実行方法
サーバーの中にログインします。任意のフォルダにスクリプトを記載します。
1##フォルダを作成
2mkdir /home/shell
3##移動
4cd /home/shell
5##スクリプトを作成
6vi accesslog-check-httpd.sh
7##スクリプトに権限実行を付与
8chmod +x accesslog-check-httpd.sh
以下の形式でスクリプトを実行します:
1./accesslog-check-httpd.sh $1 $2 $3
2
- $1 は時間指定(デフォルトは現在時刻)
- 数字を入れることで1時間前などの時間を指定できます。
- -1 で1時間前、1 で1時間後(昨日の1時間前とかの指定が可能)。
- $2 は日付指定(デフォルトは本日の日付)
- -1 で昨日などを指定可能です。
- $3 はログファイルのパス指定(デフォルトは /var/log/httpd/access_log)。
例:
1##今の時間が「06/Jan/2025:14」の場合
2#何もなしだと 今の時間の1時間分のログ pathは「/var/log/httpd/access_log」
3./accesslog-check-httpd.sh
4
5#「05/Jan/2025:12」の1時間分のログ pathは「/var/log/httpd/hogehoge/access_log」
6./accesslog-check-httpd.sh -2 -1 /var/log/httpd/hogehoge/access_log
ログの結果例
スクリプトを実行すると、以下のような結果が表示されます:
1
2##サンプルです。IPやサイトは適当なものに置き換えてます。
3$./accesslog-check-httpd.sh
4最もアクセスの多いIP一覧 (時刻: 06/Jan/2025:14):
57659 192.168.1.1
65630 10.0.0.2
74036 172.16.0.3
83340 203.0.113.4
92816 198.51.100.5
101612 192.0.2.6
111611 10.1.1.7
121565 172.16.1.8
131514 ::1
141450 203.0.113.9
15
16ログからアクセスの多いサイト一覧:
1721555 internal-server.local
184561 example1.com
194003 hogesampledomain.jp
203067 demohogehogetestsite123.net
212856 demo-site.org
222476 demohogecompany.co.jp
232179 demodemoservice-site.com
241928 demolocal-business.jp
251790 demoecommerce-shop.net
261777 demoportfolio-site.jp
27
28各IPアドレスのリクエストメソッド統計:
29IPアドレス: 192.168.1.1
307659 "GET"
31----------------------------------
32
33IPアドレス: 10.0.0.2
345686 "GET"
35----------------------------------
36
37IPアドレス: 172.16.0.3
384029 "GET"
397 "POST"
40----------------------------------
41
42IPアドレス: 203.0.113.4
432959 "GET"
44402 "POST"
45----------------------------------
46
47IPアドレス: 198.51.100.5
481763 "GET"
491061 "HEAD"
50----------------------------------
51
52IPアドレス: 192.0.2.6
531374 "GET"
54243 "POST"
5510 "OPTIONS"
56----------------------------------
57
58IPアドレス: 10.1.1.7
591611 "GET"
60----------------------------------
61
62IPアドレス: 172.16.1.8
631565 "GET"
64----------------------------------
65
66IPアドレス: ::1
671537 "OPTIONS"
68----------------------------------
69
70IPアドレス: 203.0.113.9
711450 "GET"
72----------------------------------
73
74ESTABLISHED状態のHTTPD接続元IP一覧:
7524 203.0.113.50
7619 192.168.0.100
7716 10.0.1.15
7814 172.16.10.30
798 198.51.100.25
807 192.168.1.200
817 10.1.1.45
827 203.0.113.75
837 172.16.20.40
847 192.0.2.150
85
このスクリプトにより、Apacheのログ分析が効率的になり、手動でのコマンド実行にかかる手間を大幅に削減できます。ぜひ皆さんも活用してみてください!