표준 명령줄 도구를 사용하여 명령 출력의 모든 IP 주소를 구문 분석합니다.

표준 명령줄 도구를 사용하여 명령 출력의 모든 IP 주소를 구문 분석합니다.

많은 수의 IP 주소가 포함된 로그 파일이 여러 개 있습니다. IP 주소를 일치시키고 확인할 수 있는 프로그램을 통해 데이터를 전송할 수 있기를 원합니다.

IE 고양이 /var/log/somelogfile |

이것은 선이 될 것입니다

10:45에 10.13.13.10에 액세스함

입력하다

10:45 myhostname.intranet을 통해 액세스됨

내 생각에는 sed와 호스트의 조합을 사용하여 이 작업을 수행할 수 있는 방법이 있을 수 있지만 방법은 모르겠습니다. 이를 수행하기 위해 간단한 스크립트를 작성할 수 있다는 것을 알고 있지만 가능하다면 내장 도구를 사용하고 싶습니다. 어떤 제안이 있으십니까?

답변1

Python의 빠르고 더러운 솔루션은 다음과 같습니다. 캐싱(네거티브 캐싱 포함)을 수행하지만 스레드는 없으며 지금까지 본 것 중 가장 빠른 것도 아닙니다. 비슷한 이름으로 저장하면 rdns다음과 같이 호출할 수 있습니다.

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

이를 실행하면 PTR 레코드로 IP 주소에 주석이 추가됩니다.

$ 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 주소를 만날 때마다 이를 구문 분석하는 것보다 더 많은 도움이 될 수 있습니다. 몇 줄만 더 추가하면 결과를 지속적으로 캐시하도록 할 수도 있어 반복 호출에 도움이 됩니다.

답변2

나는 사용할 것이다jdresolve -n -a

데비안 등을 위한 패키지도 다음에서 구할 수 있습니다:

https://github.com/jdrowell/jdresolve

    jdresolve는 IP 주소를 호스트 이름으로 확인합니다. 모든 파일 형식은
    회선이 IP로 시작하지 않는 경우를 포함하여 지원됨
    주소.

나는 아파치 로그, 오징어 로그 및 많은 수의 IP 주소가 있는 구문 분석이 필요한 모든 항목을 구문 분석하는 데 10년 넘게 이를 사용해 왔습니다. 잘 작동하고, 안정적이고 빠르며, 이전에 실행한 조회를 캐시할 수 있습니다.

답변3

로그 파일 및 파이프 입력을 캡처할 수 있는 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 

답변4

로그 형식이 항상 위에 표시된 것과 동일하게 표시되면 다음 명령을 사용하여 그렇게 할 수 있습니다.echo 10:45 accessed by 10.13.13.10|awk '{print $4}'|nslookup

관련 정보