1P by GN⁺ | ★ favorite | 댓글 1개
  • HTTP 접근 전에 작업 증명(Proof-of-Work) 을 요구하는 Anubis는 AI 스크레이퍼보다 일반 사용자와 저사양 기기, JavaScript 미지원 클라이언트에 더 큰 지속적 비용을 부과함
  • LLM이 만든 anubis-fetch는 작업 증명을 직접 풀고 필요하면 Chromium을 실행하며, Chrome의 TLS/JA3 지문을 모방해 Cloudflare의 수동 차단까지 통과함
  • 스크레이퍼는 발급받은 쿠키를 캐시·재사용해 비용을 여러 요청에 걸쳐 상각할 수 있지만, 사람은 방문할 때마다 수초의 대기와 배터리 소모를 감수해야 함
  • 기본 난이도 4는 평균 65,536회 해시를 요구하며, 네이티브 Go 구현은 약 1.3ms, 브라우저 JavaScript는 약 130ms가 걸리지만 실제 체감 대기 시간은 약 1~5초임
  • 회당 체감 시간 2초와 에너지 20J를 가정하면 하루 100만 회의 도전은 연간 약 23인년·2MWh, 하루 1억 회는 약 2,300인년·200MWh를 소모함

AI가 우회한 Anubis

  • Linux 커널에서 binfmt_misc의 bpf를 통해 인터프리터 PT_INTERP$ORIGIN을 지원하는 패치를 작업하면서, LLM에 Linux 커널 메일링 리스트 스레드를 읽도록 요청함
  • lore.kernel.org는 리소스 접근 전에 작업 증명을 요구하는 HTTP 프록시 Anubis를 도입한 상태였음
  • LLM은 이 제한을 처리하는 anubis-fetch를 제작함
    • 우선 작업 증명을 네이티브로 풀고, 실패하면 Chromium으로 URL을 방문함
    • req로 실제 Chrome의 TLS/JA3 지문을 모방해 Cloudflare의 수동 차단도 통과함
    • anubis-fetch <URL>은 HTML을 표준 출력으로 내보내고, --text 옵션은 읽기 쉬운 일반 텍스트를 출력함
  • Anubis가 겨냥한 AI와 봇은 작업 증명 지원을 한 번 추가하면 쉽게 우회할 수 있음
    • 스크레이퍼는 도전을 해결한 뒤 받은 쿠키를 캐시·재사용해 비용을 여러 요청에 걸쳐 상각함
    • 반면 사람은 방문할 때마다 스피너를 기다리고 배터리를 소비하며, 이 비용을 다른 사용자와 나눌 수 없음
    • 저사양 기기와 스마트폰일수록 부담이 커지고, JavaScript를 사용하지 않는 w3m·lynx·스크린 리더·RSS 리더는 접근할 수 없음
  • AI를 막으려는 장치가 AI에는 쉽게 우회되는 반면, 사람과 개방형 웹에는 계속 비용을 부과하는 역진적 부담으로 작동함

작업 증명이 만드는 시간·에너지 비용

  • 난이도 d는 해시가 가져야 하는 선행 0의 16진수 문자 개수이며, 풀이당 기대 작업량은 W = 16^d회 해시임
    • 흔한 기본값인 난이도 4는 65,536회 해시를 요구함
      • 약 50 MH/s인 네이티브 Go 구현: 약 1.3ms
      • 약 0.5 MH/s인 브라우저 JavaScript: 약 130ms
      • 페이지 로드와 워커 실행, 재로딩을 포함한 체감 시간: 약 1~5초
    • 난이도 5는 1,048,576회 해시를 요구함
      • 네이티브 Go 구현: 약 20ms
      • 브라우저 JavaScript: 약 2초
      • 체감 시간: 약 5~15초
  • 전 세계의 일일 Anubis 도전 풀이 횟수를 C, 회당 체감 시간을 t = 2초, 화면과 CPU를 포함한 기기 에너지를 E = 20J로 가정함
    • 연간 사람 시간은 C × t × 365 / 3.15×10⁷로 계산함
    • 연간 에너지는 C × E × 365 / 3.6×10⁶kWh로 계산함
  • 이 가정에 따른 연간 비용은 다음과 같음
    • 하루 100만 회: 약 23인년, 약 2MWh
    • 하루 1,000만 회: 약 230인년, 약 20MWh
    • 하루 1억 회: 약 2,300인년, 약 200MWh
  • 모든 수치는 대략적인 추정치이며, 봇 팜과 AI 도구가 몇 자릿수 더 많은 에너지를 사용하므로 환경 문제를 주장하기 위한 계산은 아님
  • 로봇에게 시간은 제약이 아니지만 사람의 시간은 유한하므로, 이용자들은 AI 시대 이전에는 없었던 웹사이트 접근 대기에 집단적으로 상당한 시간을 쓰게 됨

