risolvere tutti gli indirizzi IP nell'output dei comandi utilizzando gli strumenti della riga di comando standard


8

Ho diversi file di registro che contengono un sacco di indirizzi IP. Mi piacerebbe essere in grado di reindirizzare i dati attraverso un programma che corrisponderebbe e risolverà gli indirizzi IP.

IE cat / var / log / somelogfile | ospite

che avrebbe trasformato una linea come

10:45 accesso entro il 10.13.13.10

in

10:45 accessibile da myhostname.intranet

Il mio pensiero è che potrebbe esserci un modo per farlo con una combinazione di sed e host, ma non ho idea di come farlo. So che potrei scrivere un semplice script che lo farebbe, ma preferirei essere in grado di utilizzare strumenti integrati, se possibile. Eventuali suggerimenti?


2
Il motivo per cui ciò non avviene normalmente è perché può essere piuttosto lento eseguire tutte quelle query PTR. Uno script multi-thread (in, ad esempio Python) che memorizza nella cache i risultati (possibilmente in modo persistente) funzionerebbe meglio.
Alexios,

Risposte:


8

Ecco una soluzione rapida e sporca a questo in Python. Fa il caching (incluso il caching negativo), ma non il threading e non è la cosa più veloce che tu abbia mai visto. Se lo salvi come qualcosa del genere rdns, puoi chiamarlo così:

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

L'esecuzione annoterà gli indirizzi IP con i loro record PTR sul posto:

$ 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).

Ed ecco la fonte:

#!/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.

Nota: questo non è esattamente ciò che stai cercando nella lettera (usando "strumenti standard"). Ma probabilmente ti aiuta più di un hack che risolve ogni indirizzo IP ogni volta che viene rilevato. Con poche altre righe, puoi persino far sì che i risultati della cache vengano memorizzati in modo persistente, il che aiuterebbe a ripetere le chiamate.


Grazie per la sceneggiatura. Fa esattamente quello che stavo cercando. Speravo di trovare una soluzione che non richiedesse la scrittura di una sceneggiatura, ma questa è probabilmente la cosa migliore dopo.
Daniel,

3

Vorrei usare jdresolve -n -a

Confezionato per debian, ecc. Disponibile anche su:

https://github.com/jdrowell/jdresolve

    jdresolve risolve gli indirizzi IP in nomi host. Qualsiasi formato di file è
    supportato, inclusi quelli in cui la linea non inizia con l'IP
    indirizzo.

Lo uso da oltre un decennio per risolvere i log di apache, i calamari e qualsiasi altra cosa con molti indirizzi IP che devono essere risolti. Funziona bene, in modo affidabile e veloce e può memorizzare nella cache le ricerche delle precedenti esecuzioni.


2

uno script bash in cui puoi inserire il tuo file di log e pipe.

#!/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"

l'output è simile a:

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 

2

Uno veloce perl uno:

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

1

Se il formato del registro viene visualizzato costantemente come mostrato sopra, puoi farlo davvero sporco echo 10:45 accessed by 10.13.13.10|awk '{print $4}'|nslookup

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.