• SEARCH

    통합검색
세모계
    • Dark Mode
    • GNB Always Open
    • GNB Height Maximize
    • Color
    • Brightness
    • SINCE 2015.01.19.
    • 세모계 세모계
    •   SEARCH
    • 세상의 모든 계산기
      • 자유(질문) 게시판
      • 계산기 뉴스/정보
      • 수학, 과학, 공학 이야기
      • 세모계 : 공지 게시판
        • 구글 맞춤검색
    • TI
    • CASIO
    • HP
    • SHARP
    • 일반(쌀집) 계산기
    • 기타계산기
    • by OrangeDay
  • 세상의 모든 계산기 자유(질문) 게시판
    • 세상의 모든 계산기 자유(질문) 게시판 일반 ()
    • (Nginx) "웹 크롤러 request 순위 확인" 스크립트 (우분투)

    • Profile
      • 세상의모든계산기
      • 2025.02.15 - 10:57 2025.02.14 - 17:40 7937
    #!/bin/bash
    # monip.sh
    # Nginx access 로그에서 상위 25개 IP를 분석하여
    # - Bot (Crawler)인 경우: User-Agent 문자열로 Bot 종류를 추출
    # - User인 경우: whois 명령으로 Organization Name 조회
    # 그리고 IP별 국가 정보(geoiplookup)를 추가하여 출력함
    
    LOG_FILE="/var/log/nginx/access.log"
    
    if [ ! -f "$LOG_FILE" ]; then
        echo "로그 파일이 존재하지 않습니다: $LOG_FILE"
        exit 1
    fi
    
    awk '
      # Bot의 종류를 판별하는 함수
      function get_bot_type(ua,   ua_lower) {
        ua_lower = tolower(ua)
        if(ua_lower ~ /googlebot/)   return "Googlebot"
        if(ua_lower ~ /bingbot/)      return "Bingbot"
        if(ua_lower ~ /slurp/)        return "Yahoo Slurp"
        if(ua_lower ~ /duckduckbot/)  return "DuckDuckBot"
        if(ua_lower ~ /baiduspider/)  return "Baiduspider"
        if(ua_lower ~ /yandex/)       return "YandexBot"
        return "Unknown Bot"
      }
      
      # User-Agent 문자열을 바탕으로 사용자 종류를 판별
      function classify_user_agent(ua) {
        if(ua == "" || ua == "-") return "알 수 없음"
        ua_lower = tolower(ua)
        if(ua_lower ~ /bot|crawl|spider|slurp|mediapartners/) return "Bot (Crawler)"
        return "User"
      }
      
      # geoiplookup 명령을 사용하여 IP의 국가 정보를 가져오는 함수
      function get_country(ip,   cmd, result, arr, country) {
        cmd = "geoiplookup " ip " 2>/dev/null"
        if ((cmd | getline result) > 0) {
          # 예: "GeoIP Country Edition: US, United States"
          split(result, arr, ":")
          if(length(arr) > 1) {
            country = arr[2]
            gsub(/^[ \t]+|[ \t]+$/, "", country)
          } else {
            country = "Unknown"
          }
        } else {
          country = "조회 실패"
        }
        close(cmd)
        return country
      }
      
      {
        # Combined log format 예제:
        # 127.0.0.1 - - [14/Feb/2025:12:00:00 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 ..."
        regex = "([^ ]*) - ([^ ]*) \\[([^\\]]*)\\] \"([^\"]*)\" ([^ ]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\""
        if(match($0, regex, arr)) {
          ip      = arr[1]
          referer = arr[7]
          ua_str  = arr[8]
          
          count[ip]++                  # IP별 요청 횟수 집계
          ua_stats[ip, ua_str]++        # IP별 User-Agent 빈도 집계
          ref_stats[ip, referer]++      # (참고용) 리퍼러 집계
        }
      }
      
      END {
        # gawk의 asorti() 함수로 요청 횟수 기준 내림차순 정렬
        n = asorti(count, sorted, "@val_num_desc")
        
        # 헤더 출력 (순서: 순위 | IP | 국가 | Requests | 사용자 종류 | 기타정보)
        printf("| %-2s | %-15s | %-18s | %-10s | %-17s | %-21s |\n", "순위", "IP", "국가", "Requests", "사용자 종류", "기타정보")
        print("|------|-----------------|----------------------|------------|------------------------|-------------------------|")
        
        limit = (n < 25 ? n : 25)
        for(i = 1; i <= limit; i++){
          ip = sorted[i]
          req_count = count[ip]
          
          # 해당 IP의 가장 많이 등장한 User-Agent 선택
          max_ua = ""
          max_ua_count = 0
          for(key in ua_stats) {
            split(key, parts, SUBSEP)
            if(parts[1] == ip) {
              if(ua_stats[key] > max_ua_count) {
                max_ua_count = ua_stats[key]
                max_ua = parts[2]
              }
            }
          }
          
          user_type = classify_user_agent(max_ua)
          
          extra = ""
          if(user_type == "User") {
             # User인 경우: whois 명령으로 Organization Name 조회
             cmd = "whois " ip " 2>/dev/null | grep -i -m 1 \"orgname:\""
             org = ""
             if((cmd | getline org) > 0) {
                sub(/^[ \t]+/, "", org)
                split(org, a, ":")
                if(length(a) > 1) {
                  org = a[2]
                  gsub(/^[ \t]+/, "", org)
                }
             } else {
                org = "조회 실패"
             }
             close(cmd)
             extra = org
          } else if(user_type == "Bot (Crawler)") {
             extra = get_bot_type(max_ua)
          } else {
             extra = "없음"
          }
          
          # 각 IP의 국가 정보 추가
          country = get_country(ip)
          
          printf("| %-4d | %-15s | %-20s | %-10d | %-22s | %-25s |\n", i, ip, country, req_count, user_type, extra)
        }
      }
    ' "$LOG_FILE"

     

     

    사용 방법

    1. 스크립트를 파일에 저장 후 실행 권한 부여:

      chmod +x monip.sh

    2. 스크립트 실행 (필요한 경우 sudo로):

      sudo ./monip.sh

     

     

    결과

    image.png

    Attached file
    image.png 288.8KB 44
    이 게시물을..
    N
    0
    0
    • 세상의모든계산기 25
      세상의모든계산기

      계산기는 거들 뿐
      혹은
      계산기를 거들 뿐

    세상의모든계산기 님의 최근 글

    ban 설정 강화 82339 1 2026 05.09 정적분 구간에 미지수가 있고, solve 를 사용할 수 없을 때 그 값을 확인하려면? 2763 4 2026 04.10 높아질수록 좁아지는 시야에 대하여 - written by ChatGPT 13272 2026 02.12 내가 올해 몇살이더라? (내 나이 계산기) 10417 2026 02.11 AGI 자기 거버넌스 구조와 인간-AGI 관계 모델 (written by GEMINI & GPT) 13767 1 2026 01.30

    세상의모든계산기 님의 최근 댓글

    2) 고정기준값 41에 대한 오차 제곱합 계산방법   이건 통계메뉴에서는 딱히 방법이 떠오르지 않네요.  질문하신 것과 같이 적은 갯수의 data라면 직접 입력하시는게 최선입니다.      하지만 DATA 갯수가 수십개 이상이라면? ㄴ 스프레드시트 기능을 이용하시는게 좋겠습니다.  【MENU】【8】   A열에 DATA 입력하고  B로 이동한 후 OPTN 【1】 Fill Formula 【ALPHA】키 방향키 숫자키 등을 이용해 수식 완성   C로 이동후 Formula 수식 입력   D의 빈공간으로 이동 후 OPTN 방향키 아래 누르다보면 Sum 보임 ALPHA 키 이용해서 수식 완성. : 기호는 MENU 버튼 바로 아래 있음 (ALPHA키로 입력) 【=】입력하면  최종결과 확인 * 주의 (B열, C열과 달리) D1 셀은 계산 결과인 951이 직접 입력된 상태이므로 DATA 수정후 recalculation 하여도 자동계산되지 않음.  자동계산을 위해서는 formula 형식으로 입력해야 함.  2026 10.27 1) 통계적 편차제곱합(평균 50.25기준) 입력 방법   【MENU】 【6】 【1】 로 1-var Stat 모드로 진입하여  【48】 【=】 【66】 【=】 【32】 【=】 【55】【=】  DATA 입력  【OPTN】 【3】 【▼】 【▼】   fx-570EX 기종에도 편차제곱합을 바로 보여주진 않습니다.  본문에 나온 것처럼 앞서 계산되어 저장된 각종 변수를 이용해 계산합니다.    【AC】【OPTN】【4】Statistics Calc   이 화면에서 다시  OPTN 하고 (메뉴가 3개로 줄어 있죠?)  여기서 화살표 아래를 내려보면 추가 메뉴가 있습니다.  4개 메뉴에는 각각 아래 하위 메뉴가 있습니다.      이 중에서 필요로 하는 것을 골라 계산하시면 되겠습니다.  Variable 에 있는 값을 이용하면  다른 공식을 쓰셔도 됩니다.  2026 10.27 질문자님, 48,66,32,55 네 개 DATA 의 평균은 50.25라서 41은 평균이 아닙니다. 그래서 식을 두 가지로 나눠서 봐야 합니다. 1) 통계적 편차제곱합(평균 50.25기준)이면 답은 608.75 입니다. 2) 만약 41이라는 고정 기준값에 대한 제곱합을 구하시는 거면 식은 (48-41)²+... 이고 답은 951입니다. 원문에 +로 쓰신 건 -의 오타로 보입니다. 2026 10.27 본문의 변환 위젯에 사용된 전서체 폰트는 대만의 최고 학술 연구 기관인 중앙연구원(Academia Sinica)에서 제공하는 ‘숭희전체(崇羲篆體)’로 전통 한자 서체인 소전(小篆)을 현대 컴퓨터 폰트(글꼴)로 구축한 오픈소스 프로젝트로 개발되었습니다. https://xiaoxue.iis.sinica.edu.tw/chongxi/download.htm 2026 10.20 예제1)      예제2)       예제3)      추가옵션    2026 10.18
    글쓴이의 서명작성글 감추기 
    • 댓글 입력
    • 에디터 전환
    댓글 쓰기 에디터 사용하기 닫기
    • view_headline 목록
    • 14px
    • 목록
      view_headline
    × CLOSE
    전체 일반 389 질문 509 웃김 2 팁 & 정보 16 퀴즈 2 리뷰 11 퍼옴 & 링크 6 공지 1
    기본 (0) 제목 날짜 수정 조회 댓글 추천 비추
    분류 정렬 검색
    등록된 글이 없습니다.
    • 글쓰기
    • 세상의 모든 계산기 자유(질문) 게시판
    • 세상의모든계산기
    • 사업자등록번호 703-91-02181
    • 세모계 all rights reserved.