resolve todos os endereços IP na saída do comando usando ferramentas de linha de comando padrão

8

Eu tenho vários arquivos de log que contêm um monte de endereços IP. Eu adoraria poder enviar os dados por meio de um programa que correspondesse e resolvesse os endereços IP.

I.E. cat / var / log / somelogfile | host

que se tornaria uma linha como

10:45 accessed by 10.13.13.10

em

10:45 accessed by myhostname.intranet

Meu pensamento é que pode haver uma maneira de fazer isso com uma combinação de sed e host, mas não tenho idéia de como fazê-lo. Eu sei que eu poderia escrever um script simples que faria isso, mas eu preferiria ser capaz de usar ferramentas embutidas, se possível. Alguma sugestão?

    
por Daniel 18.06.2012 / 19:33

5 respostas

8

Aqui está uma solução rápida e suja para isso em Python. Ele faz cache (incluindo caching negativo), mas não tem threads e não é a coisa mais rápida que você já viu. Se você salvá-lo como algo como rdns , pode chamá-lo assim:

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

Em execução, anotará os endereços IP com seus registros PTR no local:

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

E aqui está a 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.

Por favor, note: não é bem isso que você procura (usando "ferramentas padrão"). Mas provavelmente ajuda mais do que um hack que resolve todos os endereços IP sempre que é encontrado. Com mais algumas linhas, você pode até fazer cache de seus resultados de forma persistente, o que ajudaria com repetidas invocações.

    
por 18.06.2012 / 20:21
3

Eu usaria jdresolve -n -a

Empacotado para o debian, etc. também disponível em:

link

    jdresolve resolves IP addresses to hostnames. Any file format is
    supported, including those where the line does not begin with the IP
    address.

Estou usando isso há mais de uma década para resolver logs do apache, logs do squid e qualquer outra coisa com muitos endereços IP que precisam ser resolvidos. Ele funciona bem, de maneira confiável e rápida, e pode armazenar em cache pesquisas de execuções anteriores.

    
por 26.09.2012 / 12:20
2

um script bash você pode cat seu arquivo de log e pipe em.

#!/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"
A saída

se parece com:

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 
    
por 18.06.2012 / 23:42
2

Um rápido perl:

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

Se o formato de log estiver exibindo consistentemente o mesmo que você mostra acima, você pode fazer isso muito sujo com echo 10:45 accessed by 10.13.13.10|awk '{print $4}'|nslookup

    
por 18.06.2012 / 20:19