Bro 네트워크 로그 구문 분석 스크립트를 최적화하는 데 도움을 찾고 있습니다. 배경은 다음과 같습니다.
나는 수많은 형제 로그를 가지고 있지만 내 범위(다중 가변 길이 서브넷)의 IP를 쿼리하는 데에만 관심이 있습니다.
그래서 내가 찾고 있는 IP 범위와 일치하는 정규식 패턴이 포함된 텍스트 파일이 있습니다.
/^10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5])$/
(scope.txt에는 정규식 패턴의 추가 IP 범위에 대한 최대 20줄이 포함되어 있습니다.) findInScope.sh:
#!bin/sh
for file in /data/bro_logs/2016-11-26/conn.*.log.gz
do
echo "$file"
touch /tmp/$file
for nets in $(cat scope.txt)
do
echo "$nets"
zcat $file | bro-cut -d | awk '$3 ~ '$nets' || $5 ~ '$nets'' >> /tmp/$file
done
sort /tmp/$file | uniq > ~/$file
rm /tmp/$file
done
추가 배경 지식으로 원시 bro conn 로그는 시간당 약 100MB이므로 현재 스크립트는 1시간 분량의 로그 데이터를 구문 분석하는 데 약 10-20분이 걸립니다. 하루의 기록은 최대 3시간이 걸릴 수 있습니다.
나는 40개의 단일 awk 문을 사용하는 것을 고려했지만, 다른 IP 범위에 대해 동일한 스크립트를 사용할 수 있도록 별도의scope.txt 파일을 원했기 때문에 그렇게 하지 않기로 결정했습니다.
또한 여러 conn.log 파일(예: zcat conn.*.log.gz)에서 zcat를 시도했지만 출력 파일이 1GB를 초과하여 시간별 로그를 그대로 유지하고 싶었습니다.
답변1
awk를 통해 로그 파일을 한 번만 전달하면 많은 이점을 얻을 수 있습니다. 이는 모든 정규 표현식을 하나로 결합하는 것을 의미합니다. scope.txt
파일에서 이 작업을 수행 하지 않으려면 awk를 호출하기 전에 수행하십시오. 예를 들어,
sed <scope.txt 's|^/\^|(|; s|\$/$|)|; $!s/$/|/' | tr -d '\n' >pattern
zcat $file | bro-cut -d |
awk '
BEGIN{ getline pat <"pattern"; pat = "^(" pat ")$" }
$3 ~ pat || $5 ~ pat
' >~/$file
sed는 각 정규식 줄 주변의 합계를 닫는 쌍으로 /^
바꾸고 줄 끝에 1을 추가한 다음 한 줄의 결과를 모두 파일에 저장합니다. 따라서 파일은 모두 OR로 연결된 패턴입니다. 누락된 콘텐츠는 스키마 파일을 변수로 읽는 awk 스크립트 문에 추가됩니다.$
()
|
pattern
^(...)$
BEGIN
pat
위의 내용은 내부 for
루프를 대체하고 sort|uniq
.
답변2
scope.txt
가장 간단한 대답은 약간 수정된 파일을 스키마 파일로 사용 하고 zcat | grep
(또는 그냥 zgrep
)을 사용하여 필요한 라인을 얻는 것입니다.
먼저 scope
파일을 수정하여 다음을 변경합니다.
/^10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5])$/
입력하다:
(^|[^0-9.])(10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5]))($|[^0-9.])
이 작업을 쉽게 수행하려면 다음을 사용할 수 있습니다.
sed -e 's:^/\^:(^|[^0-9.])(:' -e 's:\$/$:)($|[^0-9.]):' scope.txt > grepscope.txt
그런 다음 다음을 검색하세요.
zgrep -Ehf grepscope.txt /data/bro_logs/2016-11-26/conn.*.log.gz | less
또는 각 파일의 출력을 별도로 저장하기를 원하기 때문에:
for f in /data/bro_logs/2016-11-26/conn.*.log.gz; do
zgrep -Ehf grepscope.txt "$f" | sort -u > ~/"${f##*/}"
done
또한 "for" 루프 변수에는 다음이 $f
포함됩니다.모두각 파일의 경로를 차례로 지정합니다. ~/"$f"
(존재하지 않을 수 있는 홈 디렉터리의 하위 디렉터리를 참조하는) 출력을 지시할 때 오류를 방지하기 위해 ~/data/bro_logs/2016-11-26
경로 이름에서 마지막 슬래시 앞의 모든 항목을 제거하고 기본 이름만 사용합니다. 각 로그 파일.
언급할만한 징후 zgrep
:
-E
패턴의 괄호를 이스케이프할 필요가 없도록 확장 정규식을 지정합니다.
-h
일치하는 각 줄의 접두어로 파일 이름을 인쇄하지 않습니다. ( for
루프 버전에서는 이 옵션을 생략할 수 있습니다. 기본적으로 grep
제가 지정한 첫 번째 명령에서처럼 여러 파일을 검색할 때 파일 이름만 인쇄하지만 두 버전 모두에 그대로 놔둬도 손상이 발생하지 않기 때문입니다.)
-f
당신이 할 수 있도록스키마 파일을 지정합니다. 귀하의 질문에 따르면 이것이 바로 귀하에게 필요한 것이며 을 사용하면 grep -f
많은 "or"가 포함된 Awk 명령을 작성할 필요 없이 파일에서 가져온 여러 검색 패턴을 사용할 수 있습니다.
sort | uniq
특정 옵션 플래그를 sort -u
사용해야 하는 경우가 아니면 일반적으로 로 대체할 수 있습니다 . uniq
이 경우에는 그럴 필요가 없으므로 더 간단한 형식을 사용했습니다 sort -u
.