
소규모 HTTP 서비스를 위한 사용자 공간 봇 및 DDoS 방어
DDoS 및 봇 남용을 헛된 노력으로 바꾸는 사용자 공간 기만 계층.
Net Ward는 HTTP 서비스 앞에 리버스 프록시로 위치합니다. 실제 트래픽은 그대로 통과합니다. 알려진 프로브와 플러드는 봇의 노력을 소모시키는 무해한 미러 응답을 받으며 절대 애플리케이션에 도달하지 않습니다 — 커널 훅 없음, 페이로드 없음, 보복 없음, 설계상 페일오픈.
Dragon Lady가 구축하고 유지 관리합니다 — github.com/Dragon-Lady · X: @answerislove2 실제 환경에서 진행 중인 공급망 및 봇 남용 캠페인을 추적하는 독립 보안 연구자.
웹사이트: dragon-lady.github.io/netward-standalone
python -m pip install --upgrade "netward>=0.4.12"
python -m netward --config example_config.json
버전 0.4.12 이상이 신규 설치 및 업그레이드에 권장되는 기준입니다. 이전 릴리스는 재현성을 위해 계속 제공되지만, 신규 배포에는 현재 릴리스를 사용해야 합니다.
또는 소스에서:
git clone https://github.com/Dragon-Lady/netward-standalone
cd netward-standalone
pip install -e .
Net Ward는 listen_address에서 수신 대기하고 정상 트래픽을 upstream_target으로 전달합니다.
예제 구성을 복사하고 업스트림 대상을 편집하세요:
cp example_config.json config.json
Net Ward를 시작하기 전에 upstream_target을 실제 HTTP 서비스로 지정하세요. 업스트림에 연결할 수 없는 경우, 일치하지 않는 요청은 원시 프록시 오류를 노출하는 대신 기본 미러 응답을 반환합니다.
필수 필드:
| 필드 | 의미 |
|---|---|
node_id | 이 Net Ward 인스턴스의 고정 이름 |
upstream_target | 보호 대상 HTTP 서비스 |
listen_address | Net Ward가 바인딩할 호스트와 포트 |
선택적 필드는 미러 강도, 로컬 저장소, 메시 플레이스홀더, 알림 채널, 업스트림 타임아웃, 프로브 로그 보존을 제어합니다. 패턴 일치 또는 요청 폭주의 시작은 SQLite에 알림을 기록합니다. 알림은 종류, 소스, 패턴을 기준으로 5분 동안 중복 제거됩니다. alert_channels 목록이 비어 있으면 stdout으로 전송됩니다. 명시적 전달을 위해 stdout, email, slack, ntfy 중 원하는 조합을 선택하세요. 외부 전달은 백그라운드에서 실행되며 실패한 채널을 재시도합니다. 최근에 전달되지 않은 알림은 시작 시 재시도됩니다.
이메일에는 alert_email, alert_smtp_host, alert_smtp_from이 필요합니다. alert_smtp_port와 alert_smtp_security(starttls, ssl, none)를 설정하세요. none은 루프백 SMTP 서버에만 허용됩니다. 인증이 필요한 경우 alert_smtp_username과 alert_smtp_password_env를 비밀번호가 담긴 환경 변수 이름으로 설정하세요. Slack에는 alert_slack_webhook이 필요합니다. ntfy에는 alert_ntfy_topic(ntfy.sh의 토픽 또는 전체 자체 호스팅 토픽 URL)이 필요합니다. 보호된 토픽의 경우 alert_ntfy_token_env를 베어러 토큰이 담긴 환경 변수 이름으로 설정하세요. HTTP 대상은 루프백을 제외하고 HTTPS를 사용해야 합니다. alert_timeout_secs의 기본값은 5초입니다. Net Ward는 시작 시 요청된 대상을 확인하고 성공적인 전달 영수증을 alerts 테이블에 저장합니다. 알림 메시지에는 소스 IP, 패턴 ID, 분류가 포함되며, 원시 요청 본문이나 헤더는 포함되지 않습니다.
| 선택적 필드 | 기본값 | 의미 |
|---|---|---|
upstream_timeout_total | 10 | 업스트림 호출의 전체 요청 예산(초) |
upstream_timeout_connect | 3 | 연결(DNS + TCP + TLS) 타임아웃(초) |
upstream_timeout_sock_read | 5 | 업스트림 소켓 읽기 사이의 유휴 시간(초) |
upstream_max_concurrency | 64 | 처리 중인 업스트림 요청 수 |
upstream_max_body_bytes | 8388608 | 버퍼링되는 업스트림 응답 본문 최대 크기(8 MiB). 더 큰 본문은 기본 미러로 fail-open됨 |
probe_retention_secs | 604800 | 프로브 로그 TTL(7일) |
probe_max_rows | 10000 | 쓰기 시 퍼지 후 프로브 로그 최대 행 수 |
alert_timeout_secs | 5 | 외부 알림 전달의 채널별 타임아웃(초) |
python -m netward --config config.json
예시 토폴로지:
| 구성 요소 | 주소 |
|---|---|
| Net Ward | 127.0.0.1:8080 |
| 업스트림 앱 | http://127.0.0.1:9000 |
| 스토리지 | netward.db |
로드 밸런서 또는 웹 서버를 Net Ward로 향하게 하십시오. 가능하면 업스트림 앱은 호스트 또는 신뢰할 수 있는 네트워크에서만 접근 가능하도록 유지하십시오.
Net Ward를 localhost 외부에서 접근 가능하게 하려는 의도가 있을 때만 listen_address를 0.0.0.0:<port>로 설정하십시오.
Linux/macOS에서는 storage_path를 모든 사용자가 쓰기 가능한 상태로 두지 마십시오. 예: chmod 600 netward.db, 또는 모니터링을 위해 의도적으로 읽기 접근이 필요한 경우에만 chmod 644 netward.db.
Net Ward는 문서화된 박스당 용량을 지속적으로 유지하지만, Python 런타임 메모리 풀은 지속적인 고부하 후 작업 세트 상태를 보유할 수 있습니다. 지속적인 고트래픽 환경에서 Net Ward를 운영하는 운영자는 프로세스 리소스 사용량을 모니터링하고 데몬을 주기적으로 재시작해야 합니다. 예를 들어 매주 또는 RSS가 기준선의 2배를 초과할 때 재시작하십시오. v0.5에서는 자동 텔레메트리가 아닌 운영자 피드백과 로컬 테스트 관찰을 기반으로 이 지침을 개선할 예정입니다.
정상 요청은 업스트림에 도달해야 합니다:
curl -i http://127.0.0.1:8080/
알려진 프로브는 미러링되어야 합니다:
curl -i http://127.0.0.1:8080/wp-admin/
WordPress 프로브는 가짜 로그인 페이지를 반환합니다. 업스트림 서비스는 해당 요청을 수신하지 않습니다.
위의 예시 토폴로지를 사용하면, 정상적인 첫 실행은 다음과 같아야 합니다:
127.0.0.1:9000에서 작은 업스트림 서비스를 시작합니다.127.0.0.1:8080에서 Net Ward를 시작합니다./를 요청하고 업스트림 응답이 돌아오는지 확인합니다./wp-admin/을 요청하고 대신 미러 응답이 돌아오는지 확인합니다.예상 결과: 일반 트래픽은 업스트림 앱에 도달하는 반면, 알려진 프로브는 Net Ward의 미러 계층에서 처리됩니다. 이것이 프록시 경로, 패턴 매칭, 미러 응답이 모두 작동하고 있다는 가장 간단한 신호입니다.
번들로 제공되는 벤더 패턴 세트를 설치하거나 새로 고칩니다:
python -m netward.cli --db netward.db install-patterns
python -m netward.cli --db netward.db install-patterns --force
활성 패턴 나열:
python -m netward.cli --db netward.db list-patterns
데이터베이스에 쓰지 않고 프로브 보고서를 읽습니다. 보고서는 집계 카운트로 구성됩니다. 어떤 프로브 패밀리가 발동했는지, 해당 패밀리가 적중한 요청 경로별 총계, 그리고 얼마나 많은 소스가 관련되었는지입니다. 원시 IP 주소나 지리 정보는 출력하지 않습니다. --send는 동일한 다이제스트를 전달합니다. 경로 카운트는 포함되지만 원시 IP는 절대 포함되지 않습니다. 출력 파일은 소유자 전용(0600)입니다.
python -m netward.cli --db netward.db report
python -m netward.cli --db netward.db report --since 7d --format md --output report.md
python -m netward.cli --db netward.db report --format html --output report.html
python -m netward.cli --db netward.db report --family wordpress --top 10
python -m netward.cli --db netward.db report --send --config config.json
저장된 프로브 로그는 7일 또는 10,000행으로 제한됩니다. 보고서는 해당 기간을 설명하고 그 사실을 명시합니다. 더 엄격한 권장 패턴은 검토용으로 출력되며 설치되지 않습니다.
패턴 비활성화 또는 재활성화:
python -m netward.cli --db netward.db disable-pattern wordpress_admin_probe
python -m netward.cli --db netward.db enable-pattern wordpress_admin_probe
업스트림이 /admin에 실제 관리자 패널을 노출한다면, Net Ward를 해당 서비스 앞에 배치하기 전에 generic_admin_login_probe를 비활성화하거나 더 엄격한 운영자 패턴으로 교체하십시오:
python -m netward.cli --db netward.db disable-pattern generic_admin_login_probe
일부 벤더 패턴은 기본적으로 제공되지만 기본적으로 비활성화되어 있습니다. 이는 업스트림이 해당 패턴이 대상으로 하는 프로토콜 기능을 동일하게 사용하는 경우 정상 트래픽을 차단할 수 있기 때문입니다.
basic_auth_probeAuthorization: Basic <base64>를 통한 무차별 대입 자격 증명 스터핑(brute-force credential stuffing)을 탐지합니다.
다음 경우에만 활성화하는 것이 안전합니다: 업스트림이 HTTP Basic Auth를 전혀 사용하지 않는 경우. 업스트림이 실제 사용자로부터 Basic Auth 자격 증명을 수락하는 경우, 이 패턴을 활성화하면 해당 사용자들이 무한 401 루프에 갇히게 됩니다 — Net Ward가 가짜 챌린지를 반환하고, 브라우저가 다시 프롬프트를 표시하며, 이 주기가 반복됩니다.
활성화:
netward-cli --db netward.db enable-pattern basic_auth_probe
다시 비활성화:
netward-cli --db netward.db disable-pattern basic_auth_probe
활성화한 후 제대로 작동하는지 확인하려면:
curl -i -H "Authorization: Basic dXNlcjpwYXNz" http://127.0.0.1:8080/api/admin
401과 WWW-Authenticate: Basic realm="Restricted"를 반환해야 합니다. 업스트림은 해당 요청을 수신해서는 안 됩니다.
Net Ward는 fail-open 방식이며 사용자 공간에서만 동작합니다:
미러 계층은 자동화된 남용을 되받아치는 것이 아니라 흘려보내는 것을 목적으로 합니다.
로그인 값은 수집 대상이 아닙니다. 민감한 헤더(Authorization, Cookie, Set-Cookie, Proxy-Authorization 및 이와 유사한 헤더)와 비밀번호 형태의 본문 또는 쿼리 키는 프로브가 로컬 데이터베이스에 기록되기 전에 마스킹됩니다. 잔여 위험은 남아 있습니다: 다른 헤더, 비정형 본문, 그리고 해당 키 이름을 사용하지 않는 값들은 여전히 운영자의 통제 하에 로컬에 저장될 수 있습니다. 프로브 로그를 자격 증명 보관소로 취급하지 말고, 공개 보고서에 실제 비밀 정보를 전송하지 마십시오.
Net Ward는 프로젝트 유지관리자에게 텔레메트리를 전송하지 않으며, 운영자 트래픽을 어떤 외부 목적으로도 사용하지 않습니다.