giải quyết tất cả các địa chỉ IP trong đầu ra lệnh bằng cách sử dụng các công cụ dòng lệnh tiêu chuẩn


8

Tôi có một số tệp nhật ký có chứa một loạt các địa chỉ IP. Tôi rất thích có thể dẫn dữ liệu qua một chương trình phù hợp và giải quyết các địa chỉ IP.

IE mèo / var / log / somelogfile | tổ chức

mà sẽ biến một dòng như

10:45 được truy cập bởi 10.13.13.10

vào

10:45 được truy cập bởi myhostname.intranet

Tôi nghĩ có thể có một cách để làm điều này với sự kết hợp giữa sed và host, nhưng tôi không biết làm thế nào để làm điều đó. Tôi biết rằng tôi có thể viết một kịch bản đơn giản để làm điều đó, nhưng tôi muốn sử dụng các công cụ tích hợp nếu có thể. Bất kỳ đề xuất?


2
Lý do điều này thường không được thực hiện là vì có thể khá chậm để thực hiện tất cả các truy vấn PTR đó. Một tập lệnh đa luồng (ví dụ: Python) lưu trữ kết quả (có thể liên tục) sẽ hoạt động tốt nhất.
Alexios

Câu trả lời:


8

Đây là một giải pháp nhanh chóng và bẩn thỉu cho vấn đề này trong Python. Nó thực hiện bộ nhớ đệm (bao gồm cả bộ nhớ đệm âm), nhưng không phân luồng và không phải là thứ nhanh nhất bạn thấy. Nếu bạn lưu nó như một cái gì đó như thế rdns, bạn có thể gọi nó như thế này:

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

Chạy nó sẽ chú thích các địa chỉ IP với bản ghi PTR của chúng tại chỗ:

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

Và đây là nguồn:

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

Xin lưu ý: đây không hoàn toàn là những gì bạn viết sau bức thư (sử dụng 'công cụ tiêu chuẩn'). Nhưng nó có thể giúp bạn nhiều hơn một bản hack giải quyết mọi địa chỉ IP mỗi khi gặp phải. Với một vài dòng nữa, bạn thậm chí có thể làm cho nó lưu trữ kết quả của nó một cách liên tục, điều này sẽ giúp với các yêu cầu lặp lại.


Cảm ơn kịch bản. Nó làm chính xác những gì tôi đang tìm kiếm. Tôi đã hy vọng tìm ra một giải pháp không yêu cầu viết kịch bản, nhưng đây có lẽ là điều tốt nhất tiếp theo.
Daniel

3

Tôi sẽ sử dụng jdresolve -n -a

Đóng gói cho debian, vv cũng có sẵn tại:

https://github.com/jdrowell/jdresolve

    jdresolve phân giải địa chỉ IP thành tên máy chủ. Bất kỳ định dạng tập tin là
    được hỗ trợ, bao gồm cả những nơi mà dòng không bắt đầu bằng IP
    Địa chỉ.

Tôi đã sử dụng nó trong hơn một thập kỷ để giải quyết các bản ghi apache, nhật ký mực và bất cứ thứ gì khác có nhiều địa chỉ IP cần giải quyết. Nó hoạt động tốt, đáng tin cậy và nhanh chóng, và nó có thể lưu trữ tra cứu bộ đệm từ các lần chạy trước.


2

một tập lệnh bash bạn có thể đưa tệp logfile của bạn và đặt vào.

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

đầu ra trông như:

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

Một cách nhanh chóng:

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

1

Nếu định dạng nhật ký luôn hiển thị giống như bạn hiển thị ở trên, bạn có thể làm điều này thực sự bẩn với echo 10:45 accessed by 10.13.13.10|awk '{print $4}'|nslookup

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.