ESP32-C3 ทำ DNS Ad Blocker บล็อกกว่า 500,000 โดเมนโดยไม่ใช้ PSRAM
ESP32-C3 ตัวเล็ก ๆ ที่มี Flash เพียง 4 MB จะเอา Blocklist หลักแสนโดเมนไปเก็บไว้ตรงไหน โดยเฉพาะเมื่อไม่มี PSRAM ให้ยัดชื่อเว็บไซต์ทั้งหมดลงไป?
โปรเจกต์ open-source esp32-c3-adblock ของ M-Abozaid เลือกแก้โจทย์ด้วยวิธีที่น่าสนใจกว่าเพิ่ม RAM: ไม่เก็บ Domain เป็น String ในหน่วยความจำ แต่แปลงแต่ละชื่อให้เหลือ 40-bit FNV-1a Hash ขนาดเพียง 5 Bytes แล้วเก็บ Hash ที่เรียงลำดับไว้ใน Flash
ผลคือ ESP32-C3 SuperMini สามารถทำหน้าที่เป็น Pi-hole-style DNS Sinkhole พร้อม Web Dashboard, Blocklist Update และ OTA ได้ โดย Configuration ที่เน้นความจุสามารถขยายไปถึงประมาณ 537,000 Domains ตามข้อมูลของผู้พัฒนา
แต่คำว่า “รองรับกว่า 500,000 Domains” มี Trade-off ที่ต้องรู้ก่อน: Maximum-capacity Configuration นี้ต้องใช้ Single-app Partition และแลกกับการปิด Firmware OTA
- โปรเจกต์ใช้ ESP32-C3 ที่มี Flash 4 MB และไม่ต้องมี PSRAM
- Domain ถูกเก็บเป็น 40-bit FNV-1a Hash ขนาด 5 Bytes แทน String
- 140,000+ Domains ใช้ Flash ประมาณ 0.67–0.7 MB ตามข้อมูลของผู้พัฒนา
- ผู้พัฒนารายงาน RAM Usage ประมาณ 50 KB
- ผู้พัฒนารายงาน Lookup ประมาณ 10 ms ในบริบทที่รวม Wi-Fi Round-trip Time
- Dual-app Partition รองรับ Blocklist ประมาณ 250k พร้อม Firmware OTA
- Single-app Partition ขยายไปประมาณ 537k แต่ Firmware OTA ใช้ไม่ได้
- มี Web Dashboard, Captive Portal, Remote Blocklist Update และ OTA
- มี STL เคสสำหรับ ESP32-C3 SuperMini ใน Official Repository
ESP32-C3 AdBlock คืออะไร?
esp32-c3-adblock เป็น Open-source DNS Ad Blocker ที่พัฒนาให้ทำงานบน ESP32-C3 โดยไม่ต้องพึ่ง PSRAM
แนวคิดใกล้เคียงกับ DNS Sinkhole: Client ใน Network ส่ง DNS Query มายัง ESP32-C3 แล้วอุปกรณ์จะตรวจว่า Domain นั้นอยู่ใน Blocklist หรือไม่
ถ้าอยู่ใน Blocklist Firmware จะตอบกลับด้วย 0.0.0.0 เพื่อทำให้ Request นั้นไปต่อไม่ได้ตามแนวทางของโปรเจกต์
ถ้า Domain ไม่อยู่ใน Blocklist Query จะถูก Forward ไปยัง Upstream DNS Resolver แล้วส่งคำตอบกลับมายัง Client
DNS Sinkhole ต่างจาก Browser Ad Blocker อย่างไร?
โปรเจกต์นี้ทำงานในระดับ DNS ไม่ใช่ Extension ที่ติดตั้งอยู่ใน Browser
Device ที่ต้องการใช้ระบบนี้ ต้องส่ง DNS Request มายัง ESP32-C3 หรือวาง ESP32-C3 เป็น Resolver ตาม Network Configuration ที่ผู้ใช้กำหนด
README ระบุว่าสามารถชี้ DNS ของอุปกรณ์ไปยัง IP ของ C3 หรือใช้เป็น Secondary Resolver อยู่ด้านหลัง Main DNS ได้
เมื่อ Domain ตรงกับ Blocklist ระบบจึงตัดสินใจตั้งแต่ขั้นตอน DNS Resolution ก่อนที่จะเชื่อมต่อไปยังปลายทาง
ไม่มี PSRAM แต่เก็บ Blocklist ใหญ่ได้ เพราะไม่เก็บชื่อ Domain แบบเดิม
ถ้าเก็บ Domain เป็น String ชื่อ Domain แต่ละรายการจะมีความยาวไม่เท่ากัน และการเก็บรายการหลักแสนรายการใน RAM สามารถกิน Memory ได้มาก
Project นี้เลือกอีกวิธี: นำ Domain ไปคำนวณ FNV-1a Hash แล้วตัดให้เหลือ 40 Bits
40 Bits เท่ากับ 5 Bytes ต่อรายการ ทำให้ขนาดข้อมูลของแต่ละ Entry คงที่ และสามารถเรียง Hash ทั้งหมดไว้ใน Flash เพื่อค้นหาภายหลังได้
| แนวทาง | ข้อมูลจากผู้พัฒนา |
|---|---|
| เก็บ Domain String ใน RAM | ผู้พัฒนายกตัวอย่างว่า 141k Domains อาจใช้ RAM ราว 2.5 MB ใน String-based Approach |
| 40-bit Hash ใน Flash | 141k Domains ใช้ Flash ประมาณ 0.67–0.7 MB และ RAM โดยรวมประมาณ 50 KB ตามรายงานของผู้พัฒนา |
| Hash Size | 5 Bytes ต่อ Domain Hash |
จุดสำคัญคือ Blocklist ไม่จำเป็นต้องถูกโหลดเป็น Domain String ทั้งก้อนเข้ามาอยู่ใน RAM จึงลดข้อจำกัดเรื่องหน่วยความจำลงอย่างมาก
ทำไมต้อง 40-bit? ทำไมไม่ใช้ 32-bit หรือ 64-bit ไปเลย?
Official README อธิบายว่าผู้พัฒนาเลือก 40 Bits เพราะมองว่าเป็นจุดสมดุลระหว่าง Flash Usage และโอกาสเกิด Hash Collision
| Hash Width | ข้อแลกเปลี่ยนตาม Developer |
|---|---|
| 32-bit | ใช้ Flash น้อยลง แต่ผู้พัฒนาประเมินว่าที่ประมาณ 250k Domains อาจเกิดราว 7 Collisions |
| 40-bit | 5 Bytes ต่อ Entry ถูกเลือกเป็น Sweet Spot สำหรับ Flash Budget ของโปรเจกต์ |
| 64-bit | ใช้ 8 Bytes ต่อ Entry ซึ่งเพิ่มอีก 3 Bytes ต่อ Domain เพื่อแก้ปัญหา Collision ที่ผู้พัฒนาเห็นว่าไม่จำเป็นใน Scale นี้ |
ผู้พัฒนาประเมินว่า Blocklist ราว 141k Domains มี Collision ใกล้ศูนย์ ขณะที่รายการประมาณ 537k Domains อาจมีประมาณหนึ่ง Collision
เมื่อ DNS Query เข้ามา ESP32-C3 ทำอะไรบ้าง?
↓ Extract Domain
↓ FNV-1a 40-bit Hash + Parent Suffix
↓ Search Blocklist ใน Flash
↓ Match → ตอบ 0.0.0.0
ไม่ Match → Forward ไป Upstream DNS
Firmware ไม่ตรวจเฉพาะ Domain เต็มเพียงรายการเดียว แต่ยังคำนวณ Parent Suffix ตาม Logic ที่ Source Code ระบุ
นั่นหมายความว่า Block Rule ระดับ Parent Domain สามารถมีผลกับ Subdomain ตามวิธีการ Matching ของโปรเจกต์
Official README รายงาน Lookup ประมาณ 10 ms ในบริบทที่รวม Wi-Fi Round-trip Time และอธิบายแนวทางเดิมว่าใช้ประมาณ 18 Flash Reads สำหรับการค้นหา
141k, 250k และ 537k Domains ต่างกันอย่างไร?
ตัวเลขทั้งสามชุดไม่ได้หมายถึง Configuration เดียวกัน และนี่เป็นจุดที่สำคัญที่สุดก่อนเอาคำว่า “รองรับกว่า 500,000 Domains” ไปใช้งาน
| ระดับ Blocklist | จุดเด่น | Trade-off |
|---|---|---|
| ประมาณ 141k | ใช้พื้นที่ราว 0.67–0.7 MB และ Developer ประเมิน Collision ใกล้ศูนย์ | เป็นตัวอย่างหลักสำหรับอธิบาย Memory Efficiency |
| ประมาณ 250k | ใช้กับ Dual-app Partition บน Flash 4 MB | ยังเก็บ Firmware สอง App Slots เพื่อรองรับ Firmware OTA |
| ประมาณ 537k | ใช้พื้นที่กับ Blocklist ได้มากที่สุดใน Configuration ที่กล่าวถึง | ต้องใช้ Single-app Partition และไม่มี Firmware OTA |
Current Source Code ไม่ได้ค้นหา Flash แบบตรง ๆ อย่างเดียว
เมื่อเปิด Source Code ปัจจุบัน จะเห็นว่าผู้พัฒนาเพิ่มโครงสร้างช่วยลดงานค้นหา มากกว่าคำอธิบาย Binary Search แบบพื้นฐานในบทความ
ใน `main.cpp` มีองค์ประกอบ เช่น:
- First-level Flash Index
- Direct-mapped Cache
- Range Buffer
- Custom Domain List แยกจาก Flash Blocklist
แนวคิดคือใช้ Index ช่วยจำกัดช่วงของ Hash ก่อนอ่านข้อมูลช่วงที่เกี่ยวข้องจาก Flash และ Cache ผลบางส่วนเพื่อลดการค้นซ้ำ
แต่เนื่องจาก Source ไม่ได้ให้ Benchmark ใหม่ ที่ระบุ Lookup Time ของ Optimization ปัจจุบัน บทความนี้จึงไม่สร้างตัวเลข Performance เพิ่มเอง
Hardware ที่ใช้
Target หลักของโปรเจกต์คือ ESP32-C3 และ Board ที่ผู้พัฒนาระบุว่าทดสอบคือ ESP32-C3 SuperMini
| รายการ | ข้อมูลจาก Source |
|---|---|
| MCU / Board Target | ESP32-C3, ทดสอบกับ ESP32-C3 SuperMini |
| CPU | Single-core 32-bit RISC-V สูงสุด 160 MHz |
| SRAM | 400 KB |
| Flash | ขั้นต่ำ 4 MB สำหรับ Configuration ของโปรเจกต์นี้ |
| PSRAM | ไม่จำเป็น |
| Wi-Fi | 2.4 GHz Wi-Fi |
| Power | 5V ผ่าน USB ตามข้อมูลของโปรเจกต์ |
README ยังระบุว่า Classic ESP32 DevKit / WROOM มี Build Target ที่ Community ช่วยเพิ่มเข้ามา และผ่านระดับ Compile Test แต่ C3 ยังคงเป็น Target หลักที่ผู้พัฒนาทดสอบ
เสียบกับ Router แล้วกลายเป็น DNS Sinkhole ได้อย่างไร?
USB ของ Router ในภาพทำหน้าที่เป็นแหล่งจ่ายไฟ ไม่ได้หมายความว่า Router ทุกยี่ห้อจะตั้ง DNS ให้ ESP32-C3 ให้อัตโนมัติเพียงเพราะเสียบ USB
ตาม README ผู้ใช้ต้องชี้ DNS ของ Client มายัง IP Address ของ C3 หรือจัด Network Configuration ให้ C3 อยู่ในเส้นทางการ Resolve DNS ตามที่ต้องการ
ตั้ง Wi-Fi ผ่าน Captive Portal ได้ ไม่ต้อง Hardcode Credential เสมอไป
ถ้า C3 เชื่อม Wi-Fi ไม่ได้ หรือผู้ใช้ไม่ได้ใส่ Credential ไว้ใน Firmware ระบบจะเปิด Access Point สำหรับ Setup
SSID มีรูปแบบ: C3-AdBlock-XXXX
ผู้ใช้สามารถเชื่อมจากโทรศัพท์ เลือก Wi-Fi Network แล้วใส่ Password ผ่าน Captive Portal
เมื่อต้องการย้ายไป Network ใหม่ README ระบุว่าสามารถใช้ปุ่ม Forget WiFi ใน Dashboard หรือกด BOOT ขณะเปิดเครื่อง เพื่อเรียก Setup Portal กลับมา
Web Dashboard ที่ c3adblock.local ดูอะไรได้บ้าง?
Dashboard เข้าผ่าน: http://c3adblock.local
Feature ที่ Source ระบุ ได้แก่:
- ดูจำนวน DNS Request ที่ Block / Allow
- ดูสถิติแยกตาม Client
- Ban Client
- Add Custom Blocked Domain
- Upload Blocklist
- ตั้ง Remote Blocklist Update
- Firmware OTA
- Forget Wi-Fi
- ดู System Information
Custom Blocked Domain ยังถูกเก็บแยกจาก Main Flash Blocklist และ Source Code ตรวจรายการ Custom ก่อน จึงสามารถเพิ่ม Domain เพิ่มเติมผ่าน Runtime ได้
Blocklist และ Firmware Update ผ่าน Wi-Fi ได้
หลัง Flash ครั้งแรก Project รองรับการ Update ผ่าน Network ทั้งฝั่ง Blocklist และ Firmware ภายใต้ Configuration ที่รองรับ OTA
Blocklist Update
ผู้ใช้สามารถ Upload `blocklist.bin` ผ่าน Dashboard หรือกำหนด URL สำหรับ Remote Auto-update
Official README ระบุว่า Default List ถูก Build ใหม่ทุกวันจันทร์ผ่าน GitHub Actions และเผยแพร่ผ่าน Stable Release URL สำหรับ Device ที่ต้องการดึง Update อัตโนมัติ
Firmware OTA
Dual-app Partition มี App Slots สองชุด เพื่อรองรับการ Update Firmware โดยไม่ต้องเสียบ USB ทุกครั้ง
แต่พื้นที่ที่ใช้กับ App Slot ชุดที่สอง ก็คือพื้นที่ที่หายไปจาก Blocklist จึงเกิด Trade-off ประมาณ 250k vs 537k Domains
Security: มี Auth แล้ว แต่ไม่ได้แปลว่าการเชื่อมต่อถูกเข้ารหัส
Official GitHub ปัจจุบันให้รายละเอียดเรื่อง Security มากกว่าการระบุว่า Dashboard มี Password เพียงอย่างเดียว
State-changing Endpoint ใช้ HTTP Basic Auth
Endpoint ที่สามารถเปลี่ยน State เช่นเพิ่ม Domain, Ban Client, Upload Blocklist หรือทำ Firmware OTA ต้องใช้ Username และ Password
Network OTA ยังมี OTA Password แยกอีกส่วนหนึ่ง
มีการลด Stored XSS
Custom Domain ถูก HTML Escape ก่อนแสดงบน Dashboard เพื่อป้องกัน Domain String ที่มี Markup ถูก Render เป็น Script หรือ HTML
มี CSRF Hardening เพิ่ม
Mutating Endpoint ต้องมี Custom Request Header ที่ Dashboard ของโปรเจกต์ส่งเอง เพื่อป้องกันหน้าเว็บภายนอก เรียก Action บางประเภทผ่าน Browser ได้ง่าย ๆ
แต่ Dashboard ยังใช้ HTTP
อีกเรื่องที่ Developer เตือนคือ ห้ามปล่อย Password ค่า Placeholder จากไฟล์ Example ไว้ใช้งานจริง เพราะค่าเหล่านั้นอยู่ใน Public Repository
หากนำไปทดลอง ควรทำบน Network ที่ผู้ใช้เป็นเจ้าของหรือได้รับอนุญาต และไม่ควรถือว่า Device นี้เป็น Security Appliance ที่มี TLS หรือ Enterprise-grade Authentication หาก Source ไม่ได้ระบุเช่นนั้น
มี STL เคสให้พิมพ์ 3D จริงใน Official Repository
Project มีไฟล์: hardware/esp32-c3-supermini-enclosure.stl สำหรับ ESP32-C3 SuperMini
รอบนี้สามารถพูดถึง Print Settings ได้ เพราะ README ระบุค่ามาโดยตรง
| รายการ | ค่าที่ Source ระบุ |
|---|---|
| Layer Height | 0.2 mm |
| Infill | ประมาณ 15% |
| Support | ไม่จำเป็นตาม Notes ของผู้พัฒนา |
| Antenna | ต้องเว้นบริเวณปลายเสา PCB Antenna และหลีกเลี่ยงพลาสติกหนาหรือโลหะใกล้เสา |
| Ventilation | ผู้พัฒนาแนะนำไม่ให้ปิดช่องระบายอากาศ |
README ยังระบุว่า Board ขณะ Idle อยู่ประมาณ 45–55 °C จึงไม่ควรออกแบบ Enclosure ที่ปิด Ventilation โดยไม่จำเป็น
หากมีไฟล์ STL แล้วแต่ไม่มีเครื่องพิมพ์ สามารถส่งไฟล์ให้ทีม GlobalByte ช่วยประเมินบริการพิมพ์ 3D ได้
สามารถเปิดไฟล์ต้นฉบับได้ที่ STL Enclosure บน Official GitHub
Code และ Build Flow จาก Official GitHub
Repository มี Source Code C++, PlatformIO Build Instructions และ Script สำหรับสร้าง Blocklist
ด้านล่างเป็นเพียง Excerpt สำหรับอธิบายแนวคิด ควรเปิด Repository ต้นฉบับควบคู่กันก่อน Build จริง
static uint64_t fnv40(const char* s, size_t n) {
uint64_t h = 0xcbf29ce484222325ULL;
for (size_t i = 0; i < n; i++) {
h ^= (uint8_t)s[i];
h *= 0x100000001b3ULL;
}
return h & HASH_MASK;
}
Function นี้คำนวณ FNV-1a แล้ว Mask ผลลัพธ์ให้เหลือขนาดตาม HASH_BYTES ซึ่ง Current Source กำหนดไว้ 5 Bytes
cp src/secrets.example.h src/secrets.h
python3 tools/build_blocklist.py data/blocklist.bin
pio run -t upload
pio run -t uploadfs
pio device monitor
ก่อน Build จริงต้องแก้ค่า Credential ใน `src/secrets.h` โดยเฉพาะ Web Password และ OTA Password ไม่ควรปล่อยค่า Placeholder ตามไฟล์ Example
ข้อจำกัดที่ควรรู้ก่อนเอาไปใช้จริง
1. 537k Domains ไม่ได้มาพร้อม Firmware OTA
Maximum Blocklist Configuration ต้องใช้ Single-app Partition จึงไม่มีพื้นที่ App Slot ชุดที่สองสำหรับ Firmware OTA
2. Dashboard ไม่ได้ใช้ HTTPS
Basic Auth ป้องกันการเรียก Endpoint โดยไม่มี Credential ในกรณีทั่วไปบน LAN แต่ไม่ได้ Encrypt Traffic
3. Captive Portal เป็น Open AP ระหว่าง Setup
ผู้พัฒนาออกแบบให้ Join ได้ง่าย แต่หมายความว่าช่วง Provisioning ควรทำในพื้นที่ Network ที่ควบคุมได้
4. Source ไม่รับรอง Router ทุกยี่ห้อ
การเสียบ USB กับ Router ในตัวอย่าง เป็นการใช้เป็นแหล่งจ่ายไฟ ไม่ใช่หลักฐานว่า Router ทุก Model จะตั้ง DNS หรือรองรับ Workflow นี้อัตโนมัติ
5. DNS Client ต้องใช้ Resolver นี้
README ระบุให้ชี้ DNS ของ Device ไปยัง C3 หรือจัดให้ C3 อยู่ใน DNS Path ดังนั้นประสิทธิผลของระบบขึ้นกับ Network Configuration ที่ใช้จริงด้วย
6. Source ไม่ได้ระบุ Ad-block Percentage
ไม่มีข้อมูลจาก Source ที่ให้ตัวเลขว่า Block โฆษณาได้กี่เปอร์เซ็นต์ จึงไม่ควรเขียนว่าแทนระบบ Ad Blocking ทุกแบบได้ 100%
Maker เรียนรู้อะไรจากโปรเจกต์นี้ได้?
สิ่งที่น่าเรียนรู้ที่สุดอาจไม่ใช่เรื่อง Ad Blocking แต่คือวิธีคิดเรื่อง Memory
แทนที่จะถามว่า “ต้องเพิ่ม RAM เท่าไรถึงจะเก็บข้อมูลทั้งหมดได้?” Project นี้กลับถามว่า “จำเป็นต้องเก็บข้อมูลในรูปแบบเดิมหรือไม่?”
- ลด String ให้เป็น Fixed-size Hash
- ย้าย Dataset ขนาดใหญ่ไป Flash
- เลือก Hash Width จาก Memory Budget และ Collision Risk
- ใช้ Sorted Data เพื่อช่วยค้นหา
- สร้าง First-level Index และ Cache เพิ่มใน Current Source
- แบ่ง Partition ตาม Trade-off ระหว่าง Data Capacity กับ OTA
- เพิ่ม Web Dashboard ให้ Embedded Device ดูแลตัวเองได้
- คิดเรื่อง Security ของ Local Web Interface ตั้งแต่ต้น
แนวคิดเดียวกันยังประยุกต์ได้กับ Embedded Project ที่ต้องเก็บ Lookup Table หรือ Dataset จำนวนมาก โดย Hardware มี RAM จำกัด
ผู้พัฒนายังยกตัวอย่างเชิงแนวคิดว่า Chip ที่มี Flash มากขึ้นอย่าง ESP32-S3 สามารถใช้แนวทาง Hash-in-Flash แบบเดียวกัน เพื่อขยายจำนวน Entry ได้อีก
ถ้ากำลังทดลอง ESP32-C3, Networking หรือ Embedded DNS Project สามารถสอบถามทีม GlobalByte เรื่อง Development Board และ Maker Accessories ที่เหมาะกับ Requirement ได้
โปรเจกต์นี้มีทั้ง Network, Security และ Partition Trade-off แนะนำอ่านต้นฉบับควบคู่กัน
โดยเฉพาะก่อน Flash Firmware, เปลี่ยน Partition, ตั้ง Password หรือเปิด OTA ควรตรวจ README และ Source Code ล่าสุดโดยตรง
FAQ — คำถามเกี่ยวกับ ESP32-C3 DNS Ad Blocker
1. โปรเจกต์นี้ต้องใช้ PSRAM หรือไม่?
ไม่ต้องใช้ PSRAM จุดเด่นหลักของโปรเจกต์คือเก็บ Blocklist เป็น 40-bit Hash ใน Flash แทนการเก็บ Domain String ใน PSRAM
2. ใช้ ESP32-C3 รุ่นไหน?
Target หลักคือ ESP32-C3 และผู้พัฒนาระบุว่าทดสอบกับ ESP32-C3 SuperMini ที่มี Flash 4 MB
3. ESP32 รุ่นเก่าใช้ได้ไหม?
Official README ระบุว่ามี Build Target สำหรับ Classic ESP32 DevKit / WROOM จาก Community และผ่าน Compile Test แต่ C3 เป็น Target หลักที่ผู้พัฒนาทดสอบ
4. 40-bit Hash มีขนาดกี่ Bytes?
40 Bits เท่ากับ 5 Bytes ต่อ Hash Entry
5. Blocklist 140,000 Domains ใช้พื้นที่เท่าไร?
ผู้พัฒนารายงานประมาณ 0.67–0.7 MB ของ Flash
6. ใช้ RAM เท่าไร?
Official README รายงานประมาณ 50 KB สำหรับแนวทางที่อธิบายไว้
7. Lookup ใช้เวลานานไหม?
Developer รายงานประมาณ 10 ms โดยตัวเลขดังกล่าวรวม Wi-Fi Round-trip Time และไม่ควรตีความเป็น Benchmark คงที่ของทุก Network
8. รองรับ 537,000 Domains จริงไหม?
Source ระบุ Configuration สูงสุดประมาณ 537k Domains แต่ต้องใช้ Single-app Partition และแลกกับการไม่มี Firmware OTA
9. ถ้าอยากใช้ Firmware OTA รองรับกี่ Domains?
Official README ระบุประมาณ 250k Domains ใน Dual-app Partition บน Flash 4 MB
10. ถ้า Domain ถูก Block จะเกิดอะไรขึ้น?
Firmware ตอบ DNS ด้วย 0.0.0.0 ตาม DNS Sinkhole Logic ของโปรเจกต์
11. Dashboard เข้า URL อะไร?
Source ระบุ URL http://c3adblock.local สำหรับ Web Dashboard บน Network ที่ Resolve mDNS ได้
12. Dashboard ใช้ HTTPS หรือไม่?
ไม่ใช้ HTTPS ตาม Documentation ปัจจุบัน Web Interface ทำงานผ่าน HTTP Port 80
13. HTTP Basic Auth ปลอดภัยเท่ากับ HTTPS ไหม?
ไม่เท่ากัน Developer ระบุเองว่า Basic Auth เป็น LAN Trust-boundary Control และ Credential ไม่ได้ถูก Encrypt ระหว่างทาง
14. ตั้ง Wi-Fi โดยไม่แก้ Source Code ได้ไหม?
ได้ Firmware มี Captive Portal สำหรับ Provision Wi-Fi เมื่อไม่สามารถ Connect หรือไม่มี Credential ที่บันทึกไว้
15. Blocklist Update อัตโนมัติได้ไหม?
ได้ Source รองรับ Remote Blocklist URL และ Scheduled Update รวมถึง Default Blocklist ที่ Project สร้างใหม่ผ่าน GitHub Actions
16. มีไฟล์เคส 3D Print หรือไม่?
มี Official Repository มี STL สำหรับ ESP32-C3 SuperMini Enclosure
17. ใช้ Print Settings อะไร?
README ระบุ Layer Height 0.2 mm, Infill ประมาณ 15% และไม่ต้องใช้ Support พร้อมเตือนให้เว้นพื้นที่บริเวณ PCB Antenna
18. บล็อกโฆษณาได้ 100% หรือไม่?
Source ไม่ได้ระบุ Success Rate หรือรับรองว่า Block โฆษณาได้ทุกประเภท จึงไม่สามารถสรุปเป็น 100% ได้จากข้อมูลที่มี
สรุป: จุดเด่นไม่ใช่แค่บล็อก 500,000 Domains แต่คือการใช้ Memory ให้ฉลาดขึ้น
esp32-c3-adblock เป็นตัวอย่างที่ดีว่า Hardware ราคาประหยัดและ RAM จำกัด ไม่จำเป็นต้องแก้ด้วยการเพิ่ม Memory เสมอไป
การเปลี่ยน Domain String ให้กลายเป็น Fixed-size 40-bit Hash แล้วเก็บลง Flash ทำให้ ESP32-C3 ที่ไม่มี PSRAM สามารถทำงานกับ Blocklist หลักแสนรายการได้
แต่ทุกอย่างมี Trade-off: ต้องเลือกระหว่าง Firmware OTA กับ Blocklist ความจุสูงสุด, ต้องยอมรับความเสี่ยงของ Hash Collision ในระดับที่ Developer ประเมิน และต้องเข้าใจว่า Web Dashboard ใช้ HTTP ไม่ใช่ HTTPS
สำหรับ Maker นี่จึงไม่ใช่แค่โปรเจกต์ Ad Blocker แต่เป็น Case Study เรื่อง Data Structure, Flash Storage, Hashing, DNS, OTA, Partitioning, Embedded Web UI และ Security ที่รวมอยู่ใน ESP32-C3 ตัวเดียว
References / แหล่งข้อมูลต้นฉบับ
- Open-source ESP32-C3 DNS ad blocker supports over 500,000 domains without PSRAM — CNX Software
- esp32-c3-adblock — Official GitHub Repository
- ESP32-C3 AdBlock Main Firmware Source
- Dual-OTA Partition Layout
- ESP32-C3 SuperMini 3D Printable Enclosure STL
- ESP32_AdBlocker — Project cited as inspiration by the developer
อยากลอง ESP32-C3, Networking หรือ Embedded Project?
ถ้ากำลังทดลอง ESP32-C3, Development Board, DNS, IoT หรือ Embedded Networking Project สามารถสอบถามทีม GlobalByte เรื่องบอร์ดและอุปกรณ์ที่เหมาะกับ Requirement ของงานได้
และถ้าต้องการทำ Enclosure Project นี้มีไฟล์ STL ต้นฉบับให้แล้ว สามารถส่งไฟล์ให้ทีม GlobalByte ช่วยประเมินบริการพิมพ์ 3D ได้เช่นกัน
ตัวเลข Blocklist Capacity เช่นประมาณ 141k, 250k และ 537k Domains ขึ้นกับ Partition Layout และ Configuration ไม่ควรตีความว่า ESP32-C3 ทุกชุดสามารถใช้ Maximum Blocklist พร้อม Firmware OTA ได้พร้อมกัน
ค่า RAM Usage ประมาณ 50 KB, Lookup ประมาณ 10 ms, จำนวน Flash Reads และ Hash Collision เป็นข้อมูลที่ผู้พัฒนาเผยแพร่ใน Project Documentation ไม่ใช่ Benchmark ที่ GlobalByte ทดสอบซ้ำเอง
Current Source Code มี Index และ Cache Optimization เพิ่มจากคำอธิบาย Binary Search แบบพื้นฐาน จึงไม่ควรใช้ตัวเลข Flash Reads จาก Documentation เป็นค่าคงที่สำหรับทุก Query และทุก Version
Dashboard ใช้ HTTP Basic Auth แต่ไม่ใช่ HTTPS และ Credential ไม่ได้ถูก Encrypt ระหว่างทาง Captive Portal Access Point ในช่วง Setup ยังเป็น Open Network ตามการออกแบบของ Project
ควรทดลองบน Network และ Hardware ที่ผู้ใช้เป็นเจ้าของหรือได้รับอนุญาตเท่านั้น พร้อมตั้ง Web Password และ OTA Password จริง แทนค่า Placeholder ก่อนนำ Device ไปใช้งานบน Network ที่มีอุปกรณ์อื่นร่วมอยู่