# 일부 봇을 차단하는 방법

> Clean Markdown view of GeekNews topic #31950. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=31950](https://news.hada.io/topic?id=31950)
- GeekNews Markdown: [https://news.hada.io/topic/31950.md](https://news.hada.io/topic/31950.md)
- Type: GN+
- Author: [xguru](https://news.hada.io/@xguru)
- Published: 2026-07-29T20:58:24+09:00
- Updated: 2026-07-29T20:58:24+09:00
- Original source: [nochan.net](https://nochan.net/b/Internet-Crap/20260606-How-To-Block-Some-Of-The-Bots/)
- Points: 1
- Comments: 1

## Topic Body

- CDN 없이 **HTTP 프로토콜/IP 대역/클라이언트 신호/TCP 특성/TLS 지문/콘텐츠 압축**을 조합해, 구현이나 설정이 부실한 봇 대부분을 차단하는 방법을 정리함  
- 모든 방법은 선택적으로 조정해야 하며, **1~3년치 접근 로그**를 먼저 분석하지 않으면 VPN 사용자/검색엔진/CDN/학교/도서관/특정 언어 사용자를 함께 차단할 수 있음  
- HTTP/1.1 클라이언트와 데이터센터의 AS/CIDR 대역을 차단하면 많은 봇을 제거할 수 있지만, **GoogleBot을 비롯한 검색엔진**과 정상적인 데이터센터 이용자도 제외될 수 있음  
- Nginx 헤더 검사와 nftables의 TCP 윈도 크기/MSS/TTL 필터는 단순 크롤러와 스캐너를 줄이지만, **LTE/VPN/Windows** 같은 정상 환경에서 오탐이 발생할 수 있음  
- 장기적으로는 **JA4 TLS 지문 탐지**와 Brotli 전용 응답을 대안으로 제시하지만 완전한 차단은 보장하지 않으며, 수익을 내는 서비스에는 사용하지 말 것을 경고함  
  
---  
  
### 차단 범위와 적용 전제  
  
- 차단 목표를 일부 봇/대부분의 봇/모든 봇 가운데 먼저 결정해야 함  
  - 여기서 다루는 방식은 정교한 자동화 도구 전체가 아니라 **구현이나 설정이 부실한 봇 대부분**을 비교적 단순하게 차단하는 데 초점을 둠  
  - 각 방식별로 정상 사용자와 검색엔진을 차단할 위험을 함께 표시함  
- 2026년 7월 26일 Hacker News에 공유된 뒤, 차단 기능 대부분을 블로그에서 별도의 데모 사이트로 옮겨 독자가 방법을 읽은 후 직접 접근을 시도하는 퍼즐 형태로 바꾸기로 함  
- 모든 설정은 선택적으로 수정하거나 생략할 수 있으며, 실제 적용 전 충분한 조사와 테스트가 필요함  
- 정상 사용자/조직 내부 시스템/의존 중인 외부 서비스가 차단될 수 있으므로 적용 책임은 전적으로 운영자에게 있음  
- **수익을 내는 운영 환경에는 사용하지 말 것**  
  
### 방법 1: HTTP 프로토콜로 구분  
  
- 정상 사용자 차단 위험은 낮고, 일부 검색엔진 차단 위험은 중간 수준  
- 일반 브라우저는 HTTP/2.0을 사용하지만 많은 봇은 HTTP/1.1을 사용한다는 차이를 이용함  
  - GoogleBot은 HTTP/1.1을 사용한다고 보며 이 방식으로 차단됨  
  - Bing과 Facebook 크롤러는 HTTP/2.0을 사용함  
  - HTTP/1.1로 링크 제목이나 짧은 미리보기를 가져오는 서비스도 차단될 수 있음  
  - Opera Mini도 대상에서 제외함  
- Nginx에서 `$server_protocol`이 `HTTP/2.0`이 아니면 다른 페이지로 리디렉션하거나 `200`, `403`, `444`를 반환하도록 구성함  
  
```nginx  
if ($server_protocol != HTTP/2.0) {  
    return 403 'Upgrade your client';  
}  
```  
  
- `444`를 반환하면 별도 응답 없이 연결을 끊을 수 있음  
- Google 검색 유입을 차단했을 때 발생할 손실보다 얻는 이점이 큰지는 각 조직이 직접 판단해야 함  
  
### 방법 2: 데이터센터 IP 대역 차단  
  
- 정상 가정용/LTE 사용자의 차단 위험은 낮지만 VPN 사용자는 중간 수준이며, 데이터센터에서 동작하는 검색엔진은 차단 위험이 높음  
- 최근 1~2년의 접근 로그에서 다음 신호를 조합해 의심스러운 요청을 찾음  
  - HTTP 프로토콜  
  - User-Agent  
  - `Accept-Language`  
  - `Sec-Fetch-Mode`  
  - `Accept`  
- 의심 IP를 [BGP Tools](https://bgp.tools/) 또는 [Hurricane Electric BGP Toolkit](https://bgp.he.net/)에서 조회해 소속 AS와 광고 중인 Prefix를 확인함  
- 제공된 [네트워크 블랙홀 목록](https://nochan.net/b/Internet-Crap/20260606-How-To-Block-Some-Of-The-Bots/20260714_network_blackholes.tar.bz2)은 CDN과 검색엔진 대역도 포함할 수 있으므로 선별 적용해야 함  
- 별도 목록에 앞서 `3/8`, `10/8`, `11/8`, `25/8`, `26/8`, `38/8`, `41/8`, `60/8`, `61/8`, `200/8`, `224/3` 대역을 이미 블랙홀 처리한 구성을 사용함  
- AS의 Prefix 페이지를 복사한 뒤 셸 함수로 CIDR만 추출하고 정렬/중복 제거/병합함  
  - [sum_cidr.pl](https://nochan.net/b/Internet-Crap/20260606-How-To-Block-Some-Of-The-Bots/sum_cidr.pl.bz2)을 사용하며 Perl 모듈 `Net::CIDR::Lite`가 필요함  
  - 생성된 결과는 검토 후 `/usr/local/etc/*.netset` 파일로 이동함  
- 서버 시작 시 각 CIDR을 블랙홀 라우트로 추가함  
  
```sh  
for CflIP in $(grep -E ^[1-9] /usr/local/etc/_cloudflare.netset); do  
    /sbin/ip route add blackhole "${CflIP}" 2>/dev/null  
done  
```  
  
- 예시에서는 Cloudflare 전체 대역을 차단해 Workers 등을 통한 요청을 받지 않도록 함  
- 방화벽의 ipset 규칙보다 **Linux 블랙홀 라우팅이 CPU를 적게 사용한다**는 이유로 라우팅 방식을 선택함  
- 현재 서버가 속한 호스팅 업체의 대역도 차단할 수 있음  
  - DNS/설정/내부 서비스에서 같은 주소 공간을 사용하지 않아야 함  
  - 직접 연결된 게이트웨이 경로는 블랙홀 경로보다 우선 적용됨  
  
### 방법 3: 국가/프록시/Tor/악성 IP 차단  
  
- [FireHOL Blocklists](https://github.com/firehol/blocklist-ipsets/) 저장소의 목록을 내려받아 필요한 대역을 블랙홀 라우트로 추가함  
- 목록 파일에는 주석이 포함되므로 `grep -Ev '^#'`로 제거한 뒤 처리해야 함  
- 특히 다음 목록을 권장함  
  - `firehol_abusers_30d.netset`  
  - `firehol_level2.netset`  
- 큰 목록은 시작 스크립트 실행 시간이 길어질 수 있음  
- 실제 서버와 방화벽 구성에 사용한 설정 파일도 제공함  
  - [전체 서버/방화벽 시작 설정](https://nochan.net/b/Internet-Crap/20260606-How-To-Block-Some-Of-The-Bots/extra_system_settings.txt)  
  - [웹 서버 전용 설정](https://nochan.net/b/Internet-Crap/20260606-How-To-Block-Some-Of-The-Bots/web_specific.txt)  
  - [웹 서버 sysctl 설정](https://nochan.net/b/Internet-Crap/20260606-How-To-Block-Some-Of-The-Bots/sysctl.conf.txt)  
  
### 방법 4: HTTP 클라이언트 신호 검사  
  
- User-Agent나 헤더는 위조할 수 있지만, 속도를 우선하는 단순 봇은 이를 제대로 위조하지 않는 경우가 많다는 전제를 사용함  
- `Curl`, `Wget` 요청에는 일반 텍스트를 반환하고 `Bot`, `GPT`, `LLM`, `Spider`가 포함된 요청에는 `410 Gone`을 반환함  
  
```nginx  
if ($http_user_agent ~* Curl)   { return 200 '\nGNU Terry Pratchett\n\n'; }  
if ($http_user_agent ~* Wget)   { return 200 '\nGNU Terry Pratchett\n\n'; }  
if ($http_user_agent ~* Bot)    { return 410 '1000101'; }  
if ($http_user_agent ~* GPT)    { return 410 '1000101'; }  
if ($http_user_agent ~* LLM)    { return 410 '1000101'; }  
if ($http_user_agent ~* Spider) { return 410 '1000101'; }  
```  
  
- 관찰된 User-Agent 일부 문자열을 하나의 긴 정규식으로 검사해 크롤러/스캐너/수집 도구를 차단함  
  - `Go-http`, `Java`, `libwww`, `okhttp`, `urllib`, `python`, `nmap`, `zgrab`, `semrush`, `shodan`, `rss`, `scrap`, `crawler`, `headless`, `github`, `facebook`, `google`, `bing` 등에 해당하는 부분 문자열이 포함됨  
- 적용 전에 2~3년치 User-Agent를 집계해 실제 정상 클라이언트가 정규식과 일치하는지 확인해야 함  
  
```sh  
sort access-user-agents.txt | uniq -c | sort  
```  
  
- 일치 요청이 HTTP/1.1이면 봇일 가능성이 높은 것으로 취급하되 GoogleBot은 예외로 고려함  
- HTTP/2.0 요청이라면 BGP 도구에서 IP 소속을 추가로 확인함  
  
#### Sec-Fetch-Mode  
  
- `Sec-Fetch-Mode`를 접근 로그에 추가하고 값이 `cors`, `no-cors`, `navigate` 중 하나가 아니면 차단함  
  
```nginx  
if ($http_sec_fetch_mode !~ (cors|no-cors|navigate)) {  
    return 410 '1000101';  
}  
```  
  
#### Referer 검사  
  
- 다른 사이트에서 콘텐츠를 삽입하거나 스캔하는 요청을 막기 위해 `Referer`에 특정 문자열이 있으면 차단함  
  - 관리자 페이지/검색엔진/소셜 네트워크/암호화폐/성인 콘텐츠/스캐너/WordPress 관련 문자열 등을 검사함  
- Google 루트 페이지 `https://www.google.com/`를 Referer로 주장하는 특정 봇 유형도 별도로 차단함  
  - 오래된 Android인 것처럼 가장하는 요청에서 관찰된 패턴임  
  
#### HTTP 메서드 제한  
  
- 정상 브라우저 요청에 필요한 `GET`과 `POST`만 허용하고 다른 메서드는 차단함  
  
```nginx  
if ($request_method !~ (^GET$|^POST)) {  
    return 410 '1000101';  
}  
```  
  
- 실제 애플리케이션에서 `POST`가 필요한 경로를 더 세부적으로 제한하거나, 사용하지 않는 경우 완전히 제외할 수 있음  
  
#### 프록시와 브라우저 형태 검사  
  
- `X-Forwarded-For` 헤더가 있으면 프록시 요청으로 판단해 차단함  
  - 학교나 도서관처럼 정상적인 공유 프록시 환경도 차단될 수 있음  
- User-Agent에 `Linux`, `BSD`, `Macintosh`, `Windows`, `Mozilla`, `WhatsApp` 중 하나도 없으면 브라우저처럼 보이지 않는 요청으로 판단함  
- `Accept-Language`에 `en` 또는 `es`가 없으면 차단하는 규칙도 사용함  
  - 일부 브라우저와 영어/스페인어를 쓰지 않는 정상 사용자를 차단할 가능성이 큼  
- `br` 또는 `sy`가 포함된 언어 설정을 별도로 차단하는 선택적 규칙도 제시함  
  
#### 민감한 경로 스캔 차단  
  
- 다음 파일이나 경로를 요청하면 자동 스캔으로 보고 차단함  
  - `.git`  
  - `.yml`  
  - `.db`  
  - `.sql`  
  - `.conf`  
  
### 방법 5: nftables로 TCP 스캐너 차단  
  
- nftables의 `raw` 테이블 `PREROUTING` 체인에서 TCP SYN 패킷 특성을 검사함  
- 예시 서버 주소 `172.238.221.88`을 목적지로 명시해 패킷 손실 상황에서 발생할 수 있는 오탐을 줄임  
- 80/443 포트로 들어오는 SYN 패킷 가운데 다음 조건을 차단함  
  - TCP 윈도 크기가 **12,288바이트 미만**  
  - MSS가 **1,220~1,460 범위 밖**  
- 실제 클라이언트는 더 큰 윈도 크기를 사용하며, 해당 범위를 벗어난 MSS는 정상 클라이언트일 가능성이 낮다는 기준을 사용함  
- MSS를 정확히 `1460`으로 제한하면 더 엄격해지지만 LTE와 VPN 사용자 대부분을 차단할 수 있음  
  
#### TTL 기반 선택적 제한  
  
- TCP SYN의 TTL이 `128`보다 크면 LTE 장치 대부분을 차단할 수 있음  
- TTL이 `64`보다 크면 Windows 시스템 대부분도 차단됨  
- 기본 TTL 기준은 다음과 같이 설명함  
  - Linux/Mac/BSD: `64`  
  - Windows: `128`  
  - LTE: 이보다 더 큰 값  
  
#### 연결 추적 제외  
  
- 80/443 포트를 `notrack`으로 지정해 conntrack 테이블에 웹 트래픽을 넣지 않음  
- 이 경우 filter 테이블에서도 송수신 방향에 대한 **상태 비저장 규칙**을 직접 구성해야 함  
- 예시에서는 클라이언트 출발 포트 `1000-65535`와 서버의 80/443 포트 사이 트래픽을 허용함  
  
### 방법 6: 성인 콘텐츠와 로봇 헤더  
  
- 성인 콘텐츠 접근 제한에는 [RTA: Restricted To Adults](https://www.rtalabel.org/index.php?content=howtofaq#single) 헤더를 사용함  
- RTA 이외의 연령 확인 방식은 사용자 추적과 수익화를 위한 것이라고 봄  
- Nginx 응답에 다음 헤더를 항상 추가함  
  
```nginx  
add_header Rating 'RTA-5042-1996-1400-1577-RTA' always;  
add_header adult 'porn, sex, politics, religion, philosophy' always;  
add_header X-Robots-Tag "none,noindex,nofollow,nosnippet,noai" always;  
```  
  
- 일반 봇은 이러한 헤더를 무시할 수 있지만, 검색엔진이나 성인 콘텐츠를 피하도록 설계된 봇에는 영향을 줄 수 있음  
  
### 방법 7: TLS 지문 탐지  
  
- 앞선 1~6번 방법은 모두 거친 휴리스틱이며, 장기적으로는 **TLS 지문 분석**이 더 나은 선택일 수 있음  
- 봇이 TLS 지문을 정상 브라우저와 동일하게 바꾸지 않는다는 조건에서 JA4를 활용할 수 있음  
- 먼저 [Deploying JA4](https://blog.miloslavhomer.cz/deploying-ja4/)의 배포 방법을 확인한 뒤 [FoxIO JA4](https://github.com/FoxIO-LLC/ja4)를 적용하도록 안내함  
  
### 방법 8: Brotli 압축 콘텐츠만 제공  
  
- 사이트 콘텐츠를 미리 Brotli로 압축하고 웹 서버가 압축된 파일만 반환하도록 구성함  
- 많은 봇이 Brotli 압축 HTML을 해석하지 못한다는 점을 이용함  
- 적용 후 여러 봇이 페이지 링크를 더 이상 따라가지 않아 HTML을 실제로 파싱하지 못하는 것으로 확인함  
- Nginx에서는 정적 Brotli 파일을 항상 제공하도록 설정함  
  
```nginx  
brotli_static always;  
```  
  
- HTML 파일은 다음과 같이 사전 압축함  
  
```sh  
cat ./i.html | brotli --best -fncv > ./i.html.br  
```  
  
### 방법 9: 스캐너의 자기 식별 유도  
  
- 반복적으로 취약점 경로를 탐색하는 초보 공격자와 스캐너를 줄이는 별도 방법은 [Help Attackers Self Report](https://nochan.net/b/Internet-Crap/20260524-Help-Attackers-Self-Report/)에서 다룸

## Comments



### Comment 62588

- Author: neo
- Created: 2026-07-29T20:58:25+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=49060945) 
- 여러 공개 웹사이트를 운영하고 다른 사이트를 긁어 도구에 활용하는 입장에서, 왜 사람들이 봇을 그토록 신경 쓰는지 궁금함  
  캐시를 둔 WordPress도 가장 저렴한 VPS에서 초당 약 **1,000개 요청**을 처리하고, 제대로 만든 정적 사이트라면 그 10배도 가능할 듯함. 블로그를 Lambda 같은 것으로 제공하는 건지, 아니면 강박이나 취약점 방어, 크롤링이 실제 서비스에 영향을 주던 시절의 습관인지 궁금함
  - 내 경우에는 **Forgejo 인스턴스**가 문제임. 블로그는 페이지 수가 제한된 정적 파일이라 괜찮지만, Forgejo는 봇이 사실상 무한히 페이지를 찾아낼 수 있고 일부 페이지를 만들 때 백그라운드에서 Git까지 실행하는 동적 서비스라 작은 서버가 쉽게 과부하됨  
    저장소는 오픈소스라 일부러 공개해 둠. 지금은 간단한 쿠키 검사로 방어하며 소수의 봇만 통과하지만, 검색 엔진 노출을 희생해야 하는 절충임
  - 공유 호스팅의 개인 사이트가 끊임없는 **AI 봇 크롤링**으로 CPU를 과도하게 사용해 최근 정지됐음. 크롤링 자체보다 봇이 너무 많고 비효율적으로 동작하는 게 문제임
  - 봇 운영자가 피하거나 우회하기 어려운 JavaScript 같은 공통 특성을 찾아보는 재미로 하는 실험임. 이 블로그는 RAM 디스크에 둔 사전 압축 정적 콘텐츠라 초당 수십만 요청도 처리할 수 있을 듯함  
    포럼, 이미지 게시판, 채팅 서버 등에 적용할 방법을 보여주려는 것이며 모든 선택지는 조정하거나 끌 수 있음. 실제 적용 전에는 시험 서버에서 검증해야 하고, 그냥 비웃고 넘어가도 괜찮음
  - 집에서는 **40Gbit 회선**과 그에 맞는 서버를 마련할 수 없음. Google Cloud VPS 몇 대가 nmap과 각종 웹 취약점 검사를 돌리며 분산 서비스 거부 공격을 해도 저사양 장비의 성능은 쉽게 떨어짐  
    DMZ가 막혀 로컬 IMAP 서버를 확인하는 데 몇 초 더 걸리는 게 큰일은 아니지만, 그렇다고 이를 좋아하거나 계속 허용할 이유도 없음
  - 봇 대응에 더 유용한 일을 할 시간을 빼앗기는 게 가장 큰 문제임  
    주말에 10~20년간 운영하던 viewvc(CVS·Subversion)와 hgweb(Mercurial) 웹 인터페이스를 종료했음. 주거용 프록시 IP에서 하루 **270만 건**, 평균 초당 30건의 요청이 들어와 오래된 uWSGI/CGI 프로그램과 같은 서버의 다른 사이트에 부담을 줬고, 트래픽도 VPS 한도인 월 1TB에 근접했기 때문임  
    동적 VCS URL 조합이 수백만 개일 수 있어 캐시 효과도 불확실하고, 서버를 더 조정하는 데 시간을 쓸 가치도 없어 결국 중앙집중형 인터넷에 한 걸음 더 가까워지는 선택을 했음

- “승인된” 사용자 에이전트 외의 모든 것을 차단하면 기존 **브라우저 독점**을 돕고 디스토피아를 앞당기게 됨. RMS가 수십 년 전부터 경고한 것도 이런 문제임  
  문제가 된다면 트래픽 양과 요청 빈도를 기준으로 막아야 함. 나 역시 사이트에 접속할 수 없지만 이에 맞춰 행동할 생각은 없으며, DRM처럼 의지가 강한 상대는 결국 통과할 것임
  - 그 비판은 받아들일 수 있음. RMS와 몇 번 함께했는데 흥미롭고 매우 영리한 사람이며, 이 문제로 만났다면 잔소리를 끝없이 들었을 듯함  
    다만 어떤 브라우저든 쓸 수 있다는 주장과 별개로, 즉흥적으로 생성한 코드이거나 악성 사이트에 맞서 충분히 검증되지 않은 브라우저는 특히 조심해야 함. 리더 앱도 침투 시험 전문가의 광범위한 제3자 코드 검토를 거치지 않았다면 **악성 서버**에 취약할 수 있음
  - 동작을 기준으로 판단할 수도 있음. go-away는 이미지와 CSS를 불러오는지, 메타 새로고침 리디렉션을 따라가는지 검사하고, Anubis는 몇 초 동안 **JavaScript 실행**이 가능한지 확인함
  - 사용자 에이전트 문자열 자체가 대체로 해로움. 새 브라우저라면 그냥 **Chrome 사용자 에이전트**를 복사하는 편이 나음

- `169.254.169.254`를 가리키는 가짜 **cpanel 하위 도메인**을 추가하면 초보 공격자가 자기 호스팅 업체를 포트 스캔하게 되어 탐지되거나 차단될 수 있다는 발상이 마음에 듦
  - 처음 실험했을 때는 아무 일도 없을 줄 알았음. 며칠 안에 독일 Amazon EC2의 한 사람이 피해야 할 레코드를 찾으려는 듯 내 도메인 일부에 영역 전송을 시도하더니, 이후 내 도메인을 완전히 제외했고 스캔도 곧 멈췄음  
    출발지 IP는 전 세계에 흩어져 있었지만 실제 스캔 잡음은 **단 한 사람**에게서 나온 셈임
  - AWS가 인스턴스 메타데이터 서비스(IMDS)에 fail2ban을 실행할 이유를 모르겠음. 구현을 믿지 못하는 건지, 대형 고객의 소송을 원하는 건지도 의문임

- **IP 기반 차단**은 주의해야 함. IP 대역은 가끔 재할당되므로 엉뚱한 사람을 막을 수 있으며, 지역이나 데이터센터라는 이유로 차단했던 대역이 주거용 ISP로 넘어간 경우도 여러 번 봤음  
  HTTP/1.1 차단도 오래된 브라우저를 쓰는 실제 사용자를 막을 위험이 큼. 또한 교차 출처 요청에서 전체 URL을 보내지 않는 브라우저가 있어 Google 검색에서 유입되면 리퍼러가 Google 루트 페이지만 가리킬 수 있으므로, 이를 봇의 거짓말로 단정해 막으면 Google 검색 유입까지 사라질 수 있음
  - 자신도 모르게 네트워크가 **주거용 VPN**에 재판매되는 사람도 안타깝게 많음  
    반면 HTTP/1.1 차단은 합리적이라고 봄. 거의 모든 브라우저가 이를 넘어선 프로토콜을 지원한 지 10년이 넘었고, 그 정도로 오래된 브라우저라면 이미 주류 웹 대부분이 깨지므로 개인 사이트 하나가 더 안 되는 것도 예외가 아니라 일상일 것임
  - 취미와 실험용 사이트에서는 **Google의 모든 ASN**을 완전히 차단함. 최근에는 유익한 트래픽을 받은 적이 없고 검색 품질도 망가졌다고 봄  
    오래된 브라우저와 API 도구를 놓치더라도 HTTP/1.1 차단은 유지할 예정임. 낡은 금융 시스템의 독점 코드라면 이해하지만, 공개 인터넷은 스스로를 위해 갱신해야 함  
    Google을 오래전부터 막았으므로 Google에서 왔다고 주장하는 요청은 모두 거짓임. 블로그를 여러 무작위 도메인으로 순환시켜 연관 관계와 스냅샷을 끊고, 사람들이 내 글을 발견하는 경로를 통제하려 함
  - 몇 년 전 AWS에서 들어오는 트래픽을 차단하고 글을 썼음. 평소 실제 방문자는 주당 수십 명뿐인데 그 글은 약 3개월간 **실제 사람 15,000명**이 봤고도 빠르게 잊혔음  
    덕분에 무료 침투 시험도 받았으며, 방어책과 처리 파이프라인이 견고하다는 결론을 얻음. 생존 압력 때문에 봇 트래픽의 90%가 VPN으로 이동해 VPN 종단점이 크리스마스트리처럼 빛나고 있음  
    일회성 접근 IP 피드를 제공할 수도 있지만, 이용자는 제대로 검증받고 용도도 승인받아야 함. 이 과정 자체가 재미있음
  - 글쓴이는 여러 종류의 실제 사용자를 차단해도 괜찮다고 명시했으므로, 그 조언은 따르지 않겠음

- 읽을 수 없다면 보관본 [https://archive.ph/d3236](<https://archive.ph/d3236>)에서 볼 수 있음
  - 일반적인 iOS Safari 사용자에게는 안타까운 구현임: [https://i.ibb.co/vCDH79d0/IMG-0303.png](<https://i.ibb.co/vCDH79d0/IMG-0303.png>)  
    봇도 아닌데 무언가를 읽기 위해 iCloud Private Relay를 끄고 싶지는 않음. 글쓴이의 다른 답변에 따르면 시험 사이트로서는 좋은 구현이지만, 다른 웹 관리자는 가능하면 모든 방식을 그대로 도입하지 않았으면 함
  - 나도 접속하지 못했는데 **archive.ph 크롤러**는 무사히 통과했다는 점이 재미있음

- 응답 본문에 410과 `Sec-Fetch-Mode:` 문자열만 나오는 걸 보면 나를 봇으로 판단한 듯함. 읽을 것도 볼 것도 없어 그냥 떠나게 되며, 현대 웹은 끔찍함
  - 실제 브라우저는 해당 헤더를 보내지만 일부 리더 앱과 Chrome Headless를 쓰지 않는 대부분의 봇은 보내지 않음  
    지원 현황은 [https://caniuse.com/?search=sec-fetch-mode](<https://caniuse.com/?search=sec-fetch-mode>)에서, 일부 헤더는 [https://nochan.net/.env](<https://nochan.net/.env>)에서 확인 가능함
  - 거기까지도 못 가고 **TLS 핸드셰이크**조차 통과하지 못했다는 `PR_END_OF_FILE_ERROR`가 발생했음

- 웹 트래픽의 **99% 이상이 봇이나 에이전트**일 것으로 예상되어 방문자 수 표시를 없앨까 고민 중임. 수치가 무의미하고 실제보다 사이트가 훨씬 붐벼 보이지만, 진짜 사람이 글을 읽거나 책을 내려받지 못하게 될까 봐 대응을 망설이고 있음
  - 테크노 스릴러·SF·미스터리 소설이라니 나중에 살펴보고 싶음

- 차단이 필요하다면 일반적으로 **허용 목록**이 거부 목록보다 효과적이며, 허용 목록을 적용할 수 없다면 이 방식도 좋은 해법이 아닐 수 있음  
  Cloudflare와 Anubis 같은 도구는 심각한 접근성 문제를 일으킬 수 있어 요청 빈도 제한을 선호함. 접근성을 해치지 않으면서도 깔끔하고, 일시적 문제에는 짧은 IP 차단도 잘 작동함  
  개인적으로 fail2ban으로 HTTP 로그를 분석해 `robots.txt`에서 금지한 URL이나 `wp-login.php` 같은 경로를 요청하거나 요청 빈도 제한을 지나치게 자주 넘는 IP를 N시간 차단함. 현재 Git 웹 UI에서는 Anubis를 시험 중임
  - 기업 간 통신에서는 **네트워크 간 VPN**으로 허용 목록을 구현했음. VPN 밖에서는 서버에 접근할 수 없고 직원은 회사 VPN을 통해 접속할 수 있음

- fail2ban만으로도 꽤 잘 막을 수 있지만, 처음 몇 달은 환경에 맞게 세밀하게 조정해야 함  
  먼저 `failregex = ^ - \S+ \[\] ".*?" 40[034]` 필터로 탐지한 뒤 더 구체적인 목록에 추가했으며, 지금은 약 **80개의 정규식**으로 모든 트래픽을 차단해 일반 `40[034]` 필터까지 도달하는 요청이 오래도록 없었음  
  다만 로드 밸런서나 프록시 뒤에서는 실제 IP를 얻는 방법이 필요해 fail2ban과 원문의 방식 모두 번거로워짐
  - 대부분의 **7계층 로드 밸런서**는 실제 IP가 담긴 헤더를 추가하는 기능을 제공함. 웹 서버가 그 헤더를 기록하도록 설정하면 되며, CDN이 실제 IP를 전달하는 방식과 매우 비슷함

- 이 댓글들과 내 접속 시도를 보면 봇뿐 아니라 **정상 트래픽도 모두 차단**하는 듯함
  - 댓글만 보면 오해할 수 있음. 지금까지 약 **2,600명**과 일부 봇은 글을 볼 수 있었음  
    일요일에는 사람들이 웹을 탐색할 때 쓰는 특이한 브라우저와 앱을 가장 많이 볼 수 있고, 평일에는 평범한 주류 브라우저가 많아 좋은 시험이 됨
