アクセスログから、Googleでどんな検索をして、このサイトに来たかを知る方法
Google Analytics を使えばいいんだけど、まぁシェル芸でもできるんやで。
やりたいこと¶
まず、こういうタイプのApacheのログがある。
999.999.999.999 - - [01/Jun/2016:00:00:00 +0900] "GET /projects/a-painter-and-a-black-cat/news HTTP/1.1" 200 54953 "https://www.google.co.jp/search?q=%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf&btnG=%E6%A4%9C%E7%B4%A2&hl=ja" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"
このログからは、googleで検索して、このページに来たことがわかる。Refererに記録されている。
ただ、マルチバイト文字は、すべからくURLエンコードされていて、そのままでは読めない。ログから、それを抽出して、デコードして表示してみましょう。
Google Analyticsを使えばいいという話もあるけれど、シェル芸の練習でやってみます。
ログの抽出¶
ここがシェルスクリプトの真骨頂である。1行でいける。
まず、該当のログを出力してみる。
# cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log
全部のログが表示されちゃう。絞り込んでみよう。
- "google"が含まれるログに絞り込む。
| grep google
- そこから、"Googlebot"を含まないログに絞り込む。
|grep -v Googlebot
- そこから、q=&"を含まないログに絞り込む。
|grep -v "q=&"
- そこから、"q=cache"を含まないログに絞り込む。
|grep -v "q=cache"
- そこから、"q="を含むログに絞り込む。
|grep q=
全部くっつけて、、、こうじゃ!
# cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log |grep google|grep -v Googlebot|grep -v "q=&"|grep -v "q=cache"|grep q=
環境の違いで、微妙に上手くいかない人もいるかと思うが、適宜調整してください。
URLデコード¶
URLデコードは、実はワンライナーで実現できる。
perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' "ここにURLエンコードデータ"
上の方に書いたログで試してみよう。
対象は、以下の部分である。
%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf
ほい。
$ perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' "%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf" 画像 データ 隠蔽 ctf
さて、ログから該当部分を抽出するにはどうするか。
こうした。
- "q="を区切り文字として、それ以降を出力
echo 'ログのデータ1行' | awk -F'q=' '{print $2}'
- "&"を区切り文字として、その手前を出力
|awk -F'&' '{print $1}'
- "(ダブルコーテーション)を区切り文字として、その手前を出力
|awk -F'\"' '{print $1}'
全部くっつけて、、、こうじゃ!
echo 'ログのデータ1行' | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}'
実際に試してみよう。
$ echo '999.999.999.999 - - [01/Jun/2016:00:00:00 +0900] "GET /projects/a-painter-and-a-black-cat/news HTTP/1.1" 200 54953 "https://www.google.co.jp/search?q=%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf&btnG=%E6%A4%9C%E7%B4%A2&hl=ja" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"' | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}' %E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf
ちゃんと抽出できてますね。
Googleでどんな検索をして、このサイトに来たかを知るツール(シェルスクリプト)¶
それで、こんなシェルスクリプトを作ってみた。
時系列でどんな検索ワードで飛んできたかわかる。
PrintGoogleSearchWords.sh
#!/bin/bash IFS=' ' CONTENT=`cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log |grep google|grep -v Googlebot|grep -v "q=&"|grep -v "q=cache"|grep q=` for WORD in ${CONTENT} do HOST_NAME=`echo ${WORD} | awk '{print $1}'` ACCESS_DATE=`echo ${WORD} | awk '{print $4}'|tr -d '['` URL_ENCODE_DATA=`echo ${WORD} | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}'` URL_DECODE_DATA=`perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' ${URL_ENCODE_DATA}` printf "%s %15s %s\n" ${ACCESS_DATE} ${HOST_NAME} ${URL_DECODE_DATA} done exit 0
コメント