Find top IP in access log

By.

min read

My profile

Share this:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

Source: https://www.tecmint.com/find-top-ip-address-accessing-apache-web-server/

Get top /24 for ipv4

#!/usr/bin/env python3
"""
Find top /24 subnets from a file of IPv4 addresses (one per line).
Usage: python3 top_subnets.py <file> [--top N]
"""

import sys
import argparse
from collections import Counter

def get_24_subnet(ip: str) -> str | None:
    parts = ip.strip().split(".")
    if len(parts) != 4:
        return None
    try:
        if all(0 <= int(p) <= 255 for p in parts):
            return f"{parts[0]}.{parts[1]}.{parts[2]}.0/24"
    except ValueError:
        pass
    return None

def main():
    parser = argparse.ArgumentParser(description="Find top /24 subnets from a list of IPs.")
    parser.add_argument("file", help="Path to the file (one IPv4 per line)")
    parser.add_argument("--top", type=int, default=10, help="Number of top subnets to show (default: 10, 0 = all)")
    args = parser.parse_args()

    counter = Counter()
    skipped = 0

    with open(args.file) as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith("#"):
                continue
            subnet = get_24_subnet(line)
            if subnet:
                counter[subnet] += 1
            else:
                skipped += 1

    total_ips = sum(counter.values())
    top_n = args.top if args.top > 0 else len(counter)
    results = counter.most_common(top_n)

    print(f"{'Rank':<6} {'Subnet':<20} {'Count':>8}  {'% of IPs':>10}")
    print("-" * 50)
    for rank, (subnet, count) in enumerate(results, 1):
        pct = count / total_ips * 100
        print(f"{rank:<6} {subnet:<20} {count:>8}  {pct:>9.2f}%")

    print("-" * 50)
    print(f"Total unique /24 subnets : {len(counter)}")
    print(f"Total valid IPs          : {total_ips}")
    if skipped:
        print(f"Skipped (invalid lines)  : {skipped}")

if __name__ == "__main__":
    main()

Get top /20 for ipv6

THRESHOLD=10

# 1. Count uniques
sort acces.log | uniq -c > ips_count.txt

# 2. Create /20 blocks without strtonum()
awk -v t="$THRESHOLD" '{
    count = $1
    ip = $2
    split(ip, h, ":")
    h1 = h[1]
    # Bash-style hex AND: printf + substr
    cmd = "printf \"%x\" $((0x" h[2] " & 0xF0))"
    cmd | getline h2_prefix
    close(cmd)
    block = h1 ":" h2_prefix "::/20"
    blocks[block] += count
}
END {
    for (b in blocks)
        if (blocks[b] >= t)
            print blocks[b], b
}' ips_count.txt | sort -nr | head -50
Share this:

Leave a Reply

Your email address will not be published. Required fields are marked *