ufwのログをPythonとGeoIPで国別に集計してみた。

Programming Python

昨日のPythonコードを見直しました。いわゆるリファクタリング。

変更したのは昨日のコードの最後の5行で、以下の部分になります。

<見直し前>

print(trans_geoip(ip_addrgroup.most_common(1)[0][0]),ip_addrgroup.most_common(1)[0][0],ip_addrgroup.most_common(1)[0][1])
print(trans_geoip(ip_addrgroup.most_common(2)[1][0]),ip_addrgroup.most_common(2)[1][0],ip_addrgroup.most_common(2)[1][1])
print(trans_geoip(ip_addrgroup.most_common(3)[2][0]),ip_addrgroup.most_common(3)[2][0],ip_addrgroup.most_common(3)[2][1])
print(trans_geoip(ip_addrgroup.most_common(4)[3][0]),ip_addrgroup.most_common(4)[3][0],ip_addrgroup.most_common(4)[3][1])
print(trans_geoip(ip_addrgroup.most_common(5)[4][0]),ip_addrgroup.most_common(5)[4][0],ip_addrgroup.most_common(5)[4][1])

繰り返し文としつつ、見やすく整形しました。

<見直し後>

for h in range(1,21):
    print(ip_cntrgroup.most_common(h)[h-1][0].ljust(10,' '),str(ip_cntrgroup.most_common(h)[h-1][1]).rjust(6,' '))
print('--------------------------------------------')
for i in range(1,31):
    print(str(i).zfill(2),trans_geoip(ip_addrgroup.most_common(i)[i-1][0]).ljust(7,' '),ip_addrgroup.most_common(i)[i-1][0].ljust(15,' '),str(ip_addrgroup.most_common(i)[i-1][1]).rjust(6,' '))

