네이버 검색 유입이 제 사이트 트래픽의 대부분을 차지합니다. 그래서 네이버 크롤러가 들어오고 있는지가 꽤 중요한 숫자입니다. 어느 날 apex 도메인에 curl을 날려봤더니 403이 돌아왔습니다.
곧바로 가설이 섰습니다. CDN 엣지가 네이버 크롤러를 차단하고 있다. 이건 최우선 작업입니다. 유입의 87%가 오는 채널이 문턱에서 막혀 있다면 다른 어떤 SEO 작업도 의미가 없으니까요. 인계 문서에 "차단이면 최우선"이라고 적어서 넘겼습니다.
질문 하나 드리겠습니다. 당신이 "내 봇이 차단됐다"고 판정할 때, 그 근거는 어디서 나온 응답입니까?
실험을 더 해봤습니다. 전부 같은 답이 나왔습니다
가설을 굳히려고 조건을 늘렸습니다.
curl -sS -o /dev/null -w '%{http_code}\n' -A 'Yeti/1.1' https://<apex>/
curl -sS -o /dev/null -w '%{http_code}\n' -A 'Googlebot/2.1' https://<apex>/
curl -sS -o /dev/null -w '%{http_code}\n' -A '<정상 브라우저 UA>' https://<apex>/셋 다 403이었습니다. 이쯤 되면 보통 "확정"이라고 씁니다. 실제로 저는 그렇게 썼습니다.
그런데 세 번째 줄이 이상합니다. 평범한 브라우저 UA도 403입니다. 엣지가 진짜로 봇만 골라 막는 중이라면, 브라우저 행세를 한 요청은 통과해야 합니다. 통과하지 못했다는 건 이 실험이 "누구를 막는가"를 전혀 구분하지 못한다는 뜻입니다.
여기서 1원칙 질문을 걸었습니다. 이 실험은 '통과'라는 결과를 낼 수 있는 구조인가?
아니었습니다. CDN의 봇 검증은 UA 문자열이 아니라 요청 IP의 역방향 DNS로 합니다. 제 노트북에서 나간 요청은 UA에 뭘 적든 검증된 크롤러가 될 수 없습니다. 그래서 모든 조건이 같은 답을 줍니다. 조건을 아무리 늘려도 정보량은 0입니다.
그리고 403 자체도 오독이었습니다. 그건 "차단"이 아니라 브라우저 챌린지 페이지였습니다. 검증된 봇은 그 페이지를 애초에 만나지 않습니다. 증상(403)과 원인(차단)을 같은 것으로 읽은 겁니다.
판정은 원본 access log에서 나왔습니다
당신이라면 여기서 어디를 보겠습니까?
- 엣지 대시보드의 봇 관리 화면 — 차단 규칙 목록을 확인한다.
- 검색엔진 콘솔의 "수집 요청" 화면 — 크롤러가 왔는지 본다.
- 원본 서버의 access log — 그 봇 UA의 상태코드 분포를 센다.
1번은 "무엇을 막도록 설정했는가"만 말합니다. 실제로 막혔는지는 말하지 않습니다. 2번은 더 위험합니다. 서치어드바이저·서치콘솔의 그 화면은 접수를 보여주지 접수 뒤에 무슨 일이 있었는지는 안 보여줍니다.
3번으로 갔습니다. 원본 서버에서 해당 창의 접근 기록을 크롤러 UA로 걸러 상태코드만 셌습니다.
Yeti GET / 200
Yeti GET /sitemap.xml 200
Yeti GET /robots.txt 304403은 0건이었습니다. 크롤러는 들어오고 있었고, 한 번도 막힌 적이 없었습니다. 엣지 예외 등록 작업은 처음부터 존재하지 않는 문제였습니다.
가설이 기각된 뒤에 진짜 문제가 나왔습니다
여기서 끝냈으면 "오탐이었다"로 정리됐을 겁니다. 그런데 같은 로그가 다음 질문에 답을 줬습니다. 막힌 게 아니면, 얼마나 자주 오는가?
- 네이버 크롤러: 하루 3건
- 구글 크롤러: 하루 18건
6배 차이입니다. 문제는 진입이 아니라 크롤 예산이었습니다. 차단 가설이 맞았다면 고칠 게 한 줄(엣지 예외)이었을 텐데, 실제 문제는 훨씬 느리고 비싼 쪽입니다. 사이트 신뢰도와 내부 링크 구조로 크롤 빈도를 올려야 하는 일입니다.
이 숫자는 곧바로 다른 판정의 분모로 들어갔습니다. 새 파라미터 페이지 227개를 배포해두고 색인 속도를 기다리는 중인데, 하루 3건짜리 크롤 예산이면 227개가 다 돌기까지 걸리는 시간이 판정 창의 상한입니다. 페이지를 늘렸는데 히트가 줄었던 이야기에서 배운 "수율부터 보라"가 여기서 "예산부터 보라"로 이어집니다.
자가진단 3개
- 그 실험이 '통과'를 출력할 수 있는 구조인가. 모든 조건이 같은 답을 주면 조건을 늘려도 정보량은 0입니다. 실험 설계할 때 "반대 결과가 나오려면 무엇이 참이어야 하는가"를 먼저 적어두세요.
- 판정 근거가 엣지 응답인가 원본 로그인가. 엣지는 나에게 준 답을 말할 뿐, 봇에게 준 답을 말하지 않습니다. 로그를 못 보는 상황이면 판정이 아니라 확인 못 함으로 남겨야 합니다.
- 증상 코드와 원인을 같은 칸에 쓰고 있지 않은가.
403은 차단·챌린지·레이트리밋·오설정이 전부 내는 코드입니다. 코드 하나로 원인을 확정하면, 없는 문제를 최우선으로 올리게 됩니다.
솔직한 부분
이 조사로 트래픽은 1도 늘지 않았습니다. 얻은 건 두 가지입니다. 하지 않아도 될 작업 하나를 최우선 목록에서 지웠고, 실제 병목(크롤 빈도)의 숫자를 손에 쥐었습니다.
부끄러운 부분도 적어둡니다. 저는 세 가지 조건으로 실험했다는 사실 자체를 근거의 강도로 착각했습니다. 표본을 늘린 게 아니라 같은 편향을 세 번 반복한 것이었는데도요. 반복은 검증이 아닙니다.
지금 당신이 "차단된 것 같다"고 적어둔 이슈가 하나 있다면, 그 판정의 출처를 확인해보세요. 원본 로그에서 나온 상태코드입니까, 아니면 당신이 직접 찔러본 응답입니까?