• 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 5343
    #!/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 42
    이 게시물을..
    N
    0
    0
    • 세상의모든계산기 25
      세상의모든계산기

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

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

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

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

    링크가 깨졌다고 하시니   404 에러가 나는 아래 링크를 말씀하시는 것 같은데  https://digilander.libero.it/fpirozzi/fourier.zip 이것은 TI-89 / TI-92 용 파일이며    [TI-92][TI-89] Fourier Transform Library https://allcalc.org/52455 링크의 Attatched files + 안에 있습니다.  2026 09.11 본문에 사용된 nspire 용 파일은 본문 하단에 Attatched files + 안에 있습니다.  클릭하면 표시됩니다.    2026 09.11 이 사이트에 올라와 있는 첨부 파일은 본문 하단에 있는 [Attatchment] 버튼을 눌러야 리스트가 보입니다. 2026 09.07 이렇게 질문하시면 무슨 파일인지 알 수가 없습니다.   해당 글에 댓글을 쓰시는게 최선이며,    권한 문제로 그것이 불가능하면  해당 글의 주소를 붙여넣으시거나,  제목 전체를 복사해 넣으셔야 구분이 됩니다. 2026 09.07 - claude AI는 l-c*r^2 을 1-c*r^2 으로 잘못 읽고 표시하고 있습니다. - TI-nspire CAS 계산기에 l-c*r^2 ≥0 을 조건에 추가해 계산해 보아도 결과는 바뀌지 않습니다. 2026 07.20
    글쓴이의 서명작성글 감추기 
    • 댓글 입력
    • 에디터 전환
    댓글 쓰기 에디터 사용하기 닫기
    • view_headline 목록
    • 14px
    • 목록
      view_headline
    × CLOSE
    전체 일반 389 질문 509 웃김 2 팁 & 정보 16 퀴즈 2 리뷰 11 퍼옴 & 링크 6 공지 1
    기본 (0) 제목 날짜 수정 조회 댓글 추천 비추
    분류 정렬 검색
    등록된 글이 없습니다.
    • 글쓰기
    • 세상의 모든 계산기 자유(질문) 게시판
    • 세상의모든계산기
    • 사업자등록번호 703-91-02181
    • 세모계 all rights reserved.