🗂

[SadServers] 解説 "Saskatoon": counting IPs.

2022/11/02に公開
3

"Saskatoon": counting IPs.

SadServersの問題の解説です。 URLは、https://sadservers.com/newserver/saskatoon#

SadServers って何? って人は、 SadServers解説 を見てください。
一言でいうと、LeetCode (コーディング問題集) の Linuxサーバ設定版のようなものです。

問題

Level: Easy

Description: There's a web server access log file at /home/admin/access.log. The file consists of one line per HTTP request, with the requester's IP address at the beginning of each line.

Find what's the IP address that has the most requests in this file (there's no tie; the IP is unique). Write the solution into a file /home/admin/highestip.txt. For example, if your solution is "1.2.3.4", you can do echo "1.2.3.4" > /home/admin/highestip.txt

Webサーバーのアクセスログファイルは、/home/admin/access.logにあります。このファイルは、HTTPリクエストごとに1行で構成されており、各行の先頭にリクエスト元のIPアドレスが記載されています。

このファイルの中で最も多くのリクエストを持つIPアドレスは何かを見つけなさい(同点はない。IPは一意である)。その解答をファイル /home/admin/highestip.txt に書き込んでください。たとえば、あなたの解決策が "1.2.3.4" であれば、次のようになります echo "1.2.3.4" > /home/admin/highestip.txt

Test: The SHA1 checksum of the IP address sha1sum /home/admin/highestip.txt is 6ef426c40652babc0d081d438b9f353709008e93 (just a way to verify the solution without giving it away.)

IPアドレスのSHA1チェックサム sha1sum /home/admin/highestip.txt は 6ef426c40652babc0d081d438b9f353709008e93 (あくまで解を明かさないための検証方法)です。

Time to Solve: 15 minutes.

OS: Debian 11

解き方

/home/admin/access.log を見ると、行頭にIPアドレスが記載されている、次のようなデータとなっています。

dmin@ip-172-31-27-155:/$ cat /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"

各行の先頭のIPアドレスだけを取り出すために cutコマンドを使います。
-d ' ' でスペース区切りで分割し、 -f 1で 1番目の区切り要素(先頭)を出力します。

admin@ip-172-31-27-155:/$ cat /home/admin/access.log   | cut -d' ' -f 1 
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

順番を並べ替えるために sort コマンドを使います。

admin@ip-172-31-27-155:/$ cat /home/admin/access.log   | cut -d' ' -f 1 | sort
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

連続するIPアドレスの数を数えるために、uniq -c を使います。
行頭にカウント数が記されます。

admin@ip-172-31-27-155:/$ cat /home/admin/access.log   | cut -d' ' -f 1 | sort  | uniq -c 
      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 103.25.13.22

最大のカウント数のIPアドレスを見つけるために、再度sortします。昇順に並ぶので、最大カウント数は、最終行に表示されます。

admin@ip-172-31-27-155:/$ cat /home/admin/access.log   | cut -d' ' -f 1 | sort  | uniq -c  | sort
    ...
    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

つまり、66.249.73.135 が 最大の482回アクセスがありました。これを /home/admin/highestip.txt に書き込みます。

admin@ip-172-31-27-155:/$ echo "66.249.73.135" > /home/admin/highestip.txt

Discussion

l1i1i1i1l1i1i1i1
cat /home/admin/access.log   | cut -d' ' -f 1 | sort  | uniq -c  | sort

これと

cat /home/admin/access.log   | cut -d' ' -f 1 | uniq -c  | sort

このコマンドの結果ってなんで異なるんですかね?後者だと次のような結果が返ってきます

     41 199.168.96.66
     41 50.139.66.106
     42 130.237.218.86
     49 130.237.218.86
     49 75.97.9.59
     50 75.97.9.59
     85 130.237.218.86
     89 130.237.218.86
     97 75.97.9.59
kenmakenma

uniq は 同じ行が連続している行の重複を取り除きます。 つまり、ソートしていないと、期待通り動きません。なので、 uniq の間に sort が必要です。

https://linuxjm.osdn.jp/html/GNU_textutils/man1/uniq.1.html

uniq に与える入力はソートされていなければならない。比較は連続した行の間での み行われる。

例えば、text.txt が、次のように、 130.237.218.86 の間に 1.1.1.1が挟まれていると、

 130.237.218.86 
 130.237.218.86 
 1.1.1.1 
 130.237.218.86 
 130.237.218.86 
 130.237.218.86 
cat test.txt | uniq -c 
   2  130.237.218.86
   1  1.1.1.1
   3  130.237.218.86

のように、1.1.1.1で分断されているので、前半で130.237.218.86が2回。 後半で130.237.218.86が3回存在していると出力されます。
これを回避するために、予めsortします。

l1i1i1i1l1i1i1i1

なるほど!連続している場合に削除して数えているんですね!なるほどです,ありがとうございます!