見出し画像

アクセスログのIPアドレス情報をipinfo.ioから取得してCSVに出力する


概要

この Python スクリプトは、Nginx のアクセスログファイルからユニークな IP アドレスを抽出し、各 IP アドレスに関する詳細情報を取得して、それらを CSV ファイルに出力するツールです。

Nginx 用に作っていますが、extract_unique_ips 関数の IP アドレスを抽出する正規表現とログファイルのパスを修正することでApacheなどの他のウェブサーバーにも利用できます。

主な機能

  1. Nginx のアクセスログからユニークな IP アドレスを抽出

  2. 抽出した IP アドレスについて、ipinfo.io API を使用して詳細情報を取得

  3. 取得した情報をCSVファイルに出力

必要な環境

  • Python 3.6以上

  • requests ライブラリ

インストール

  1. このスクリプトをサーバーの適切な場所にダウンロードします。

  2. 必要なライブラリをインストールします:

pip install requests

設定

スクリプト内の以下の変数を環境に合わせて設定してください:

INPUT_FILE = '/var/log/nginx/access.log'
OUTPUT_FILE = '/path/to/your/output/ip_info.csv'
  • INPUT_FILE: Nginxのアクセスログファイルのパス

  • OUTPUT_FILE: 生成するCSVファイルの保存先パス

使用方法

  1. スクリプトを実行します:

python ip_info_csv_generator.py
  1. スクリプトは以下の手順で動作します:

    • ログファイルからユニークな IP アドレスを抽出

    • 各 IP アドレスの情報を ipinfo.io API から取得

    • 取得した情報をCSVファイルに出力

  2. 処理が完了すると、指定した場所にCSVファイルが生成されます。

出力されるCSVファイルの構造

生成されるCSVファイルには以下の列が含まれます:

  • IP: IPアドレス

  • Hostname: ホスト名(利用可能な場合)

  • City: 都市名

  • Region: 地域名

  • Country: 国名

  • Org: 組織名(通常はISP)

以下は、生成されるCSVファイルの出力例です:

ip,hostname,city,region,country,org
192.0.2.1,example1.com,New York,NY,US,AS12345 Example ISP
192.0.2.2,example2.net,London,England,GB,AS67890 Another ISP
192.0.2.3,example3.org,Tokyo,Tokyo,JP,AS11111 Third ISP
192.0.2.4,,Sydney,New South Wales,AU,AS22222 Fourth ISP
192.0.2.5,example5.com,Berlin,Berlin,DE,AS33333 Fifth ISP

注意事項

  • このスクリプトはipinfo.io APIを使用しています。大量のIPアドレスを処理する場合、実行に時間がかかる可能性があります。また、レート制限にご注意ください。

  • APIキーを使用していないため、無料版のAPIの制限に従います。より多くのリクエストや追加情報が必要な場合は、有料のAPIキーを取得して使用することを検討してください。

トラブルシューティング

  1. PermissionError: アクセスログファイルを読み取れない場合、適切な権限があることを確認してください。

  2. APIエラー: インターネット接続を確認し、ipinfo.io APIが利用可能であることを確認してください。

  3. 出力エラー: OUTPUT_FILEのパスが正しく、書き込み権限があることを確認してください。

カスタマイズ

  • 必要に応じて、get_ip_info 関数を修正して、異なるAPIや情報源を使用できます。

  • CSVに追加の情報を含めたい場合は、get_ip_info 関数と create_csv 関数を適宜修正してください。

スクリプト全文

以下に、スクリプト全文を示します。このスクリプトを ip_info_csv_generator.py という名前で保存し、上記の説明に従って使用してください。

"""
このスクリプトは、ログファイルからユニークなIPアドレスを抽出し、ipinfo.io APIを使用して
各IPアドレスの情報を取得し、収集したデータをCSVファイルに出力します。

使用方法:
    1. 必要なライブラリ(requests)がインストールされていることを確認してください。
    2. INPUT_FILEとOUTPUT_FILE変数を適切なパスに設定してください。
    3. スクリプトを実行してください。

注意: このスクリプトはipinfo.io APIを使用しており、レート制限がある場合があります。
      負荷軽減のためリクエスト間に1秒の遅延を実装しています。
"""

import re
import csv
import requests
import time
from collections import defaultdict

INPUT_FILE = '/var/log/nginx/access.log'
OUTPUT_FILE = '/path/to/your/output/ip_info.csv'

def extract_unique_ips(file_path):
    """
    ログファイルからユニークなIPアドレスを抽出します。

    引数:
        file_path (str): ログファイルのパス

    戻り値:
        list: ファイル内で見つかったユニークなIPアドレスのリスト
    """
    ip_counts = defaultdict(int)
    ip_pattern = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
    
    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            match = re.search(ip_pattern, line)
            if match:
                ip = match.group()
                ip_counts[ip] += 1
    
    return list(ip_counts.keys())

def get_ip_info(ip):
    """
    ipinfo.io APIを使用してIPアドレスの情報を取得します。

    引数:
        ip (str): 検索するIPアドレス

    戻り値:
        dict: IPアドレスに関する情報を含む辞書。取得に失敗した場合はNone。
    """
    url = f"https://ipinfo.io/{ip}/json"
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        return {
            'ip': ip,
            'hostname': data.get('hostname', ''),
            'city': data.get('city', ''),
            'region': data.get('region', ''),
            'country': data.get('country', ''),
            'org': data.get('org', '')
        }
    return None

def create_csv(ips, output_file):
    """
    IPアドレスの情報をCSVファイルに出力します。

    引数:
        ips (list): IPアドレスのリスト
        output_file (str): 出力するCSVファイルのパス
    """
    fieldnames = ['ip', 'hostname', 'city', 'region', 'country', 'org']
    
    with open(output_file, 'w', newline='', encoding='utf-8-sig') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        
        for ip in ips:
            ip_info = get_ip_info(ip)
            if ip_info:
                writer.writerow(ip_info)
            time.sleep(1)  # 負荷軽減

def main():
    """
    メイン関数:ユニークなIPアドレスを抽出し、情報を取得してCSVファイルに出力します。
    """
    print("ユニークなIPアドレスを抽出中...")
    unique_ips = extract_unique_ips(INPUT_FILE)
    print(f"{len(unique_ips)}個のユニークなIPアドレスが見つかりました。")
    
    print("IP情報を取得してCSVファイルを作成中...")
    create_csv(unique_ips, OUTPUT_FILE)
    print(f"CSVファイル '{OUTPUT_FILE}' が正常に作成されました。")

if __name__ == "__main__":
    main()

このスクリプトを使用する際は、必ず INPUT_FILE と OUTPUT_FILE の値を適切に設定してください。また、スクリプトを実行する前に、必要な権限とライブラリがインストールされていることを確認してください。

いいなと思ったら応援しよう!