본문 바로가기
서버연구 블로그 서버연구 블로그

웹서버 Access Log에서 비정상적인 요청 패턴 찾는 방법

읽는 시간 약 13분

웹서버 장애나 비정상 트래픽을 분석할 때 가장 먼저 확인하는 자료 중 하나가 Access Log다.

Nginx Access Log에는 단순히 사용자가 어떤 페이지에 접속했는지만 기록되는 것이 아니다. 요청을 보낸 IP, HTTP Method, URI, 응답 Status Code, User-Agent, 전송 데이터 크기 등을 통해 웹서버에 어떤 요청이 들어왔고 서버가 어떻게 응답했는지를 확인할 수 있다.

하지만 Access Log에서 이상해 보이는 요청 한 줄을 발견했다고 바로 공격으로 판단해서는 안 된다.

중요한 것은 평소와 비교했을 때 어떤 요청 패턴이 반복되고 있는지, 그리고 그 변화가 실제 서버 자원이나 Backend Application에 영향을 주고 있는지를 함께 확인하는 것이다.

이번 글에서는 Nginx를 기준으로 Access Log의 동작 원리부터 비정상 요청의 실제 증상, 분석 방법, 대응 방법까지 살펴본다.

1. Nginx Access Log에는 무엇이 기록될까?

Nginx는 HTTP 요청을 처리한 뒤 설정된 access_log에 요청 정보를 기록할 수 있다.

일반적인 로그에는 다음과 같은 값이 포함된다.

$remote_addr
$time_local
$request
$status
$body_bytes_sent
$http_referer
$http_user_agent

실제 로그는 다음과 비슷하다.

203.0.113.20 - - [10/Sep/2026:14:20:31 +0900]
"GET /products HTTP/1.1" 200 5321
"https://example.com/" "Mozilla/5.0 ..."

운영자는 이 값을 각각 따로 보는 것이 아니라 서로 연결해서 봐야 한다.

Source IP
    ↓
Request URI / Method
    ↓
Status Code
    ↓
발생 횟수
    ↓
발생 시간

예를 들어 404 응답 한 건은 단순한 잘못된 URL일 수 있다.

하지만 동일한 IP가 짧은 시간 동안 수십 개의 존재하지 않는 관리 페이지를 반복해서 요청한다면 자동화된 스캔 가능성을 확인할 이유가 생긴다.

2. 비정상적인 요청은 왜 발생할까?

인터넷에 공개된 웹서버에는 정상 사용자만 접속하지 않는다.

검색엔진 Crawler, 모니터링 시스템, API Client뿐 아니라 인터넷에 공개된 서버를 자동으로 탐색하는 Scanner도 계속 접근할 수 있다.

예를 들어 다음과 같은 요청이 발생할 수 있다.

/wp-login.php
/phpmyadmin/
/.env
/admin/
/config/

서버에 WordPress나 phpMyAdmin을 설치하지 않았는데도 이런 URI가 요청될 수 있다.

공격자가 해당 서버의 구성을 정확히 알고 접근한 것이 아니라, 자동화된 프로그램이 많은 서버에 동일한 URI를 순차적으로 요청하는 경우가 있기 때문이다.

따라서 특정 URI 한두 건만 보고 서버가 공격받았다고 판단해서는 안 된다.

운영자가 확인해야 할 것은 요청의 빈도, 반복성, Source IP, Status Code, 발생 시간이다.

3. 비정상 트래픽이 발생하면 어떤 증상이 나타날까?

소규모 Scanner나 Bot 요청은 서버 성능에 거의 영향을 주지 않을 수 있다.

이 경우 Access Log에 몇 개의 이상한 URI만 남고 서비스에는 별다른 문제가 발생하지 않는다.

하지만 요청량이 증가하면 다음과 같은 변화가 나타날 수 있다.

특정 IP Request 급증
404 / 403 응답 증가
존재하지 않는 URI 반복
Access Log 발생량 증가
Nginx Request 처리량 증가
Backend 요청 증가
CPU 또는 Connection 증가

특히 Nginx가 Reverse Proxy로 동작하고 있다면 비정상 요청이 Backend Application까지 전달될 수 있다.

Client
   ↓
Nginx
   ↓
Reverse Proxy
   ↓
Application
   ↓
Database