※注
for (x) in range((start),(end):で繰り返し回数
rjustは右寄せで字数分の埋め、ljustは左寄せで字数分の埋め、zfillはstr変換してからのゼロ埋め。

<実行結果>

オランダ王国       5075
ロシア          2326
アメリカ合衆国      1164
中国           1039
ルーマニア         750
スイス連邦         550
フランス共和国       214
日本            195
モルドバ共和国       177
セイシェル         145
イギリス          142
カナダ           141
大韓民国          113
中華民国          108
ドイツ連邦共和国       95
ベトナム           91
インド            63
ブラジル連邦共和国      59
シンガポール         57
パナマ            52
--------------------------------------------
01 ロシア     185.176.27.2       567
02 オランダ王国  93.174.93.68       329
03 オランダ王国  89.248.162.247     307
04 オランダ王国  80.82.64.167       299
05 オランダ王国  89.248.168.225     297
06 スイス連邦   185.39.10.54       294
07 オランダ王国  80.82.65.40        293
08 オランダ王国  89.248.172.196     290
09 オランダ王国  80.82.64.171       289
10 オランダ王国  80.82.64.105       261
11 スイス連邦   185.39.10.25       253
12 オランダ王国  89.248.171.170     188
13 オランダ王国  89.248.168.87      183
14 オランダ王国  93.174.93.206      175
15 オランダ王国  80.82.77.237       143
16 オランダ王国  89.248.162.163     141
17 オランダ王国  89.248.174.17      137
18 ロシア     185.176.27.162     132
19 オランダ王国  80.82.77.218       130
20 ルーマニア   83.97.20.46        124
21 オランダ王国  185.216.140.36     121
22 フランス共和国 51.91.212.80       105
23 ロシア     92.63.196.10       105
24 モルドバ共和国 185.153.198.211    101
25 セイシェル   80.82.70.184        96
26 オランダ王国  80.82.77.214        88
27 ルーマニア   92.118.37.97        87
28 ルーマニア   193.32.161.12       87
29 ルーマニア   193.32.161.31       85
30 ロシア     194.26.29.102       85

rangeの値を増やすことで表示数が簡単に増やせるようになりました。

おまけ

GeoIP2のデータベースには昨日利用したCountryだけでなく、Cityもあるのです。どんな結果になるのか気になりますので、そちらも試してみることにしました。

GeoLite2-City_20200128.tar.gzというファイルをダウンロードして解凍すると、GeoLite2-City.mmdbというファイルが格納されておりますので、今度はこれを読み込みます。

試しに出力しましたところ、以下が格納されていました。

({'continent': {'code': 'EU', 'geoname_id': 6255148, 'names': {'de': 'Europa', 'en': 'Europe', 'es': 'Europa', 'fr': 'Europe', 'ja': 'ヨーロッパ', 'pt-BR': 'Europa', 'ru': 'Европа', 'zh-CN': '欧洲'}}, 'country': {'geoname_id': 2017370, 'iso_code': 'RU', 'names': {'de': 'Russland', 'en': 'Russia', 'es': 'Rusia', 'fr': 'Russie', 'ja': 'ロシア', 'pt-BR': 'Rússia', 'ru': 'Россия', 'zh-CN': '俄罗斯联邦'}}, 'location': {'accuracy_radius': 1000, 'latitude': 55.7386, 'longitude': 37.6068, 'time_zone': 'Europe/Moscow'}, 'registered_country': {'geoname_id': 2017370, 'iso_code': 'RU', 'names': {'de': 'Russland', 'en': 'Russia', 'es': 'Rusia', 'fr': 'Russie', 'ja': 'ロシア', 'pt-BR': 'Rússia', 'ru': 'Россия', 'zh-CN': '俄罗斯联邦'}}, 'traits': {'ip_address': '92.246.76.253'}}, ['en'])
#!/usr/bin/python3
import re
import sys
import ipaddress
import geoip2.database
import csv
import collections
filename='/var/log/ufw.log'
ip_address = []
ip_country = []
ip_date = []
gip = geoip2.database.Reader("/usr/local/share/GeoLite2/GeoLite2-City.mmdb")
#
def trans_geoip(ip_addr):
    if '192.168.1.' in ip_addr:
        return ('Private')
    try:
        response = gip.city(ip_addr)
        return (response.continent.names['ja'],response.country.names['ja'],response.location.time_zone,response.location.latitude,response.location.longitude)
    except:
        print('')
def trans_word(input_text):
    replacements = {
            'Jan':'01',
            'Feb':'02',
            'Mar':'03',
            'Apl':'04',
            'May':'05',
            'Jun':'06',
            'Jul':'07',
            'Aug':'08',
            'Sep':'09',
            'Oct':'10',
            'Nov':'11',
            'Dec':'12',
            }

    return re.sub('({})'.format('|'.join(map(re.escape,replacements.keys()))),lambda m: replacements[m.group()],input_text)
#
with open(filename) as f:
    reader = csv.reader(f,delimiter=" ",doublequote=False,lineterminator="\r\n")
    for row in reader:
        print("2020"+"/"+trans_word(row[0])+"/"+row[2].zfill(2),",",row[3],",",row[12].strip("SRC=").ljust(15,' '),",",trans_geoip(row[12].strip("SRC=")))

おまけの実行結果

緯度経度まで含まれていました。
国外についてはIPが異なっても緯度経度はほぼ同一なので面白みもないです。

020/02/05 , 23:39:05 , 80.82.70.184    , ('アフリカ', 'セイシェル', 'Indian/Mahe', -4.7034, 55.5206)
2020/02/05 , 23:39:41 , 80.82.77.236    , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:39:56 , 89.248.174.17   , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:40:09 , 93.174.93.206   , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:40:10 , 80.82.77.237    , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:40:35 , 92.63.196.10    , ('ヨーロッパ', 'ロシア', 'Europe/Samara', 56.4216, 53.7757)
2020/02/05 , 23:40:58 , 89.248.162.163  , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:40:59 , 89.248.162.163  , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:41:20 , 89.248.171.170  , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:42:02 , 89.248.171.170  , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:42:08 , 200.107.92.87   , ('南アメリカ', 'アルゼンチン共和国', 'America/Argentina/Catamarca', -45.9333, -67.5333)
2020/02/05 , 23:42:18 , 176.32.34.210   , ('ヨーロッパ', 'ロシア', 'Europe/Moscow', 55.7527, 37.6172)
2020/02/05 , 23:42:44 , 193.32.161.12   , ('ヨーロッパ', 'ルーマニア', 'Europe/Bucharest', 45.9968, 24.997)
2020/02/05 , 23:42:59 , 80.82.78.20     , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:43:27 , 167.99.187.125  , ('北アメリカ', 'カナダ', 'America/Toronto', 43.6547, -79.3623)
2020/02/05 , 23:44:31 , 93.174.93.206   , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)
2020/02/05 , 23:44:32 , 167.99.187.125  , ('北アメリカ', 'カナダ', 'America/Toronto', 43.6547, -79.3623)
2020/02/05 , 23:44:34 , 89.248.174.17   , ('ヨーロッパ', 'オランダ王国', 'Europe/Amsterdam', 52.3824, 4.8995)

国内については多少IPと緯度経度にばらつきがありました。
緯度経度からもう少しだけ地域を特定することができそうです。

2020/02/05 , 03:05:43 , 122.214.140.45  , ('アジア', '日本', 'Asia/Tokyo', 35.8819, 139.8715)
2020/02/05 , 04:43:23 , 172.104.112.244 , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 06:42:56 , 172.105.207.40  , ('アジア', '日本', 'Asia/Tokyo', 35.69, 139.69)
2020/02/05 , 07:24:03 , 139.162.70.53   , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 12:31:37 , 139.162.75.99   , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 13:44:56 , 139.162.105.13  , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 15:26:41 , 139.162.72.191  , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 15:57:37 , 103.29.69.96    , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 16:41:18 , 172.104.122.237 , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 17:43:20 , 121.80.71.130   , ('アジア', '日本', 'Asia/Tokyo', 34.5792, 135.6287)
2020/02/05 , 17:58:30 , 139.162.98.244  , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 18:05:48 , 172.104.76.217  , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 18:49:44 , 172.105.224.78  , ('アジア', '日本', 'Asia/Tokyo', 35.69, 139.69)
2020/02/05 , 20:19:02 , 172.104.109.160 , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 20:31:36 , 172.104.125.180 , ('アジア', '日本', 'Asia/Tokyo', 35.6882, 139.7532)
2020/02/05 , 21:25:27 , 240d:001a:055e:1d00:8c82:c24d:04a6:df0b , ('アジア', '日本', 'Asia/Tokyo', 35.8613, 139.5157)

それではハッピーハックライフを!