Apacheのアクセスログのサイズが異常に大きくなっている場合があります。アクセスログをチェックして、ある特定の送信元から大量のアクセスがあった場合にメール通知するBashスクリプトの作成例です。
※目次をクリックすると目次の下部にコンテンツが表示されます。
- 1.短期間の大量アクセスのアクセスログの一例
- 2.Linuxのgrep、awk、sortなどを使って大量アクセスの送信元を抽出
- 3.アクセスログ内の大量アクセスのログを検知してメール通知するBashスクリプト
短期間の大量アクセスのアクセスログの一例
私が運用しているVPSサーバーで実際に記録されていた一例です。
176.56.xxx.xxx – – [12/May/2015:05:01:16 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:18 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:17 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:19 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:19 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:20 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:21 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:21 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:04 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
176.56.xxx.xxx – – [12/May/2015:05:01:16 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:18 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:17 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:19 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:19 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:20 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:21 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
176.56.xxx.xxx – – [12/May/2015:05:01:21 +0900] “POST /wp-login.php HTTP/1.0” 200 3589
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:03 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
46.19.xxx.xxx – – [02/Jun/2015:00:55:04 +0900] “POST /xmlrpc.php HTTP/1.1” 403 275
Linuxのgrep、awk、sortなどを使って大量アクセスの送信元を抽出
1)送信元アドレスをキーにして集計
①時間を指定して抽出
アクセスログの日付フォーマットが”02/Jun/2015″の形式なので、昨日の日付を同フォーマットで出力する場合は下記のようにdateコマンドのオプションを指定します。
date +”%d/%b/%Y” –date “1 day ago”
②アクセスログから送信元アドレスのみを抽出
上記ログ出力例より送信元アドレスは1番目のフィールドなので、awkコマンドで以下のように指定して抽出できます。
awk ‘{print $1}’
③IPアドレス毎にソートして集計、カウント数が大きい順に20行出力
sort | uniq -c | sort -nr | head -20
実行例)
①時間を指定して抽出
アクセスログの日付フォーマットが”02/Jun/2015″の形式なので、昨日の日付を同フォーマットで出力する場合は下記のようにdateコマンドのオプションを指定します。
date +”%d/%b/%Y” –date “1 day ago”
②アクセスログから送信元アドレスのみを抽出
上記ログ出力例より送信元アドレスは1番目のフィールドなので、awkコマンドで以下のように指定して抽出できます。
awk ‘{print $1}’
③IPアドレス毎にソートして集計、カウント数が大きい順に20行出力
sort | uniq -c | sort -nr | head -20
実行例)
# more アクセスログのpath | grep `date +"%d/%b/%Y" --date "1 day ago"` | awk '{print $1}' | sort | uniq -c | sort -nr | head -20 296990 46.19.139.xxx 301 136.243.5.xxx 189 36.52.118.xxx 169 188.165.214.xxx 147 75.134.131.xxx 52 173.242.113.xxx 45 58.138.159.xxx 44 136.243.5.xxx :
2)送信元アドレスと宛先URLのパスのペアをキーにして集計
送信元アドレスのみの場合だと検索エンジンのロボットからのアクセスも含まれてしまいます。送信元アドレスと宛先URLのパスのペアをキーにして集計する場合は下記のようにします。
①時間を指定して抽出
上記1)の①と同様。
②アクセスログから送信元アドレスと宛先URLのパスのみを抽出
上記ログ出力例より送信元アドレスは1番目、宛先URLのパスは7番目のフィールドなので、下記コマンドで抽出できます。
awk ‘{print $1 $7}’
③IPアドレス毎にソートして集計、カウント数が大きい順に20行出力
上記1)の③と同様。
実行例)
# more アクセスログのpath | grep `date +"%d/%b/%Y" --date "1 day ago"` | awk '{print $1 $7}' | sort | uniq -c | sort -nr | head -20 296990 46.19.139.xxx/xmlrpc.php 23 36.52.118.xxx/favicon.ico 8 36.52.118.xxx/wp-includes/js/wp-emoji-release.min.js?ver=4.2.2 8 36.52.118.xxx/wp-admin/admin-ajax.php 6 36.52.118.xxx/wp-login.php?loggedout=true 5 36.52.118.xxx/wp-includes/js/jquery/jquery.js?ver=1.11.2 5 36.52.118.xxx/wp-includes/css/dashicons.min.css?ver=4.2.2 5 36.52.118.xxx/wp-includes/css/buttons.min.css?ver=4.2.2 5 36.52.118.xxx/wp-admin/css/login.min.css?ver=4.2.2 5 114.164.246.xxx/wp-content/plugins/akismet/_inc/form.js?ver=3.0.4 :
アクセスログ内の大量アクセスのログを検知してメール通知するBashスクリプト
1)スクリプトの仕様
①下記3つのアクセスログを対象
access_log www1.example.com-access_log www2.example.com-access_log
②アクセスログから不審なログを抽出する方法は上記(2)の2)の方法
③上記②抽出したログのカウント数が100以上の場合はメール通知の対象として一時ファイルに記録
④上記③でメール通知の対象のログが記録されていた場合はメール通知
①下記3つのアクセスログを対象
access_log www1.example.com-access_log www2.example.com-access_log
②アクセスログから不審なログを抽出する方法は上記(2)の2)の方法
③上記②抽出したログのカウント数が100以上の場合はメール通知の対象として一時ファイルに記録
④上記③でメール通知の対象のログが記録されていた場合はメール通知
#!/bin/bash ftmp_disk="/home/user/bkup/tmp_access" fout_disk="/home/user/bkup/out_access" fmail_disk="/home/user/bkup/mail_access" : > $fout_disk cd /var/log/httpd logs=(access_log www1.example.com-access_log www2.example.com-access_log) for (( i=0 ; i<${#logs[@]}; i++ )) ; do echo ${logs[i]} >> $fout_disk more ${logs[i]} | grep `date +"%d/%b/%Y" --date "1 day ago"` | awk '{print $1 $7}' | sort | uniq -c | sort -nr | head -20 > $ftmp_disk while read line; do if [[ $line =~ ^([0-9]+)[[:space:]].* ]]; then if [ ${BASH_REMATCH[1]} -gt 100 ]; then echo $line >> $fout_disk fi fi done < $ftmp_disk done [[ `wc -l $fout_disk` =~ ^([0-9]+)[[:space:]].* ]] if [[ ${BASH_REMATCH[1]} -gt 7 ]]; then echo "From: root@mail.example.com" > $fmail_disk echo "To: user@myhome.com" >> $fmail_disk echo "Subject: Apache access-log Warning Dos" >> $fmail_disk echo "" >> $fmail_disk cat $fout_disk >> $fmail_disk /usr/sbin/sendmail -t < $fmail_disk fi
※正規表現を使ったパターンマッチ、ファイル内のデータ読取りなどの方法については下記記事参照。
bashでパターンマッチを使って条件評価
ファイルの中身を一行ずつ読んで文字列を置換するbashスクリプト
2)上記1)のスクリプトをcronに登録
cronの設定についてはいろいろ方法があります。一例を示します。
例)毎日3時30分にcronで実行させる例
# vi /etc/crontab
30 3 * * * root /home/user/bkup/access.sh
- VPSサーバーでスナップショットを取得
- ~障害に備え、リカバリーポイントを作成。
- VPSサーバーにログインして、設定内容を確認
- ~グローバルIPアドレス確認、SSHキーを作成。
- VPSサーバーにSSHでログイン
- ~Tera Term、SSH、公開鍵認証方式
- yumコマンドで最新のパッケージにアップデート
- ~全パッケージを最新にアップデート
- Apacheのインストール
- ~yumコマンドでApacheインストール、iptablesでファイアウォールの設定
- PHPとMySQLをインストール
- ~yumコマンドでPHP、MySQLインストール
- WinSCPを使ってWordPressをアップロード
- ~WinSCPをクライアントPCにインストール、ファイルアップロード方法
- WordPressをインストール
- ~MySQLでWordPress用データベース作成、wp-config.phpファイルの設定
- CentOSのファイアウォール設定
- ~iptablesを使ってネットワークフィルタリング設定を一から行う
- OpenSSHの設定をよりセキュアに
- ~ログイン制限、ポート変更、認証方式
- ApacheでTCPのTraceメソッドを無効にする
- ~Apacheの設定変更、Telnetで動作確認
- ヘッダーにApacheバージョンが表示されないようにする
- ~Apacheの設定変更、Telnetで動作確認
- Apacheでディレクトリ内一覧表示を無効にする
- ~autoindex_moduleのロードを無効にする
- セキュリティを考慮し、MySQLの匿名ユーザーにパスワードを設定、または削除
- ~MySQLの匿名ユーザーにパスワードを設定、または削除
- PHPのバージョンが表示されないようにする
- ~php.iniの設定変更
- WordPressディレクトリのパーミッションをセキュアに
- ~WordPress用ディレクトリの所有グループ、ユーザー、パーミッション設定
- パーマリンク設定時のApache設定
- ~WordPressパーマリンクの設定、Apache .htaccessの設定
- WordPressテーマの選定
- ~テーマ追加の特徴フィルターの項目、テンプレートキング
- WordPressで画像のアップロード、サイズ調整、リンクを設定
- ~アップロード画像の画像サイズ、サムネイル、画像編集、リンク設定
- 更新可能なRPMパッケージのリストをメールで送信する
- ~yumコマンド、Bashスクリプト、Cron
- Linuxでディスク使用量が多いディレクトリを調べる方法(1)
- ~du --max-depth
- Linuxでディスク使用量が多いディレクトリを調べる方法(2)
- ~duコマンド、sortコマンド
- WordPressデータベースのバックアップとリストア
- ~コマンドラインでバックアップ、リストア
- WordPressのバージョンアップと旧バージョンへの戻し
- ~データベースとディレクトリのバックアップ、リストア
- BashスクリプトでWordPressデータベースを自動バックアップ
- ~MySQLデータベースをBash、Cronを使って自動バックアップ、メール通知
- BashスクリプトでDos攻撃など大量アクセスのログを検知
- ~Apacheアクセスログ、Dos、Cron、メール通知
テーマ作成
- ブートストラップ3を使って自作テーマ作成
- (1)全体概要
- (2)ブートストラップのサンプルを使ってindex.phpを作成
- (3)header.php、sidebar.php、footer.php、index.phpのテンプレートファイル作成
- (4)JavaScriptインクルードの設定
- (5)投稿本文表示用のテンプレートファイルを作成
- (6)単一投稿用(single.php)のテンプレートファイル作成
- (7)固定ページ用(page.php)のテンプレートファイル作成
- (8)検索結果表示用(search.php)のテンプレートファイル作成
- (9)アーカイブ表示用(archive.php)のテンプレートファイル作成
- (10)カテゴリー表示用(category.php)のテンプレートファイル作成
- (11)WordPressのメニュー画面でナビゲーションメニューを設定
- (12)サイトタイトル、キャッチフレーズを表示できるようにheader.phpを修正
- (13)カスタムヘッダー画像を使えるようにheader.phpを修正
- (14)404.phpテンプレートファイルを作成
- (15)記事タイトル部分のCSS設定
- (16)記事メタデータ部分のCSS設定
- (17)記事本文部分のCSS設定
- (18)前後のページへのリンクのCSS設定
- (19)前後の投稿へのリンクのCSS設定
- (20)コメント投稿フォーム、コメント表示部のCSS設定
- (21)ウィジェット部のCSS設定
- (22)アーカイブページのCSS設定
- (23)画面を左右にスライドさせるボタンのCSS設定
- ~Bootstrap3、自作テーマ作成、TwentyFourteen
- Bootstrapのフリーのテーマを使ってデザインを簡単にカスタマイズ
- ~Bootstrap3のスタイルをカスタマイズ
- 簡単なショートコードを作ってみる
- ~ショートコードの作り方
- ショートコードを使って関連記事のリンクを自動で挿入
- ~ショートコードの簡単なサンプル
- ショートコードを使ってディレクトリ内のファイル名を取得し、投稿内にリンクを挿入
- ~カスタムフィールド利用、PHPで日本語文字列検索などのコーディング
- WordPress投稿内でAngularJSを使用
- ~AngularJS、Bootstrap、アコーディオン
- Bootstrap3で作成したナビゲーションメニューをAngularJSに変更
- ~AngularJS、Bootstrap、自作テーマheder.php
- WordPressでAngularJSを使ったGoogleマップを使えるようにする
- ~AngularJSを使って投稿内にGoogleマップ
WordPresssショートコード
AJAX、AngularJSなどその他応用
- Ruby on Rails(他サイト)
- ~構築、CMS、Bootstrap、AngularJS
- bashのシェルスクリプト実行方法
- bashのシェルスクリプト プログラミング方法メモ
- bashのパイプの使い方
- bashのlist、サブシェル、コマンドブロック
- bashでの式の評価と算術演算
- bashでパターンマッチを使って条件評価
- bashのfor文で配列やセパレータ付き文字列から各要素を取り出す
- bashのfor文を使ってディレクトリ内のファイル一覧とディレクトリ一覧を出力
- bashのselect制御構造
- bashのパターンマッチ演算子の使い方
- ファイルの中身を一行ずつ読んで文字列を置換するbashスクリプト
- ディスク使用量が多いディレクトリを抽出するbashスクリプト
- ディレクトリ内の複数のファイルに対しファイル内の文字列を置換するbashスクリプト
- Bashスクリプトでmysqldumpバックアップと世代管理
- Dos攻撃など大量アクセスのログを検知するBashスクリプトを作成