이 경우 단순히 Access Log만 증가하는 것이 아니라 Application CPU나 Database Query까지 영향을 받을 수 있다.

따라서 실제 장애 분석에서는 로그 패턴과 서버 자원 변화를 같은 시간대 기준으로 비교해야 한다.

4. 가장 먼저 요청이 많은 Source IP를 확인한다

분석의 첫 단계는 어떤 IP에서 요청이 집중되고 있는지 확인하는 것이다.

일반적인 Nginx Access Log라면 다음과 같이 집계할 수 있다.

awk '{print $1}' /var/log/nginx/access.log \
| sort \
| uniq -c \
| sort -nr \
| head

결과가 다음과 같다고 해보자.

18240 203.0.113.20
 5214 198.51.100.15
 2183 192.0.2.10

첫 번째 IP에서 요청이 많이 발생했다는 사실은 알 수 있다.

하지만 여기서 바로 해당 IP를 차단해서는 안 된다.

서버 앞에 Load Balancer, CDN, Reverse Proxy가 존재한다면 $remote_addr에 실제 사용자 IP가 아니라 Proxy 주소가 기록될 수도 있기 때문이다.

즉,

요청 많은 IP = 공격 IP

라고 단정해서는 안 된다.

먼저 현재 서버의 Proxy 구조와 실제 Client IP가 어떤 Header를 통해 전달되는지 확인해야 한다.

5. 반복되는 404 URI를 확인한다

다음으로 존재하지 않는 URI 요청이 반복되는지 확인한다.

일반적인 combined 형식에서는 다음처럼 볼 수 있다.

awk '$9 == 404 {print $7}' /var/log/nginx/access.log \
| sort \
| uniq -c \
| sort -nr \
| head

예를 들어 다음과 같은 결과가 나온다고 하자.

842 /wp-login.php
611 /.env
384 /phpmyadmin/
220 /admin/

실제 서버에 존재하지 않는 URI가 반복적으로 요청된다면 자동화된 탐색 요청일 가능성을 확인할 수 있다.

하지만 404 전체가 비정상 요청은 아니다.

삭제된 이미지, 오래된 검색엔진 URL, 잘못된 내부 링크 때문에 정상 사용자에게도 404가 발생할 수 있다.

따라서 URI만 보지 말고 Source IP와 발생 시간까지 같이 확인해야 한다.

6. Status Code 분포를 같이 확인한다

Access Log에서는 개별 요청보다 Status Code 비율 변화가 더 중요한 단서가 될 때도 있다.

awk '{print $9}' /var/log/nginx/access.log \
| sort \
| uniq -c \
| sort -nr

평소에는 대부분 200, 301, 304였는데 갑자기 404, 403, 429가 증가한다면 해당 시간대 요청을 추가로 분석할 필요가 있다.

또 502, 504가 증가한다면 상황이 다르다.

404 / 403 증가
→ 잘못된 URI 또는 접근 차단 가능성 확인

429 증가
→ Rate Limit 발생 여부 확인

502 / 504 증가
→ Backend 또는 Upstream 장애 확인

즉 Status Code는 공격 여부를 바로 알려주는 값이 아니라 다음에 어느 계층을 조사해야 할지 알려주는 단서로 사용하는 것이 좋다.

7. 시간대별 요청량으로 폭증 시점을 찾는다

전체 로그만 보면 비정상 요청이 정상 트래픽 사이에 묻힐 수 있다.

이럴 때는 시간 단위 Request 수를 비교하면 이상 발생 시점을 찾기 쉽다.

일반적인 Nginx Log Format이라면 다음처럼 확인할 수 있다.

awk '{print substr($4,2,14)}' /var/log/nginx/access.log \
| sort \
| uniq -c

예를 들어 다음과 같은 형태로 나온다.

1240 10/Sep/2026:10
1315 10/Sep/2026:11
6840 10/Sep/2026:12
7021 10/Sep/2026:13

12시부터 Request가 갑자기 증가했다면 해당 시간대의 IP, URI, Status Code를 집중적으로 분석하면 된다.

다만 이 명령은 일반적인 Access Log 형식을 전제로 한다.

로그 포맷을 직접 변경한 서버에서는 $time_local 위치가 다를 수 있으므로 실제 로그 구조를 먼저 확인해야 한다.

중요한 것은 절대적인 Request 숫자가 아니다.