댓글과 토론

Lobste.rs 의견들
  • Anubis가 겨냥하는 대상이 이를 손쉽게 무력화한다는 말에는 동의하기 어려움. Anubis의 주된 목표는 LLM 에이전트나 바이브 코딩으로 만든 프로그램이 아니라, LLM 회사들이 쓰는 무차별 웹 스크레이퍼를 막는 것임
    우회 방법이 있고 에이전트나 LLM을 활용할 수도 있지만, 대다수 스크레이퍼는 단순하며 운영자도 Anubis를 적용한 소수 사이트까지 굳이 우회하려 하지 않음. 우회 비용을 살짝 높여 수집할 가치가 없게 만드는 것이 목적에 가까움

    • Anubis는 주거용 프록시를 이용하는 스크레이퍼가 서버를 마비시키는 상황을 막는 데는 잘 작동할 것임. 개별 에이전트의 요청은 사용자가 직접 사이트를 둘러보는 것과 크게 다르지 않음
      다만 이 목적에는 Anubis가 과도하게 설계되었음. 버튼을 한 번 누르게 한 뒤 접근 쿠키를 발급해도 같은 보호 효과를 얻을 수 있으며, Apache에 구현해 보니 복잡한 작업 증명 없이도 충분히 잘 작동함
    • LLM 회사의 스크레이퍼라기보다 조악하고 남용적인 웹 스크레이퍼 전반이 대상임. 그중 일부를 LLM 회사가 운영한다는 추정이 있을 뿐임
    • 웹사이트에서 늘어난 트래픽은 OpenAI, Anthropic, Meta 같은 곳이 아니라 다른 주체들에게서 오고 있어, 무엇을 LLM 회사로 정의하는지 불분명함
      내 데이터 마이닝 작업에서도 쓰는 현대적인 스크레이핑 도구는 방해물을 거의 모두 우회할 만큼 뛰어나며, Anubis 역시 손쉽게 우회 가능함
    • 개인 사이트와 소프트웨어에 대한 RAG 접근도 막고 싶어 기본적인 사용자 에이전트 차단을 적용함. ChatGPT에서 직접 사이트 접근을 요청해 시험해 보니 잘 막혔음
      매우 특수한 구성은 빠져나갈 수 있지만, 악의적인 상대가 아니라 게으른 상대를 막는 것이 목표임
    • Anubis가 주로 막는 것은 Chrome인 척 어설프게 위장한 초보적인 Python requests 스크레이퍼이며, 그 밖의 차단 효과는 덤에 가까움
  • Anubis는 봇을 걸러내는 것이 아니라 클라이언트의 요청 속도를 제한

  • Anubis는 AI 에이전트의 접근을 막기보다 서비스 거부 공격 방어 수단에 가깝고, 현실적으로 AI 에이전트를 판별해 차단하기도 어려움
    하지만 모바일 기기에서 낯선 사이트를 방문해 JavaScript를 꺼둔 나 같은 사용자도 함께 차단함

  • 실제 운영 결과를 보면 글의 결론에 동의하기 어려움. 홈랩의 웹사이트를 fly.io 공개 프록시와 Tailscale 포워딩으로 서비스했는데, Facebook을 비롯한 스크레이퍼 때문에 매달 약 20달러의 대역폭 요금이 발생했음
    프록시에 Anubis를 적용한 뒤 무료 구간으로 돌아왔음. 필요하면 우회할 수 있어도 괜찮으며, robots.txt를 무시하는 소수 악성 주체의 대량 수집 트래픽만 대부분 차단하면 충분함

  • 스마트 TV 같은 저사양 기기의 봇넷을 활용하는 스크레이핑 작업에는 Anubis의 작업 증명이 실제 장애물이 될 수 있어 보임. https://lobste.rs/s/kpaxih/update_on_scraper_situation 에도 이 문제가 조금 다뤄져 있음

    • 잘못 알고 있는 게 아니라면 스마트 TV는 프록시로만 사용되고, 작업 증명 자체를 수행하지는 않음
  • Anubis에서 가장 신경 쓰이는 부분은 열린 웹과의 충돌임. 내 웹사이트는 주로 RSS 피드로 소비되는데, RSS를 Anubis로 보호하면 피드가 작동하지 않고 보호하지 않으면 모든 콘텐츠가 기계가 읽기 쉬운 형태로 스크레이퍼에 노출됨
    이런 작업 증명 장벽은 우리가 지향했던 열린 웹이나 인디웹과 근본적으로 양립하기 어려움

    • 지난 1년 동안 이런 불가능한 절충안 사이에 갇혀 있었고, 나 역시 좋은 해답을 찾지 못함
  • 다른 사람이 내린 선택을 존중하지 않는 태도가 노골적으로 드러남

  • 가장 불쾌한 점은 이것이 CFAA 같은 법률을 명백히 위반하는 행위로 보이는데도, 다른 범죄성 DDoS 서비스처럼 신원을 감춘다는 것임
    타인의 작업물을 훔치고 오픈 소스 코드를 세탁하는 데 사업 모델 전체를 의존하는 회사가 법을 지키리라 기대하는 것 자체가 우스움

  • Anubis는 보통 Dillo를 막지 않지만 사이트 설정에 따라 차단되기도 하며, 이는 JavaScript가 없으면 존재할 자격도 없다는 분위기를 조장해 매우 성가심: https://paste.rs/jNgwd.png
    주거용 프록시에 포함된 모든 IP 목록을 수집·관리하고 일정 기간 차단할 수 있을지 고민 중이며, ipset이 이 규모를 감당할 수도 있음. 로그를 보면 봇은 CSS나 이미지 같은 다른 자원은 불러오지 않으면서 Dillo 저장소의 모든 커밋에 있는 모든 파일을 순회하므로 비교적 쉽게 식별 가능함
    각 사이트에서는 IP당 요청 하나만 보여도 같은 IP가 여러 사이트를 가져올 가능성이 높으므로, 여러 차례 신고된 IP를 차단할 수 있음. 단순히 연결을 끊지 말고 별도 포트의 안내 페이지로 리디렉션해 차단 이유와 해결 방법을 알려줘야 함
    이렇게 하면 브라우저 확장이나 휴대폰 앱에 역방향 프록시 백도어를 심을 유인도 줄어듦. 사용자가 실제로 차단되기 시작할 것이기 때문임
    IP 평판 시스템에 의존해야 한다는 점은 안타깝지만 다른 효과적인 대응책이 잘 보이지 않음. 취약한 기기는 봇넷 명령제어 서버가 제거되어도 다음 공격자에게 다시 장악돼 새 봇넷에 편입될 수 있음

  • 글에서 “물론 LLM의 도움을 받아 이 작업을 하고 있다”고 했는데, 그렇다면 왜 바이브 코딩 태그가 붙지 않았는지 궁금함

    • 글쓴이가 컴파일러나 편집기를 사용했어도 해당 태그를 붙이지 않듯, 이 글의 주제가 바이브 코딩은 아니기 때문임. vibecoding 태그는 pushcx가 제거했음
    • 게시할 때는 차단을 우회하는 무언가를 바이브 코딩했다고 글에 명시돼 있어 해당 태그를 붙였음. 이보다 AI 코딩을 덜 언급한 글에도 태그가 붙곤 해서 삭제된 것이 의외지만, 이 태그의 적용 기준은 완전히 일관성이 없다고 받아들이게 됨