NPM(Nginx Proxy Manager) 쓰다가 WAF가 필요해져서 직접 만들었다 - Corvus

NPM의 간단함은 그대로, 공격 차단·트래픽 모니터·접속 대기열까지 한 화면에서. 직접 만든 오픈소스 게이트웨이 Corvus 소개

·약 3분·조회 32·수정일: 2026년 11월 11일

집 서버에 NPM 하나 띄워두고 잘 쓰고 있었다. 그런데 서비스를 외부에 열어두니 로그가 점점 수상해지기 시작했다..

시작은 로그였다

집 서버나 작은 서비스를 운영하다 보면 리버스 프록시로 Nginx Proxy Manager(NPM)를 많이 쓴다. 도메인 넣고, 컨테이너 고르고, 클릭 몇 번이면 Let's Encrypt 인증서까지 붙는다. 나도 그 간단함 때문에 잘 쓰고 있었다.

그런데 서비스를 외부에 열어두면 얼마 안 가 로그에 이런 요청들이 찍히기 시작한다.

GET /.env
GET /wp-config.php
GET /../../etc/passwd
GET /?id=1 UNION SELECT password FROM users
GET /.env
GET /wp-config.php
GET /../../etc/passwd
GET /?id=1 UNION SELECT password FROM users

워드프레스를 쓰지도 않고, .env가 있지도 않은데 스캐너는 매일같이 두드린다. 참 성실하다..

이미 한번 서버가 털려본 적이 있다 보니(크립토마이너 대응기) 이런 로그가 남 일 같지 않았다. 결국 이런 고민이 생겼다.

지금 무슨 요청이 들어오는지 보고, 뻔한 공격은 막고, 트래픽이 몰릴 때 조금은 제어할 수 있으면 좋겠다.

보통은 이렇게 한다

NPM에 보안을 더하는 방법은 대표적으로 두 가지가 있다.

1. NPM + CrowdSec 같은 차단 도구 - 로그를 분석해서 나쁜 IP를 막는다.
2. NPM 앞이나 뒤에 WAF 컨테이너 추가 - SafeLine, BunkerWeb, ModSecurity 등

둘 다 좋은 도구다. 다만 컨테이너와 설정 화면이 늘어나고, 요청이 어디서 막혔는지 보려면 여기저기 오가야 한다.
나는 NPM처럼 간단한 화면 하나에서 프록시랑 보안을 같이 다루고 싶었다. 그래서 그냥 만들기로 했다.

Corvus

NPM처럼 쓰는 리버스 프록시에 트래픽을 감시하고, 막고, 제어하는 기능을 넣은 게이트웨이다. NPM 포크는 아니고 처음부터 새로 만들었다. (OpenResty + Go + React)
Apache-2.0 오픈소스이고, 유료 기능은 없다.

  • 프록시 호스트, Let's Encrypt 자동 갱신(와일드카드용 DNS 인증 포함), 리디렉션, TCP/UDP 스트림

  • 호스트를 추가하면 알려진 공격 패턴(SQL 인젝션, 경로 순회, 스캐너 등)을 바로 차단

  • 반복 공격 IP 자동 차단

  • IP·국가·경로·헤더·User-Agent 보안 규칙, 브라우저 챌린지, 자동 공격 대응 모드

  • 트래픽이 몰릴 때 정원만큼만 들여보내는 접속 대기열

  • 실시간 트래픽 모니터와 Slack, Discord, Teams, Telegram 알림

  • 기존 NPM 설정 가져오기, 설정 변경 버전 기록과 롤백

Corvus 대시보드

설치: 5분이면 된다

services:
  corvus:
    image: 'ghcr.io/corvus-gateway/gateway:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '443:443'
      - '9443:9443'
    volumes:
      - ./data:/data
services:
  corvus:
    image: 'ghcr.io/corvus-gateway/gateway:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '443:443'
      - '9443:9443'
    volumes:
      - ./data:/data
docker compose up -d
docker compose up -d