사이트마다 트래픽 규모가 다르기 때문에 평소 Baseline과 비교했을 때 얼마나 달라졌는가를 보는 것이 더 중요하다.

8. 느린 요청까지 분석하려면 Log Format을 보강한다

기본 Access Log만으로는 요청 처리 시간이 충분히 보이지 않을 수 있다.

이럴 때 $request_time을 추가하면 요청 하나를 처리하는 데 얼마나 시간이 걸렸는지 기록할 수 있다.

log_format main_ext
    '$remote_addr [$time_local] '
    '"$request" $status '
    'rt=$request_time';

Reverse Proxy 환경에서는 $upstream_response_time도 같이 기록하면 유용하다.

'rt=$request_time '
'urt=$upstream_response_time';

두 값을 같이 보면 느린 요청의 위치를 어느 정도 구분할 수 있다.

request_time 증가
        ↓
전체 요청 처리 지연 확인

upstream_response_time 증가
        ↓
Backend Application 응답 지연 가능성 확인

다만 기존 로그 분석 시스템이나 Parser가 Access Log 형식에 의존하고 있다면 log_format 변경 전에 영향을 먼저 확인해야 한다.

9. 비정상 요청을 확인했다면 어떻게 대응할까?

비정상적인 요청을 발견했다고 무조건 Source IP부터 차단하는 것은 좋은 대응 순서가 아니다.

먼저 정상 트래픽인지 확인해야 한다.

CDN, 검색엔진 Crawler, API Client, 내부 모니터링 시스템일 수 있기 때문이다.

실제 비정상 요청으로 판단했다면 원인에 따라 대응 방법도 달라진다.

반복적인 Scanner
→ Firewall / WAF 차단 검토

특정 URI Request 폭증
→ Nginx Rate Limit 검토

존재하지 않는 URI 반복
→ 불필요한 요청 차단 검토

정상 사용자 404 증가
→ 잘못된 링크 또는 Application 수정

Backend까지 부하 발생
→ URI별 처리 구조와 Upstream 분석

특정 IP만 차단하면 일시적으로 로그가 줄어들 수 있지만 공격 Source가 분산되어 있다면 근본적인 해결이 되지 않는다.

반복적인 요청 폭증에는 Nginx의 limit_req, WAF, CDN Rate Limiting 같은 계층을 검토할 수 있다.

반대로 정상적인 요청인데 Application이 지나치게 느리다면 보안 문제가 아니라 Backend 성능 문제를 분석해야 한다.

운영자의 핵심 판단 기준은 항상 같다.

로그가 이상해 보이는가가 아니라, 그 요청이 실제 서비스에 어떤 영향을 주고 있는가를 확인하는 것이다.

10. 정리

Nginx Access Log는 웹서버에 들어온 HTTP Request를 분석할 수 있는 가장 기본적인 자료다.

하지만 특정 IP의 요청이 많거나 404가 반복된다는 이유만으로 공격이라고 단정해서는 안 된다.

실제 운영 환경에서는 다음 순서로 분석하는 것이 좋다.

전체 Request 변화 확인
        ↓
Source IP별 요청량 분석
        ↓
URI / Method 확인
        ↓
Status Code 확인
        ↓
발생 시간과 반복성 확인
        ↓
CPU / Connection / Backend 확인
        ↓
원인에 맞는 대응 적용

특히 단순 로그 분석에서 끝내지 않고 서버 자원과 Application 상태까지 연결해서 보는 것이 중요하다.

요청량과 4xx 응답이 증가했지만 서버 자원이 정상이라면 자동화된 스캔 수준일 수 있다.

반대로 Request 폭증과 함께 Nginx Connection, CPU, Backend 응답시간까지 증가했다면 실제 서비스 영향이 발생하고 있는지 우선 확인해야 한다.

결국 Access Log 분석의 목적은 이상한 로그 한 줄을 찾는 것이 아니다.

평소와 다른 요청 패턴을 발견하고, 그 변화가 웹서버와 Backend에 어떤 영향을 주는지를 연결해서 판단하는 것이 핵심이다.

이 관점을 익혀두면 Access Log는 단순한 접속 기록이 아니라 웹서버 장애와 비정상 트래픽을 분석하는 중요한 운영 데이터가 된다.

instone
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

error: Content is protected !!

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.