разрешить все IP-адреса в выводе команды, используя стандартные инструменты командной строки

8

У меня есть несколько файлов журнала, которые содержат несколько IP-адресов. Я хотел бы иметь возможность передавать данные через программу, которая будет сопоставлять и разрешать IP-адреса.

IE cat / var / log / somelogfile | хозяин

что бы повернуть линию как

10:45 доступно 10.13.13.10

в

10:45 доступ к myhostname.intranet

Я думаю, что может быть способ сделать это с помощью комбинации sed и host, но я понятия не имею, как это сделать. Я знаю, что мог бы написать простой скрипт, который бы это делал, но я бы предпочел использовать встроенные инструменты, если это возможно. Какие-либо предложения?

Даниил
источник
2
Причина, по которой это обычно не делается, заключается в том, что все эти запросы PTR могут выполняться довольно медленно. Многопоточный скрипт (например, Python), который кэширует результаты (возможно, постоянно), будет работать лучше всего.
Алексиос

Ответы:

8

Вот быстрое и грязное решение этого в Python. Он выполняет кэширование (включая отрицательное кэширование), но не использует многопоточность и не является самой быстрой вещью, которую вы видели. Если вы сохраните его как-то так rdns, вы можете назвать его так:

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

Его запуск аннотирует IP-адреса с их записями PTR:

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

И вот источник:

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

Обратите внимание: это не совсем то, что вы ищете после письма (используя «стандартные инструменты»). Но это, вероятно, поможет вам больше, чем взлом, который разрешает каждый IP-адрес каждый раз, когда он встречается. Имея еще несколько строк, вы даже можете сделать так, чтобы он постоянно кэшировал свои результаты, что поможет при повторных вызовах.

Алексиос
источник
Спасибо за сценарий. Это именно то, что я искал. Я надеялся найти решение, которое не требовало бы написания сценария, но это, вероятно, следующая лучшая вещь.
Даниэль
3

Я бы использовал jdresolve -n -a

Пакет для Debian и т. Д. Также доступен по адресу:

https://github.com/jdrowell/jdresolve

    jdresolve разрешает IP-адреса в имена хостов. Любой формат файла
    поддерживается, в том числе те, где строка не начинается с IP
    адрес.

Я использую его более десяти лет для разрешения логов apache, логов squid и всего остального с большим количеством IP-адресов, которые необходимо разрешить. Он работает хорошо, надежно и быстро, и может кэшировать результаты поиска из предыдущих запусков.

саз
источник
2

bash-скрипт, в который вы можете добавить свой лог-файл

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

вывод выглядит так:

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

Быстрый Perl один:

perl -MSocket -pe 's/(\d+\.){3}\d+/"$&\[".gethostbyaddr(inet_aton($&), AF_INET)."]"/ge'
Стефан Шазелас
источник
1

Если формат журнала постоянно отображается так же, как показано выше, вы можете сделать это действительно грязно с echo 10:45 accessed by 10.13.13.10|awk '{print $4}'|nslookup

Тим
источник