텍스트처리_11 시스템 로그에서 IP 주소마다 횟수 집계하기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: sed, sort, uniq
키워드: SSH, 부정 접속, 인증 실패, 로그 추출
사용처: sshd 로그 파일에서 암호 인증에 실패한 IP 주소를 세고 싶을 때


실행예제

# ./ssh-fail.sh
15  10.211.55.2
 6  10.211.55.21
 2  10.211.55.18

접속해온 IP 주소마다 ssh 암호 인증에 실패한 횟수가 많은 순서로 표시

스크립트

#!/bin/sh

# sshd 로그 파일
securelog="/var/log/secure"

# IP 주소를 추출하기 위한 패턴. 변수에 저장
pattern="^.*sshd\[.*\].*Failed password for.* from \(.*\) port .*"  #--- 1

# 암호 인증 실패 로그에서 IP 주소를 추출, 카운트해서 표시
sed -n "s/$pattern/\1/p" "$securelog" | sort | uniq -c | sort -nr #-=--- 2

   

해설

이 스크립트는 sshd 로그(/var/log/secure)에서 암호 인증에 실패한 로그를 추출해서 해당 IP 주소가 몇 번 나오는지 카운트한 값을 표시합니다.

인터넷에 ssh 접속 가능 서버를 설치해두면 브루트포스 어택(무작위로 암호를 대입하는 공격)이 들어오는 것이 일상다반사입니다. 따라서 이런 로그 확인 스크립트를 설치해서 암호 인증에 실패한 접속을 정기적으로 출력해서 부정 접속 감시에 사용하면 좋습니다.

ssh 접속 로그는 리눅스 서버라면 /var/log/secure에, FreeBSD라면 /var/log/auth.log에 출력되며 다음과 같은 형식입니다.

  • 파일1 ssh 접속 로그 예
    Jan 3 21:40:00 cent unix_chkpwd[1480]: password check failed for user (user1)
    Jan 3 21:40:00 cent sshd[1478]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser=rhost=10.211.55.2 user=user1
    Jan 3 21:40:02 cent sshd[1478]: Failed password for user1 from 10.211.55.2 port 53639 ssh2
    Jan 3 21:40:05 cent sshd[1479]: Connection closed by 10.211.55.2
    

“Failed password for user1 from …” 부분이 암호 인증에 실패했다는 의미이므로 이것을 바탕으로 카운트합니다. ssh는 키 인증 같은 다양한 인증 방법이 있으므로 출력된 로그 메시지도 환경에 따라 달라집니다. 패턴에 일치한 문자열은 환경에 따라 적절히 변경해야 합니다.

이 예제에서 다루는 로그 파일은 “Failed password for user1 from 10.211.55.2”처럼 from 뒤에 IP 주소가 들어 있으므로 이것을 추출합니다. 패턴 일치 문자열이 길어지므로 1에서 패턴을 셸 변수에 저장합니다. 긴 패턴을 이렇게 셸 변수에 입력해두면 sed 명령어를 보기 쉽습니다.

2에서 접속 IP 주소를 추출하기 위해 sed 명령어로 일치한 부분만 표시하는 -n 옵션p 플래그를 조합합니다. 또한 동시에 후방참조를 써서 “from (.*)“라고 from 뒷부분 문자열을 \1로 참조해서 출력하므로 로그 파일에서 IP 주소를 추출합니다.

2에서 sed 명령어 출력을 파이프로 sort 명령어와 uniq 명령어에 넘깁니다. 우선 첫 번째 sort 명령어로 IP 주소를 기준으로 정렬한 다음 uniq 명령행 수를 세는 -c 옵션을 이용해서 동일한 줄의 출현 회수를 셉니다.

그리고 2에서는 파이프 마지막에 한 번 더 sort 명령어 -n 옵션(숫자 정렬)과 -r 옵션(역순 정렬)을 써서 접속 수가 많았던 순서대로 표시합니다. 이런 "sort | uniq -c | sort -nr"은 텍스트 처리에서 자주 사용하는 관용구이므로 기억해두기 바랍니다.

$ cat log.txt
 2	10.211.5.18
15	10.211.55.2
 6	10.211.55.21

$ sort -nr log.txt
15	10.211.55.2
 6	10.211.55.21
 2	10.211.5.18

이렇게 해서 IP 주소마다 접속 수를 조사할 수 있습니다. 이 예제에서는 sshd 로그를 사용하지만 그 외의 부정 접속 횟수 등을 감시하기 위한 로그 파일 추출에도 유용합니다.

ssh 부정 접속이란

sshd를 다루고 있으므로 부정 접속에 대해 조금 알아보겠습니다. 요즘은 클라우드나 VPS를 이용해서 간단한 서버를 구축할 수 있으므로 이런 서버에 부정 접속도 급증하고 있습니다. 특히 공격자가 ssh 부정 로그인에 성공하면 손쉽게 공격용 숙주로 사용되므로 주의가 필요합니다 ssh 보안 대책은 다음과 같습니다.

  1. 포트 번호를 기본값 22/tcp에서 변경
  2. 공개키 인증을 사용한 암호 입력 금지
  3. iptables을 사용한 접속 IP 주소 제한

그리고 여기에서 다룬 로그 감시도 병행해서 부정 침입이 없었는지 정기적으로 확인하는 것이 좋습니다.

   

주의사항

  • /var/log/secure는 보통 root 사용자만 읽을 수 있으므로 이 스크립트도 root 권한으로 실행해야 합니다.

  • 같은 커넥션으로 여러 번 접속해보거나 짧은 시간에 여러 번 반복해서 접속하면 로그 출력에 “3 more authentication failure” 같이 하나로 뭉쳐서 출력됩니다. 따라서 여기서 사용한 횟수는 정확한 부정 접속 횟수가 아니라 어림잡은 숫자로 생각하기 바랍니다.