menyelesaikan semua alamat ip dalam output perintah menggunakan alat baris perintah standar

8

Saya memiliki beberapa file log yang berisi banyak alamat ip. Saya akan senang dapat menyalurkan data melalui program yang akan cocok dan menyelesaikan alamat ip.

Yaitu cat / var / log / somelogfile | tuan rumah

yang akan mengubah garis seperti

10:45 diakses oleh 10.13.13.10

ke

10:45 diakses oleh myhostname.intranet

Pikir saya mungkin ada cara untuk melakukan ini dengan kombinasi sed dan host, tetapi saya tidak tahu bagaimana melakukannya. Saya tahu bahwa saya bisa menulis skrip sederhana yang akan melakukannya, tetapi saya lebih suka dapat menggunakan alat bawaan jika memungkinkan. Ada saran?

Daniel
sumber
2
Alasan ini biasanya tidak dilakukan adalah karena bisa sangat lambat untuk melakukan semua pertanyaan PTR itu. Skrip multi-utas (dalam, misalnya Python) yang menyimpan hasil (mungkin secara terus-menerus) akan bekerja paling baik.
Alexios

Jawaban:

8

Berikut ini adalah solusi cepat dan kotor untuk ini dengan Python. Itu caching (termasuk caching negatif), tetapi tidak ada threading dan bukan hal tercepat yang pernah Anda lihat. Jika Anda menyimpannya sebagai sesuatu seperti rdns, Anda dapat menyebutnya seperti ini:

zcat /var/log/some-file.gz | rdns
# ... or ...
rdns /var/log/some-file /var/log/some-other-file # ...

Menjalankannya akan membubuhi keterangan alamat IP dengan catatan PTR mereka di tempat:

$ echo "74.125.132.147, 64.34.119.12." | rdns
74.125.132.147 (rdns: wb-in-f147.1e100.net), 64.34.119.12 (rdns: stackoverflow.com).

Dan inilah sumbernya:

#!/usr/bin/env python

import sys, re, socket

cache = dict()

def resolve(x):
    key = x.group(0)
    try:
        return "%s (rdns: %s)" % (key, cache[key])
    except KeyError:
        try:
            cache[key] = socket.gethostbyaddr(key)[0]
        except socket.herror:
            cache[key] = '?'
        return "%s (rdns: %s)" % (key, cache[key])

for f in [open(x) for x in sys.argv[1:]] or [sys.stdin]:
    for line in f:
        sys.stdout.write(re.sub("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", resolve, line))

# End of file.

Harap dicatat: ini bukan yang Anda harapkan dari surat itu (menggunakan 'alat standar'). Tapi itu mungkin membantu Anda lebih dari peretasan yang menyelesaikan setiap alamat IP setiap kali itu ditemui. Dengan beberapa baris lagi, Anda bahkan dapat membuatnya cache hasilnya secara terus-menerus, yang akan membantu dengan pemanggilan berulang.

Alexios
sumber
Terima kasih untuk skripnya. Itu tidak persis apa yang saya cari. Saya berharap menemukan solusi yang tidak memerlukan penulisan skrip, tetapi ini mungkin yang terbaik berikutnya.
Daniel
3

Saya akan menggunakan jdresolve -n -a

Dikemas untuk debian, dll. Juga tersedia di:

https://github.com/jdrowell/jdresolve

    jdresolve menyelesaikan alamat IP ke nama host. Semua format file
    didukung, termasuk yang jalurnya tidak dimulai dengan IP
    alamat.

Saya telah menggunakannya selama lebih dari satu dekade untuk menyelesaikan log apache, squid log, dan apa pun dengan banyak alamat IP yang perlu diselesaikan. Ini berfungsi dengan baik, andal, dan cepat, dan itu bisa cache pencarian dari berjalan sebelumnya.

cas
sumber
2

skrip bash yang bisa digunakan untuk menyimpan logfile Anda.

#!/bin/bash

while read input; do

    for arg in $( echo $input ); do
            match=$(echo "$arg" | grep -P '([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])' )
            if [ "x${match}" = "x" ]; then
                    printf "%-s" "$arg "
            else
                    dns=$( host $arg | tail -1 | awk '{print $NF}' 2>/dev/null )
                    if [ "${dns}" == "3(NXDOMAIN)" ]; then
                            printf "%-s" "$arg "
                    else
                            if [ "x${dns}" == "x" ]; then
                                    printf "%-s" "$arg "
                            else
                                    printf "%-s" "$dns "
                            fi
                    fi
            fi
    done
done
printf "\n"

output terlihat seperti:

tk-air:~ tim$ echo "10:45 accessed by 8.8.8.8" | ./get-dns 
10:45 accessed by FWDR-8.FWDR-8.FWDR-8.FWDR-8. 

tk-air:~ tim$ echo "10:45 accessed by 8.8.8.8 26 times" | ./get-dns 
10:45 accessed by FWDR-8.FWDR-8.FWDR-8.FWDR-8. 26 times 
Tim Kennedy
sumber
2

Perl cepat:

perl -MSocket -pe 's/(\d+\.){3}\d+/"$&\[".gethostbyaddr(inet_aton($&), AF_INET)."]"/ge'
Stéphane Chazelas
sumber
1

Jika format log secara konsisten menampilkan sama seperti yang Anda tunjukkan di atas, Anda dapat melakukan ini dengan sangat kotor echo 10:45 accessed by 10.13.13.10|awk '{print $4}'|nslookup

Tim
sumber