Trawling

Laurens Bosscher의 AdGuard Home 포크, OpenStick서 DNS 차단 해시 218만 개 운용

Laurens Bosscher가 만든 AdGuard Home Next-Gen은 단순 DNS 차단 규칙을 정렬된 40비트 해시 파일로 분리해 메모리를 아낍니다. Bosscher가 2026년 11월 1일 465MiB AArch64 OpenStick에서 기록한 시험에서는 고유 해시 218만 개를 적재한 뒤 서비스 RSS가 안정 상태 약 47MiB, 필터 갱신 중 최고 약 122MiB였습니다. 복잡한 규칙은 기존 엔진에 남으며, 전체 목록 시험에서는 40비트 해시 충돌 3건도 기록됐습니다.

Laurens Bosscher는 11월 7일 개인 블로그에서 배송비를 포함해 10달러에 산 OpenStick 홈랩을 소개했습니다. 이 USB형 4G 장치에는 512MB RAM과 4GB eMMC가 있고, Bosscher는 Debian을 설치해 여러 서비스를 운영합니다. 그중 AdGuard Home Next-Gen은 Bosscher가 만든 별도 포크로, 메모리가 제한된 라우터나 소형 보드에서 큰 DNS 차단 목록을 다루는 데 초점을 둡니다.

AdGuard Home은 기기에서 오는 DNS 요청을 받아 차단 목록을 확인하고, 해당 도메인에 연결되지 않도록 응답하는 서버입니다. 목록이 커지면 규칙을 저장하고 검색하는 데 필요한 메모리도 늘어납니다. Bosscher의 설계 문서는 기존 urlfilter 경로가 규칙 객체와 검색 인덱스를 메모리에 보유한다고 설명합니다. 필터를 갱신할 때는 기존 엔진이 DNS 요청에 응답하는 동안 새 엔진을 구성해 두 엔진의 메모리 사용량이 한동안 겹칩니다.

단순 도메인 규칙만 별도 인덱스로

Next-Gen은 모든 규칙을 같은 방식으로 처리하지 않습니다. hosts와 ||domain^처럼 도메인만 확인하는 규칙은 40비트로 자른 FNV-1a 해시로 바꿔 정렬된 blocklist.bin 파일에 저장합니다. 복잡한 Adblock 규칙과 허용 목록은 기존 urlfilter 경로에 남습니다.

Bosscher의 설계 문서는 기존 경로에서 규칙 객체 하나가 약 296바이트에 인덱스 비용을 더한다고 설명합니다. 반면 단순 도메인 100만 개는 5바이트 해시 파일 약 4.8MiB로 표현할 수 있습니다. 이 방식은 모든 규칙을 메모리의 객체로 유지하는 대신, 흔한 단순 도메인 규칙의 저장 형태를 짧은 해시로 바꿉니다.

목록을 갱신할 때 프로그램은 규칙을 한꺼번에 메모리에 펼치지 않습니다. 목록을 읽으면서 단순 규칙을 묶음 단위로 해시하고, 정렬한 임시 파일을 외부 정렬 방식으로 합쳐 최종 인덱스를 만듭니다. 묶음 크기는 Linux가 보고하는 사용 가능 메모리에서 여유분을 뺀 값에 맞춥니다. 목록을 만드는 동안에도 메모리 사용량을 제한하려는 설계입니다.

DNS 요청이 들어오면 프로그램은 인덱스 파일을 mmap으로 매핑해 이진 검색하고, 요청한 도메인과 상위 도메인 접미사를 조회합니다. Linux는 처음 접근하는 페이지를 페이지 캐시에 올리고, 반복 조회에서는 캐시에 남은 페이지를 사용합니다. 메모리가 부족해지면 커널이 깨끗한 매핑 페이지를 회수할 수 있으며, 이후 다시 접근할 때 페이지를 불러옵니다.

465MiB OpenStick에서 기록한 메모리 사용량

Bosscher가 저장소에 기록한 2026년 11월 1일 실측은 AArch64 OpenStick에서 진행했습니다. 시스템이 인식한 메모리는 465MiB였고, AdGuard Home 서비스에는 MemoryMax=250M이 설정됐습니다. 기존 필터에 HaGeZi Normal, Pro, Ultimate와 Threat Intelligence Feeds를 더한 뒤, 해시 경로에 들어간 도메인 규칙은 2,708,009개, 고유 해시는 2,184,149개, blocklist.bin은 11MiB였습니다.

기본 필터 상태에서 고유 해시는 185,994개, 안정 상태 RSS는 약 38MiB였습니다. 전체 목록을 적재한 뒤 고유 해시는 약 12배로 늘었고, 안정 상태 RSS는 약 47MiB가 됐습니다. 목록 갱신 중 최고 RSS는 약 122MiB였습니다. Bosscher의 시험 기록에는 doubleclick.net DNS 요청이 0.0.0.0으로 응답한 사례도 담겼습니다. 이 수치와 사례는 Bosscher가 자신의 장치에서 기록한 결과입니다.

해시 인덱스는 규칙 원문이 아니라 짧은 해시값을 비교합니다. 따라서 해시가 충돌하면 차단 목록에 없는 도메인도 차단 대상으로 판정될 수 있습니다. Bosscher는 40비트 해시를 사용한 전체 목록 시험에서 충돌 3건을 기록했으며, 위협 정보 목록에서 충돌 가능성을 더 낮추려는 설정으로 8바이트 해시를 제시합니다. 더 긴 해시는 인덱스 파일도 키웁니다. 복잡한 규칙과 허용 목록은 계속 urlfilter가 처리하므로, 메모리 절감은 단순 도메인 규칙이 차지하는 부분에 적용됩니다.

참고 자료

오류 제보