허용한 HTTP 메서드만 통과: 잡음 요청은 Nginx에서 405/444로 컷하자

운영 중에 웹 애플리케이션 로그를 tail 하다 보면 가끔 이런 순간이 옵니다.

  • 나는 GET / POST / PUT / DELETE만 쓰고 있다고 믿었는데
  • 로그에는 처음 보는 메서드가 슬쩍 끼어 있다

예를 들면 PROPFIND 같은 WebDAV 메서드가 로그에 보입니다.
앱은 어차피 “지원하지 않는 메서드”로 처리하겠죠. 하지만 중요한 건 이겁니다.

굳이 열심히 일하는 애플리케이션에게 잡음까지 처리하게 만들 필요가 있을까? 답은 보통 “아니오”입니다. 그래서 허용한 메서드만 통과시키고, 나머지는 Nginx에서 앞단 컷하는 게 깔끔합니다.


왜 굳이 Nginx에서 막아야 하나



앱 레벨에서 막을 수도 있습니다. 그런데 요청이 앱까지 들어오는 순간 이미 비용이 발생합니다.

  • WSGI/ASGI 진입
  • 미들웨어/로깅/인증 로직 일부가 돌아감
  • 앱 로그가 더러워져서 “진짜 이슈”가 묻힘
  • 트래픽이 많아지면 그만큼 쓸데없는 부하가 누적됨

반대로 Nginx에서 막으면:

  • 가장 앞단에서 즉시 종료 → 비용 최소
  • 앱 로그가 깨끗해짐 → 운영이 편해짐
  • 공격 표면이 줄어듦 → 불필요한 메서드 자체를 제거

한 문장으로 요약하면 이거예요.

앱은 제품을 만들고, Nginx는 문지기 역할을 한다.


로그에서 가끔 보이는 낯선 메서드는 대부분 “정상 사용”이 아니다

PROPFIND 같은 DAV 메서드는 “그럴듯해 보이는” 대표 케이스입니다.

  • WebDAV 기능이 열려 있는지 대충 찔러보는 스캐닝
  • 설정 실수로 PUT/MKCOL 같은 게 열려 있으면 다음 단계로 넘어가려는 시도
  • User-Agent가 비어 있거나, HTTP/1.0처럼 대충 던지는 패턴도 종종 보임

핵심은 이것 하나입니다.

우리 서비스가 그 메서드를 쓰지 않는다면, 정상 트래픽일 이유가 거의 없다. 그러면 굳이 앱까지 보내서 친절히 응답해줄 필요도 없습니다.


전략은 간단하다: Allowlist(허용 목록)로 운영하기



nginx라는 보안요원이 출입문을 관리하는 이미지

원칙은 “필요한 것만 열고 나머지는 닫기”입니다.

  • 일반 웹 페이지/정적 리소스: 보통 GET, HEAD면 충분
  • API: 필요한 엔드포인트에만 POST/PUT/PATCH/DELETE를 제한적으로 허용

그리고 그 외 메서드들은(예: PROPFIND, MKCOL, LOCK 등) 우리가 쓰지 않으면 전부 차단하는 방향이 운영적으로 가장 편합니다.


405 vs 444: 어떤 응답으로 끊을까

차단은 크게 두 가지 방식이 있습니다.

1) 405 Method Not Allowed

  • 표준적이고 이해하기 쉬움
  • 정상 클라이언트가 잘못된 메서드로 왔을 때 “안 된다”고 명확히 알려줌

2) 444 (Nginx 전용: 응답 없이 연결 종료)

  • 아무 말 없이 끊어버림
  • 스캐너/봇에게 힌트를 덜 줌
  • 운영 관점에서 조용하고 깔끔함(“잡음은 묻어버리기”)

요컨대 이런 기준으로 판단하면 될 듯 합니다.

  • 공개 웹에서 의미 없는 메서드: 444로 조용히 컷
  • 정상 클라이언트가 실수할 수 있는 경로: 405로 명확히 안내

Nginx 설정 예시: “허용 메서드 외 컷” 2가지 패턴

아래 예시는 “복붙해서 시작”하기 좋은 형태로 적었습니다.

패턴 A) 기본은 GET/HEAD만, API만 추가 허용

server {
    # ... listen/server_name 등 ...

    # 1) 기본: 웹/정적은 GET/HEAD만 허용
    location / {
        if ($request_method !~ ^(GET|HEAD)$) { return 444; }  # 또는 405
        proxy_pass http://app;
    }

    # 2) API: 필요한 메서드만 허용
    location /api/ {
        if ($request_method !~ ^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)$) { return 444; }
        proxy_pass http://app;
    }
}
  • /는 페이지 조회 중심이라 GET/HEAD만 열어도 충분한 경우가 많습니다.
  • /api/는 CORS 때문에 OPTIONS가 필요할 수 있어 같이 허용합니다.

패턴 B) “낯선 메서드”만 골라서 명시 차단(가벼운 시작)

location / {
    if ($request_method ~ ^(PROPFIND|PROPPATCH|MKCOL|COPY|MOVE|LOCK|UNLOCK)$) { return 444; }
    proxy_pass http://app;
}
  • 당장 운영에서 보이는 잡음 메서드부터 잘라내는 방식
  • 다만 장기적으로는 Allowlist 방식(패턴 A) 이 더 안전하고 관리가 쉽습니다.

참고: if는 Nginx에서 남용하면 위험하다는 말이 종종 나오지만, 이런 “즉시 return 하는 단순 조건”은 실무에서 꽤 흔하게 쓰입니다. 더 엄격하게 가고 싶으면 limit_except를 쓰는 방식도 있습니다.


결론: “허용한 것만 통과”가 운영을 편하게 만든다

요점은 단순합니다.

  • 낯선 메서드는 대부분 정상 트래픽이 아니다
  • 앱까지 보내면 비용이 생기고 로그가 더러워진다
  • 그래서 Nginx에서 허용 메서드만 남기고 나머지는 405/444로 컷한다

이 패턴 하나만 적용해도:

  • 앱 리소스가 덜 새고
  • 로그가 깔끔해지고
  • 운영이 훨씬 편해집니다.