처음 시작하면 로그에 일회용 설정 토큰이 찍힌다. 서버 주인만 관리자 계정을 만들 수 있게 하려는 장치다.

docker compose logs corvus | grep setup_token
docker compose logs corvus | grep setup_token

https://서버-IP:9443에 접속해서 (자체 서명 인증서라 브라우저 경고가 뜬다) 설정 토큰을 넣고 관리자 계정을 만들면 끝. 기본 비밀번호 같은 건 없다.

호스트만 추가하면 바로 되는 것

프록시 호스트 → 추가에서 도메인과 대상 컨테이너(예: shop-web:80)를 넣고, TLS에서 Let's Encrypt를 고른 뒤 저장한다. 여기까지는 NPM이랑 똑같다.

다른 점은 저장하는 순간부터 따로 규칙을 안 써도 보호가 켜져 있다는 것.

알려진 공격 경로 차단

기본으로 켜져 있다. 위에서 본 네 가지 요청(설정 파일 탐색, 경로 순회, SQL 인젝션)은 전부 앱에 닿기 전에 막힌다.

자동 차단

이것도 기본으로 켜져 있다. 10분 동안 20번 넘게 걸린 IP는 15분 차단하고, 다시 걸릴 때마다 차단 시간이 두 배로 늘어난다. (기본 최대 7일)

트래픽 모니터

모든 요청이 트래픽 모니터에 쌓인다. 어떤 호스트에 어떤 경로로 뭐가 들어오고, 뭐가 막혔는지 한 화면에서 볼 수 있다.

Corvus 트래픽 모니터

더 하고 싶을 때

기본값만으로 부족할 때 쓰는 기능들이다. 전부 선택 사항.

  • 보안 규칙 - "/admin 경로는 사무실 IP에서만 허용", "특정 국가 차단" 같은 것. 처음엔 로그 동작으로 두고 뭐가 걸리는지 본 다음에 차단으로 바꾸는 게 안전하다.

  • 브라우저 챌린지 - 외부 서비스 없이, 브라우저에서 짧은 계산(작업 증명)을 통과한 방문자만 들여보낸다. 봇이 몰릴 때 유용하다.

  • 공격 대응 모드 - 초당 요청 수나 차단 비율이 기준을 넘으면 자동으로 모든 방문자에게 챌린지를 건다.

  • 접속 대기열 - 선착순 이벤트처럼 사람이 몰릴 때 정원만큼만 들여보내고 나머지는 순서대로 기다리게 한다. 서버가 버틸 수 있는 만큼만 받는 셈이다.

Corvus 보안 규칙

NPM에서 옮기기

NPM 가져오기로 프록시 호스트, 리디렉션, 스트림, 인증서, 접근 목록을 그대로 가져올 수 있다.
NPM의 파일과 데이터베이스는 읽기만 하기 때문에, 마음에 안 들면 그냥 NPM으로 돌아가면 된다. 자세한 방법은 문서에 정리해 두었다.

알아두면 좋은 점

1. 아직 초기 버전(1.1.0)이다. 불편하거나 이상한 점은 이슈로 알려주면 최대한 빠르게 고치고 있다.

2. 회사나 통신사 NAT처럼 여러 사람이 IP 하나를 같이 쓰는 경우엔 함께 차단될 수 있다. 아는 네트워크는 예외 네트워크에 넣어두자.

3. 서버 회선 자체를 가득 채우는 대규모 DDoS는 게이트웨이 하나로 막을 수 없다. 그런 경우엔 Cloudflare 같은 CDN을 앞에 두는 게 맞고, Corvus는 그 뒤에서도 실제 방문자 IP를 인식해서 동작한다.

마치며

Claude Code를 적극적으로 활용해서 개발했다. 대신 설계와 검증, 테스트는 직접 하나씩 챙기고 있다.

아직 부족한 부분이 분명 있을 거다. 실제로 설치해 보고 불편한 점이나 필요한 기능을 알려주면 정말 큰 도움이 된다.

GitHub: https://github.com/corvus-gateway/corvus
한국어 문서: https://corvus-gateway.github.io/corvus/ko/

공유