Nginx 봇 차단 설정

실제 탐지된 공격 유형 기반 Nginx 악성 봇 및 스캔 요청 차단 설정

마지막 수정: 2026-05

Nginx 봇 차단 설정

실제 서버에서 탐지된 공격 패턴을 기반으로 작성한 Nginx 차단 설정이다.
응답을 주지 않고 즉시 연결을 끊는 444와 오류 페이지를 반환하는 403을 상황에 맞게 사용한다.


return 444 vs return 403

코드동작사용 상황
444응답 없이 TCP 연결 즉시 종료자동화 봇, RCE 탐색, 스캐너 — 응답 자체를 주지 않아 공격자가 서버 존재를 확인하기 어렵게 함
403Forbidden 응답 반환실수로 접근할 수 있는 정상 사용자가 있을 경우 — 이유를 알려주는 것이 적절한 경우

봇/스캐너에는 444가 권장된다. 응답을 보내지 않으므로 재시도 유발 가능성이 낮다.


설정 파일 구조

차단 규칙은 별도 파일로 분리해서 각 server 블록에 include하는 방식이 유지보수에 유리하다.

/etc/nginx/
├── nginx.conf
├── conf.d/
│   └── your-site.conf          ← server 블록
└── snippets/
    └── bot-blocking.conf       ← 차단 규칙 (include 대상)

bot-blocking.conf 전체 설정

# /etc/nginx/snippets/bot-blocking.conf

# ────────────────────────────────────────────
# 1. PHP / phpunit RCE 탐색 차단
# ────────────────────────────────────────────
# eval-stdin.php, /vendor/phpunit 등 PHP 원격 코드 실행 취약점 스캐너 차단
location ~* "(eval-stdin\.php|/vendor/phpunit|php-cgi|php\.cgi)" {
    return 444;
}

# ────────────────────────────────────────────
# 2. Path Traversal 차단
# ────────────────────────────────────────────
# URL 인코딩된 ../ 시퀀스로 상위 디렉토리에 접근하는 시도 차단
location ~* "(%2e%2e|%252e%252e|\.\.%2f|%2f\.\.)" {
    return 444;
}

# ────────────────────────────────────────────
# 3. 민감 파일 노출 차단
# ────────────────────────────────────────────
# .env, .git 등 설정 파일이 웹으로 노출되는 것 차단
location ~* "(\.env|\.git|\.htaccess|\.htpasswd|\.DS_Store|web\.config)" {
    return 444;
}

# ────────────────────────────────────────────
# 4. CGI 쉘 탐색 차단
# ────────────────────────────────────────────
# /cgi-bin/ 경로를 통한 쉘 스크립트 실행 시도 차단
location ~* "^/cgi-bin/" {
    return 444;
}

# ────────────────────────────────────────────
# 5. Tomcat Manager / Docker API 탐색 차단
# ────────────────────────────────────────────
# 관리자 콘솔 및 Docker 원격 API 스캔 차단
location ~* "^/(manager/html|host-manager|containers/json|v\d+\.\d+/containers)" {
    return 444;
}

# ────────────────────────────────────────────
# 6. ThinkPHP / Laravel RCE 쿼리 차단
# ────────────────────────────────────────────
# PHP 프레임워크 원격 코드 실행 취약점 악용 시도 차단
# 쿼리스트링에 포함되는 패턴이므로 $request_uri 기준으로 검사
if ($request_uri ~* "(invokefunction|call_user_func_array|s=index/think)") {
    return 444;
}

# ────────────────────────────────────────────
# 7. WordPress 경로 차단
# ────────────────────────────────────────────
# WordPress 미사용 서버에서 wp-admin, xmlrpc.php 스캔 차단
location ~* "^/(wp-admin|wp-login\.php|xmlrpc\.php|wp-content|wp-includes)" {
    return 444;
}

# ────────────────────────────────────────────
# 8. 악성 User-Agent 차단
# ────────────────────────────────────────────
# 알려진 취약점 스캐너, 크롤러 차단
map $http_user_agent $blocked_agent {
    default         0;
    ~*masscan       1;
    ~*nikto         1;
    ~*sqlmap        1;
    ~*nmap          1;
    ~*zgrab         1;
    ~*python-httpx  1;
    ~*go-http-client 1;
}

map 블록은 http { } 컨텍스트에 있어야 하므로 nginx.conf 또는 conf.d/ 내 별도 map 파일에 작성하고, server 블록에서 if ($blocked_agent) { return 444; } 로 사용한다.


server 블록에 적용

# /etc/nginx/conf.d/your-site.conf

# map은 http 블록에 선언 (nginx.conf 또는 별도 파일)
map $http_user_agent $blocked_agent {
    default          0;
    ~*masscan        1;
    ~*nikto          1;
    ~*sqlmap         1;
    ~*nmap           1;
    ~*zgrab          1;
    ~*python-httpx   1;
    ~*go-http-client 1;
}

server {
    listen 443 ssl;
    server_name example.com;

    # 봇 차단 규칙 포함
    include /etc/nginx/snippets/bot-blocking.conf;

    # User-Agent 차단 적용
    if ($blocked_agent) {
        return 444;
    }

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

적용 방법

# 설정 문법 검사
sudo nginx -t

# 재시작 없이 설정 반영
sudo nginx -s reload

차단 로그 확인

# 444 응답 발생 확인
sudo grep ' 444 ' /var/log/nginx/access.log | tail -20

# 특정 IP의 요청 패턴 확인
sudo grep '공격자IP' /var/log/nginx/access.log