SadServers解説#2 "Saskatoon": counting IPs.
問題概要
シナリオ
IPアドレスを数えてください。
問題詳細
/home/admin/access.logにウェブサーバのアクセスログファイルがあります。このファイルはHTTPリクエスト1件につき1行で構成され、各行の先頭にリクエスト元のIPアドレスが書かれています。
~$ head -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"
このファイルの中で最もリクエストの多いIPアドレスを見つけてください。
(IPアドレスの数が同率一位になることはありません)
解決判定
解答をファイル/home/admin/highestip.txtに書いて、Check My Solution
ボタンをクリックしてください。例えば、解答が "1.2.3.4"であれば、次のようなコマンドを実行し、Check My Solution
ボタンをクリックしてください。
~$ echo "1.2.3.4" > /home/admin/highestip.txt
解答が正解かどうか、コマンドプロンプト上で確認することも可能です。ハッシュ値を求める次のコマンドを実行して、以下と同じ出力が得られた場合は正解です。
~$ sha1sum /home/admin/highestip.txt
6ef426c40652babc0d081d438b9f353709008e93 /home/admin/highestip.txt
問題解決の方針
【表示する】
ファイル内容を編集するコマンドを適切に使えるかが問われています。
今回の問題では、ファイルの一列目に書かれているIPアドレスを集計する必要があります。
並び替える、列を抽出する、要素を数えるなどの操作をどの順番で行えば、最も多いIPアドレスを求めることができるでしょうか。
解決の手順を表示する
- ファイルの内容のうち、IPアドレスの列だけ抽出する
- 重複する要素を数えるコマンドを実行するために、IPアドレスが同じ行が連続するように並び変える
- 重複する要素を数えるコマンドを実行する
- 出現回数を並び替え、出現回数が最も多いIPアドレスを求める
ヒント
今回のように出力が長くなってしまう場合は、コマンドの最後に| head
を付けて出力行数を10行に抑制することで、コマンドの結果が見やすくなります。
ヒント1
まずは、ファイルの内容のうち、IPアドレスの1列目だけ抽出します。
特定の行だけ抽出するときは、cut
コマンドを使用します。
実行コマンド
区切り文字は" "(半角スペース)のため、-d ' '
オプションで、半角スペースを区切り文字に指定します。
また、-f 1
オプションで、1列目を抽出する列に指定します。
~$ cut -d " " -f 1 access.log | head
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
IPアドレスの列だけ抽出できました。
ヒント2
一見、同じIPアドレスが連続しているように見えますが、ファイルを見ていくと、同じIPアドレスが離れた場所に出てくる場所があります。
110.136.166.128
46.105.14.53
110.136.166.128
110.136.166.128
110.136.166.128
110.136.166.128
123.125.71.35
110.136.166.128
重複する要素を数えるコマンドを実行するために、IPアドレスが同じ行が連続するように並び変えます。
列を並び替えるには、sort
コマンドを使用します。
実行コマンド
~$ cut -d " " -f 1 access.log | sort | head
1.22.35.226
1.22.35.226
1.22.35.226
1.22.35.226
1.22.35.226
1.22.35.226
100.2.4.116
100.2.4.116
100.2.4.116
100.2.4.116
並び変えることができました。
ヒント3
重複する要素の出現回数を数えるには、uniq
コマンドを使用します。
実行コマンド
uniq
コマンドをそのまま使うだけでは、重複行を削除するだけになってしまいます。
~$ cut -d " " -f 1 access.log | sort | uniq | head
1.22.35.226
100.2.4.116
100.43.83.137
101.119.18.35
101.199.108.50
101.226.168.196
101.226.168.198
101.226.33.222
103.245.44.13
103.247.192.5
uniq
コマンドのオプション-c
を使うことで、重複した要素の出現回数を同時に表示させることができます。
~$ cut -d " " -f 1 access.log | sort | uniq -c | head
6 1.22.35.226
6 100.2.4.116
84 100.43.83.137
33 101.119.18.35
3 101.199.108.50
1 101.226.168.196
1 101.226.168.198
2 101.226.33.222
4 103.245.44.13
1 103.247.192.5
たとえば、一行目は、"1.22.35.226"が6回出現した、という意味です。
ヒント4
最も出現回数が多かったIPアドレスを割り出すために、出現回数で並び替えます。
並び替えには、再びsort
コマンドを使用します。
実行コマンド
~$ $ cut -d " " -f 1 access.log | sort | uniq -c | sort | tail
82 198.46.149.143
83 208.115.111.72
84 100.43.83.137
99 68.180.224.225
102 209.85.238.199
113 50.16.19.13
273 75.97.9.59
357 130.237.218.86
364 46.105.14.53
482 66.249.73.135
よって、出現回数が最も多いIPアドレスは、66.249.73.135
であることが分かりました。
答え
以下のコマンドを実行し、Check My Solution
ボタンをクリックしてください。
~$ echo "66.249.73.135" > highestip.txt
「いきなり問題を解き始めても調べるばかりになってしまう…」 「やりたいことが分かっても、コマンドが分からない…」 という方は、下記の記事でLinuxのコマンドを復習してから、SadServersの問題に取り掛かってみてはいかがでしょうか。
問題一覧はこちら
Discussion