어떤 IP에서 가장많이 접속했는지 확인

필자는 개인 IIS 웹서버를 운영하고 있음

다음을 통해 웹서버에서 하둡이 설치된 우분투 리눅스로 가져오고 HDFS로 복사(파일 복사가 RDB에서는 insert에 해당한다)

# 웹서버에서 하둡이설치된 리눅스로 로그파일들 복사
scp linowmik@secsm.org@192.168.0.6:/inetpub/logs/LogFiles/W3SVC1/* ./iis_logs

# HDFS로 복사
hdfs dfs -put ./iis_logs/* /logs/

# 위 복사가 너무 오래걸리면 아래 명령을 통해 진행상황 모니터링 가능
cd $HADOOP_HOME/logs
sudo tail -f $(ls -Art $HADOOP_HOME/logs | tail -n 1)
# 위명령어 설명은 다음과 같음
# ls -Art $HADOOP_HOME/logs: $HADOOP_HOME/logs 디렉토리 내의 파일을 날짜별로 오름차순 정렬합니다. -Art 옵션은 -A (숨겨진 파일 포함), -r (역순), -t (수정 시간별 정렬) 옵션을 동시에 사용하는 것입니다.
# tail -n 1: 파일 리스트 중에서 가장 최신의 파일 (리스트의 마지막 항목)을 선택합니다.
# tail -f: 선택한 파일의 내용을 실시간으로 출력합니다. -f 옵션은 'follow'의 약자로, 파일의 내용이 변경될 때마다 이를 반영하여 출력합니다.

로그가 어떤 형식인지 잠시 확인한다

sevity@sevityubuntu:~/workspace/hadoop_sevity.com$ cat iis_logs/*.log | head
#Software: Microsoft Internet Information Services 10.0
#Version: 1.0
#Date: 2015-09-06 08:32:43
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken
2015-09-06 08:32:43 127.0.0.1 GET / - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/45.0.2454.85+Safari/537.36 - 200 0 0 211
2015-09-06 08:32:43 127.0.0.1 GET /iisstart.png - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/45.0.2454.85+Safari/537.36 http://127.0.0.1/ 200 0 0 2
2015-09-06 08:32:43 127.0.0.1 GET /favicon.ico - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/45.0.2454.85+Safari/537.36 http://127.0.0.1/ 404 0 2 2

#으로 시작하는 라인을 제외하면 날짜 시간 IP 등의 순임을 알 수 있다.

  • 2023-03-23 00:20:47 : 요청이 발생한 날짜와 시간.
  • 192.168.0.6 : 서버의 IP 주소 또는 호스트 이름.
  • GET : HTTP 요청 방법. 이 경우, 클라이언트는 서버로부터 정보를 요청하고 있습니다.
  • /wiki/doku.php : 클라이언트가 요청한 리소스의 경로.
  • id=learning_rate&do=login&sectok=bac058c83457f1bfade853577f509baf : 요청에 전달된 파라미터입니다.
  • 80 : 사용된 포트 번호. HTTP의 기본 포트는 80입니다.
  • - : 이 필드는 일반적으로 RFC 1413 ident 프로토콜을 통해 확인된 원격 사용자 이름을 나타냅니다. 여기서 "-"는 이 정보가 사용 불가능하다는 것을 의미합니다.
  • 216.244.66.237 : 클라이언트의 IP 주소.
  • Mozilla/5.0+(compatible;+DotBot/1.2;++https://opensiteexplorer.org/dotbot;+help@moz.com) : 사용자 에이전트. 이는 클라이언트가 사용하는 웹 브라우저 또는 봇을 설명합니다. 이 경우에는 DotBot이라는 봇이 서버에 요청을 보냈습니다.
  • - : 이 필드는 일반적으로 "referrer" URL을 나타냅니다. 여기서 "-"는 이 정보가 사용 불가능하다는 것을 의미합니다.
  • 200 : HTTP 상태 코드. 200은 성공을 의미합니다.
  • 0 : 서브 상태 코드. 이는 서버에 따라 다르게 해석될 수 있습니다.
  • 0 : Win32 상태 코드. 이는 서버에 따라 다르게 해석될 수 있습니다.
  • 1068 : 서버가 클라이언트에게 보낸 바이트 .

 

이를위한 mapper.py를 다음처럼 작성한다.

import sys
import logging

# Set up logging
# logging.basicConfig(filename="mapper.log", level=logging.DEBUG)
# 아래처럼 하면 하둡로그랑 섞여서 나와서 디버깅할때 좋다.
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)


# Ignore bad characters
for line in sys.stdin.buffer:
    try:
        line = line.decode('utf-8', 'ignore')
    except UnicodeDecodeError as e:
        logging.error(f"Error decoding line: {line.strip()}, Error: {e}")
        continue

    try:
        data = line.strip().split(" ")
        if len(data) == 15:
            date, time, s_ip, cs_method, cs_uri_stem, cs_uri_query, s_port, cs_username, c_ip, cs_user_agent, cs_referer, sc_status, sc_substatus, sc_win32_status, time_taken = data
            logging.debug(f"Client IP: {c_ip}, Count: 1")
            print("{0}\t{1}".format(c_ip, 1))
    except Exception as e:
        # 예외 발생 시 로그 기록
        logging.error(f"Error processing line: {line.strip()}, Error: {e}")

관심있는 IP와 카운트1을 결과로 출력함을 알 수 있다. (이러면 하둡이 스트리밍하여 Reduce쪽으로 넘긴다)

 

이제 아래와 같이 reducer.py를 작성하여 IP별 카운트를 집계한다.

#!/usr/bin/env python3

import sys
import logging

# Set up logging
logging.basicConfig(filename="reducer.log", level=logging.DEBUG)

last_key = None
running_total = 0
key = None

try:
    for input in sys.stdin:
        key, value = input.strip().split("\t", 1)
        if last_key == key:
            running_total += int(value)
        else:
            if last_key:
                logging.debug(f"Key: {last_key}, Running Total: {running_total}")
                print("{0}\t{1}".format(last_key, running_total))
            running_total = int(value)
            last_key = key

    if last_key == key and key is not None:
        logging.debug(f"Key: {last_key}, Running Total: {running_total}")
        print("{0}\t{1}".format(last_key, running_total))

except Exception as e:
    # 예외 발생 시 로그 기록
    logging.error(f"Error processing input: {e}")

다음명령을 통해 map-reduce를 수행(RDB에서 SELECT에 해당한다)

# 이전실행 클린업
hdfs dfs -rm -r /output

# 실행
hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-*.jar \
	-file ~/workspace/hadoop_sevity.com/mapper.py \
    -mapper 'python3 mapper.py' \
    -file ~/workspace/hadoop_sevity.com/reducer.py \
    -reducer 'python3 reducer.py' \
    -input /logs/* -output /output 2>&1 | tee r.txt

그다음 결과를 hdfs에서 로컬로 가져와서 결과 보기

# 로컬로 가져오기
hadoop fs -get /output .

# IP카운트(2번째컬럼) 역순으로 정렬
sort -k2,2nr -t $'\t' output/* > sorted_output.txt

# 결과보기(상위 10개)
cat sorted_output.txt | head
216.244.66.237	69027
192.168.0.1	27738
211.189.165.105	20114
64.62.252.174	13246
119.207.72.84	8959
211.53.177.20	6565
66.249.82.88	5636
66.249.82.89	5632
66.249.82.90	5312
194.110.203.7	5157

# 가장 많이 접속한 IP에 대한 정보를 역추적해서 보기
grep -m 10 216.244.66.237 iis_logs/* | head
iis_logs/u_ex180725.log:2018-07-25 05:40:56 192.168.0.2 GET /robots.txt - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 404 0 2 499
iis_logs/u_ex180725.log:2018-07-25 05:44:26 192.168.0.2 GET / - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 200 0 0 641
iis_logs/u_ex180805.log:2018-08-05 02:39:00 192.168.0.2 GET /robots.txt - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 404 0 2 194
iis_logs/u_ex180805.log:2018-08-05 02:42:02 192.168.0.2 GET / - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 200 0 0 181
iis_logs/u_ex181027.log:2018-10-27 06:25:55 192.168.0.2 GET /robots.txt - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 404 0 2 183
iis_logs/u_ex181027.log:2018-10-27 06:35:36 192.168.0.2 GET / - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 200 0 0 176
iis_logs/u_ex181107.log:2018-11-07 01:04:26 192.168.0.2 GET /robots.txt - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 404 0 2 448
iis_logs/u_ex181107.log:2018-11-07 01:13:17 192.168.0.2 GET / - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 200 0 0 668
iis_logs/u_ex190201.log:2019-02-01 21:31:17 192.168.0.2 GET /robots.txt - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 404 0 2 118
iis_logs/u_ex190201.log:2019-02-01 21:45:12 192.168.0.2 GET / - 80 - 216.244.66.237 Mozilla/5.0+(compatible;+DotBot/1.1;+http://www.opensiteexplorer.org/dotbot,+help@moz.com) - 200 0 0 118
sevity@sevityubuntu:~/workspace/hadoop_sevity.com$
반응형

'Programming > Linux' 카테고리의 다른 글

스팍(Spark) 설치  (0) 2023.07.30
하둡 - 실습 - 웹서버 세션분석  (0) 2023.07.29
하둡(Hadoop)  (0) 2023.07.29
Docker 설치, 초기설정, 명령어가이드  (0) 2023.07.17
vimdiff  (0) 2021.04.07

+ Recent posts