1 คะแนน โดย GN⁺ 2 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • สรุปวิธีบล็อกบอตส่วนใหญ่ที่มีการใช้งานหรือการตั้งค่าไม่ดี โดยผสมผสาน โปรโตคอล HTTP/ช่วง IP/สัญญาณจากไคลเอนต์/คุณลักษณะ TCP/ลายนิ้วมือ TLS/การบีบอัดเนื้อหา โดยไม่ใช้ CDN
  • ทุกวิธีต้องปรับใช้อย่างเลือกสรร และหากไม่วิเคราะห์ บันทึกการเข้าถึงย้อนหลัง 1–3 ปี ก่อน อาจบล็อกผู้ใช้ VPN/เสิร์ชเอนจิน/CDN/โรงเรียน/ห้องสมุด/ผู้ใช้บางภาษาไปพร้อมกันได้
  • การบล็อกไคลเอนต์ HTTP/1.1 และช่วง AS/CIDR ของดาต้าเซ็นเตอร์สามารถกำจัดบอตได้จำนวนมาก แต่ เสิร์ชเอนจินรวมถึง GoogleBot และผู้ใช้ดาต้าเซ็นเตอร์ปกติก็อาจถูกกันออกไปด้วย
  • การตรวจสอบเฮดเดอร์ใน Nginx และตัวกรองขนาด TCP window/MSS/TTL ของ nftables ช่วยลด crawler และ scanner แบบง่ายได้ แต่มีโอกาสเกิด false positive ในสภาพแวดล้อมปกติอย่าง LTE/VPN/Windows
  • ระยะยาวเสนอ การตรวจจับลายนิ้วมือ JA4 TLS และการตอบกลับเฉพาะ Brotli เป็นทางเลือก แต่ไม่รับประกันว่าจะบล็อกได้ทั้งหมด และเตือนว่าไม่ควรใช้กับบริการที่สร้างรายได้

ขอบเขตการบล็อกและเงื่อนไขก่อนนำไปใช้

  • ต้องตัดสินใจก่อนว่าเป้าหมายการบล็อกคือบอตบางส่วน/บอตส่วนใหญ่/บอตทั้งหมด
    • วิธีที่กล่าวถึงที่นี่ไม่ได้มุ่งบล็อกเครื่องมืออัตโนมัติที่ซับซ้อนทั้งหมด แต่เน้นการบล็อก บอตส่วนใหญ่ที่มีการใช้งานหรือการตั้งค่าไม่ดี ด้วยวิธีที่ค่อนข้างเรียบง่าย
    • ระบุความเสี่ยงในการบล็อกผู้ใช้ปกติและเสิร์ชเอนจินไว้สำหรับแต่ละวิธีด้วย
  • หลังจากถูกแชร์บน Hacker News เมื่อ 26 กรกฎาคม 2026 ผู้เขียนตัดสินใจย้ายฟังก์ชันบล็อกส่วนใหญ่จากบล็อกไปยังไซต์เดโมแยกต่างหาก และเปลี่ยนให้เป็นปริศนาที่ผู้อ่านอ่านวิธีแล้วลองเข้าถึงเอง
  • การตั้งค่าทั้งหมดสามารถแก้ไขหรือข้ามได้ตามความเหมาะสม และก่อนใช้งานจริงต้องสำรวจและทดสอบให้เพียงพอ
  • ผู้ใช้ปกติ/ระบบภายในองค์กร/บริการภายนอกที่พึ่งพาอยู่อาจถูกบล็อกได้ ความรับผิดชอบในการนำไปใช้จึงเป็นของผู้ดูแลระบบทั้งหมด
  • ห้ามใช้ในสภาพแวดล้อมการให้บริการที่สร้างรายได้

วิธีที่ 1: แยกตามโปรโตคอล HTTP

  • ความเสี่ยงในการบล็อกผู้ใช้ปกติต่ำ และความเสี่ยงในการบล็อกเสิร์ชเอนจินบางส่วนอยู่ระดับกลาง
  • ใช้ความแตกต่างที่ว่าเบราว์เซอร์ทั่วไปใช้ HTTP/2.0 แต่บอตจำนวนมากใช้ HTTP/1.1
    • ถือว่า GoogleBot ใช้ HTTP/1.1 และจะถูกบล็อกด้วยวิธีนี้
    • crawler ของ Bing และ Facebook ใช้ HTTP/2.0
    • บริการที่ดึงชื่อเรื่องของลิงก์หรือพรีวิวสั้น ๆ ผ่าน HTTP/1.1 ก็อาจถูกบล็อกได้
    • Opera Mini ก็ถูกกันออกจากกลุ่มเป้าหมายด้วย
  • ใน Nginx ตั้งค่าให้เมื่อ $server_protocol ไม่ใช่ HTTP/2.0 ให้ redirect ไปหน้าอื่น หรือคืนค่า 200, 403, 444
if ($server_protocol != HTTP/2.0) {  
    return 403 'Upgrade your client';  
}  
  • หากคืนค่า 444 จะตัดการเชื่อมต่อได้โดยไม่ส่ง response แยกต่างหาก
  • แต่ละองค์กรต้องตัดสินใจเองว่าประโยชน์ที่ได้คุ้มกว่าความเสียหายจากการบล็อกทราฟฟิกจาก Google Search หรือไม่

วิธีที่ 2: บล็อกช่วง IP ของดาต้าเซ็นเตอร์

  • ความเสี่ยงในการบล็อกผู้ใช้บ้าน/LTE ปกติต่ำ แต่ผู้ใช้ VPN อยู่ระดับกลาง และเสิร์ชเอนจินที่ทำงานในดาต้าเซ็นเตอร์มีความเสี่ยงถูกบล็อกสูง
  • ค้นหา request ที่น่าสงสัยจากบันทึกการเข้าถึงย้อนหลัง 1–2 ปี โดยผสมสัญญาณต่อไปนี้
    • โปรโตคอล HTTP
    • User-Agent
    • Accept-Language
    • Sec-Fetch-Mode
    • Accept
  • ตรวจสอบ IP ที่น่าสงสัยใน BGP Tools หรือ Hurricane Electric BGP Toolkit เพื่อดู AS ที่สังกัดและ Prefix ที่ประกาศอยู่
  • รายการ network blackhole ที่ให้มาอาจรวมช่วงของ CDN และเสิร์ชเอนจินด้วย จึงต้องเลือกใช้อย่างระมัดระวัง
  • ก่อนใช้รายการแยกต่างหาก มีการใช้คอนฟิกที่ blackhole ช่วง 3/8, 10/8, 11/8, 25/8, 26/8, 38/8, 41/8, 60/8, 61/8, 200/8, 224/3 ไว้แล้ว
  • หลังคัดลอกหน้า Prefix ของ AS ให้ใช้ shell function ดึงเฉพาะ CIDR แล้ว sort/ลบรายการซ้ำ/รวมช่วง
    • ใช้ sum_cidr.pl และต้องมีโมดูล Perl Net::CIDR::Lite
    • ตรวจทานผลลัพธ์ที่สร้างขึ้นแล้วจึงย้ายไปยังไฟล์ /usr/local/etc/*.netset
  • เมื่อเริ่มเซิร์ฟเวอร์ ให้เพิ่มแต่ละ CIDR เป็น blackhole route
for CflIP in $(grep -E ^[1-9] /usr/local/etc/_cloudflare.netset); do  
    /sbin/ip route add blackhole "${CflIP}" 2>/dev/null  
done  
  • ในตัวอย่าง บล็อกช่วงทั้งหมดของ Cloudflare เพื่อไม่รับ request ผ่าน Workers เป็นต้น
  • เลือกใช้วิธี routing เพราะ Linux blackhole routing ใช้ CPU น้อยกว่า กฎ ipset ในไฟร์วอลล์
  • สามารถบล็อกช่วงของผู้ให้บริการโฮสติ้งที่เซิร์ฟเวอร์ปัจจุบันอยู่ได้ด้วย
    • DNS/การตั้งค่า/บริการภายในต้องไม่ใช้ address space เดียวกัน
    • เส้นทาง gateway ที่เชื่อมต่อโดยตรงจะถูกใช้ก่อน blackhole route

วิธีที่ 3: บล็อกประเทศ/พร็อกซี/Tor/IP อันตราย

วิธีที่ 4: ตรวจสอบสัญญาณจาก HTTP client

  • ใช้สมมติฐานว่าแม้ User-Agent หรือ header จะปลอมได้ แต่บอตแบบง่ายที่เน้นความเร็ว častoมักไม่ปลอมให้ถูกต้อง
  • สำหรับ request จาก Curl, Wget ให้คืน plain text และสำหรับ request ที่มี Bot, GPT, LLM, Spider ให้คืน 410 Gone
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 ที่เคยพบด้วย regex ยาวเส้นเดียว เพื่อบล็อก crawler/scanner/เครื่องมือเก็บข้อมูล
    • รวม substring อย่าง Go-http, Java, libwww, okhttp, urllib, python, nmap, zgrab, semrush, shodan, rss, scrap, crawler, headless, github, facebook, google, bing เป็นต้น
  • ก่อนนำไปใช้ต้องรวบรวม User-Agent ย้อนหลัง 2–3 ปี เพื่อตรวจสอบว่าไคลเอนต์ปกติจริง ๆ ตรงกับ regex หรือไม่
sort access-user-agents.txt | uniq -c | sort  
  • หาก request ที่ตรงกันเป็น HTTP/1.1 ให้ถือว่ามีโอกาสสูงว่าเป็นบอต แต่ให้พิจารณายกเว้น GoogleBot
  • หากเป็น request HTTP/2.0 ให้ตรวจสอบเพิ่มเติมว่า IP สังกัดที่ใดด้วยเครื่องมือ BGP

Sec-Fetch-Mode

  • เพิ่ม Sec-Fetch-Mode ลงใน access log และบล็อกหากค่าไม่ใช่หนึ่งใน cors, no-cors, navigate
if ($http_sec_fetch_mode !~ (cors|no-cors|navigate)) {  
    return 410 '1000101';  
}  

การตรวจ Referer

  • เพื่อป้องกัน request ที่ฝังหรือสแกนเนื้อหาจากไซต์อื่น ให้บล็อกเมื่อ Referer มีสตริงบางอย่าง
    • ตรวจสตริงที่เกี่ยวกับหน้าแอดมิน/เสิร์ชเอนจิน/โซเชียลเน็ตเวิร์ก/คริปโตเคอร์เรนซี/เนื้อหาผู้ใหญ่/scanner/WordPress เป็นต้น
  • ยังบล็อกบอตบางประเภทที่อ้างว่า root page ของ Google https://www.google.com/ เป็น Referer แยกต่างหากด้วย
    • เป็น pattern ที่พบใน request ที่ปลอมตัวเป็น Android รุ่นเก่า

จำกัด HTTP method

  • อนุญาตเฉพาะ GET และ POST ที่จำเป็นต่อ request จากเบราว์เซอร์ปกติ และบล็อก method อื่น
if ($request_method !~ (^GET$|^POST)) {  
    return 410 '1000101';  
}  
  • ในแอปพลิเคชันจริงสามารถจำกัดเส้นทางที่ต้องใช้ POST ให้ละเอียดขึ้น หรือหากไม่ใช้ก็สามารถตัดออกทั้งหมดได้

ตรวจรูปแบบพร็อกซีและเบราว์เซอร์

  • หากมี header X-Forwarded-For ให้ถือว่าเป็น request ผ่านพร็อกซีและบล็อก
    • สภาพแวดล้อมพร็อกซีแชร์ที่ถูกต้องตามปกติ เช่น โรงเรียนหรือห้องสมุด ก็อาจถูกบล็อกได้
  • หาก User-Agent ไม่มีคำใดเลยใน Linux, BSD, Macintosh, Windows, Mozilla, WhatsApp ให้ถือว่า request นั้นดูไม่เหมือนเบราว์เซอร์
  • ยังใช้กฎที่บล็อกหาก Accept-Language ไม่มี en หรือ es
    • มีความเป็นไปได้สูงที่จะบล็อกเบราว์เซอร์บางตัวและผู้ใช้ปกติที่ไม่ได้ใช้ภาษาอังกฤษ/สเปน
  • ยังเสนอ rule ทางเลือกที่บล็อกการตั้งค่าภาษาที่มี br หรือ sy แยกต่างหาก

บล็อกการสแกน path อ่อนไหว

  • หากมีการ request ไฟล์หรือ path ต่อไปนี้ ให้ถือว่าเป็นการสแกนอัตโนมัติและบล็อก
    • .git
    • .yml
    • .db
    • .sql
    • .conf

วิธีที่ 5: บล็อก TCP scanner ด้วย nftables

  • ตรวจสอบคุณลักษณะของแพ็กเก็ต TCP SYN ใน chain PREROUTING ของตาราง raw ใน nftables
  • ระบุที่อยู่เซิร์ฟเวอร์ตัวอย่าง 172.238.221.88 เป็นปลายทาง เพื่อลด false positive ที่อาจเกิดจากสถานการณ์ packet loss
  • บล็อก SYN packet ที่เข้ามายังพอร์ต 80/443 และตรงตามเงื่อนไขต่อไปนี้
    • TCP window size ต่ำกว่า 12,288 ไบต์
    • MSS อยู่นอกช่วง 1,220–1,460
  • ใช้เกณฑ์ว่าไคลเอนต์จริงใช้ window size ที่ใหญ่กว่า และ MSS ที่อยู่นอกช่วงนี้มีโอกาสต่ำที่จะเป็นไคลเอนต์ปกติ
  • หากจำกัด MSS ให้เท่ากับ 1460 พอดี จะเข้มงวดขึ้น แต่ผู้ใช้ LTE และ VPN ส่วนใหญ่อาจถูกบล็อกได้

ข้อจำกัดแบบเลือกใช้ตาม TTL

  • หาก TTL ของ TCP SYN มากกว่า 128 จะบล็อกอุปกรณ์ LTE ส่วนใหญ่ได้
  • หาก TTL มากกว่า 64 ระบบ Windows ส่วนใหญ่ก็จะถูกบล็อกด้วย
  • อธิบายค่า TTL เริ่มต้นไว้ดังนี้
    • Linux/Mac/BSD: 64
    • Windows: 128
    • LTE: ค่ามากกว่านี้

ยกเว้น connection tracking

  • กำหนดพอร์ต 80/443 เป็น notrack เพื่อไม่ใส่เว็บทราฟฟิกลงใน conntrack table
  • ในกรณีนี้ต้องกำหนด กฎแบบ stateless สำหรับทิศทางรับส่งใน filter table เองด้วย
  • ในตัวอย่าง อนุญาตทราฟฟิกระหว่างพอร์ตต้นทางของไคลเอนต์ 1000-65535 กับพอร์ต 80/443 ของเซิร์ฟเวอร์

วิธีที่ 6: เนื้อหาผู้ใหญ่และ header สำหรับโรบอต

  • สำหรับการจำกัดการเข้าถึงเนื้อหาผู้ใหญ่ ใช้ header RTA: Restricted To Adults
  • มองว่าวิธียืนยันอายุอื่นนอกเหนือจาก RTA มีไว้เพื่อการติดตามผู้ใช้และสร้างรายได้
  • เพิ่ม header ต่อไปนี้ใน response ของ 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;  
  • บอตทั่วไปอาจละเลย header เหล่านี้ แต่มีผลต่อเสิร์ชเอนจินหรือบอตที่ออกแบบมาให้หลีกเลี่ยงเนื้อหาผู้ใหญ่ได้

วิธีที่ 7: ตรวจจับลายนิ้วมือ TLS

  • วิธีที่ 1–6 ข้างต้นล้วนเป็น heuristic แบบหยาบ และระยะยาว การวิเคราะห์ลายนิ้วมือ TLS อาจเป็นทางเลือกที่ดีกว่า
  • สามารถใช้ JA4 ได้ ภายใต้เงื่อนไขว่าบอตไม่ได้เปลี่ยนลายนิ้วมือ TLS ให้เหมือนเบราว์เซอร์ปกติ
  • แนะนำให้ตรวจวิธี deploy ใน Deploying JA4 ก่อน แล้วจึงนำ FoxIO JA4 มาใช้

วิธีที่ 8: ให้บริการเฉพาะเนื้อหาที่บีบอัดด้วย Brotli

  • บีบอัดเนื้อหาไซต์ล่วงหน้าด้วย Brotli และตั้งค่าเว็บเซิร์ฟเวอร์ให้คืนเฉพาะไฟล์ที่ถูกบีบอัดแล้ว
  • ใช้ข้อเท็จจริงว่าบอตจำนวนมากตีความ HTML ที่บีบอัดด้วย Brotli ไม่ได้
  • หลังนำไปใช้ พบว่าบอตหลายตัวไม่ตามลิงก์ในหน้าอีกต่อไป จึงยืนยันได้ว่าไม่ได้ parse HTML จริง
  • ใน Nginx ตั้งค่าให้ให้บริการไฟล์ Brotli แบบ static เสมอ
brotli_static always;  
  • บีบอัดไฟล์ HTML ล่วงหน้าดังนี้
cat ./i.html | brotli --best -fncv > ./i.html.br  

วิธีที่ 9: ชักนำให้ scanner ระบุตัวเอง

  • วิธีแยกต่างหากในการลดมือใหม่โจมตีและ scanner ที่ค้นหา path ช่องโหว่ซ้ำ ๆ กล่าวไว้ใน Help Attackers Self Report

1 ความคิดเห็น

 
GN⁺ 2 시간 전
ความคิดเห็นจาก Hacker News
  • ในฐานะคนที่ดูแลเว็บไซต์สาธารณะหลายแห่ง และก็ขูดข้อมูลจากเว็บอื่นมาใช้กับเครื่องมือของตัวเองด้วย ผมสงสัยว่าทำไมผู้คนถึงใส่ใจกับบอตกันมากขนาดนั้น
    แม้แต่ WordPress ที่มีแคชก็ยังรองรับได้ราว 1,000 คำขอต่อวินาที บน VPS ราคาถูกที่สุด และถ้าเป็นเว็บสแตติกที่ทำมาดี ก็น่าจะทำได้ถึง 10 เท่าของนั้น เลยสงสัยว่าเขาเสิร์ฟบล็อกด้วยอะไรอย่าง Lambda หรือเปล่า หรือเป็นความหมกมุ่น/การป้องกันช่องโหว่/นิสัยที่ติดมาจากยุคที่การครอว์ลส่งผลต่อบริการจริง ๆ

    • กรณีของผม ปัญหาอยู่ที่ อินสแตนซ์ Forgejo บล็อกเป็นไฟล์สแตติกที่จำนวนหน้าจำกัดเลยไม่เป็นไร แต่ Forgejo เป็นบริการไดนามิกที่บอตสามารถค้นพบหน้าได้แทบไม่จำกัด และบางหน้าถึงขั้นรัน Git อยู่เบื้องหลังตอนสร้างหน้า ทำให้เซิร์ฟเวอร์เล็ก ๆ โอเวอร์โหลดได้ง่าย
      รีโพซิทอรีเป็นโอเพนซอร์ส เลยตั้งใจเปิดสาธารณะไว้ ตอนนี้ป้องกันด้วยการตรวจคุกกี้แบบง่าย ๆ ทำให้มีบอตจำนวนน้อยเท่านั้นที่ผ่านได้ แต่ก็เป็นการแลกเปลี่ยนที่ต้องยอมเสียการปรากฏในเสิร์ชเอนจิน
    • เว็บส่วนตัวบน shared hosting ของผมเพิ่งถูกระงับเพราะ การครอว์ลของบอต AI อย่างต่อเนื่องจนใช้ CPU มากเกินไป ปัญหาไม่ใช่การครอว์ลในตัวมันเอง แต่คือมีบอตมากเกินไปและทำงานอย่างไม่มีประสิทธิภาพ
    • เป็นการทดลองที่ทำเล่น ๆ เพื่อหาคุณลักษณะร่วมบางอย่าง เช่น JavaScript ที่ผู้ควบคุมบอตหลบเลี่ยงหรืออ้อมผ่านได้ยาก บล็อกนี้เป็นคอนเทนต์สแตติกที่บีบอัดไว้ล่วงหน้าและวางบน RAM disk ดังนั้นน่าจะรองรับคำขอได้หลายแสนครั้งต่อวินาที
      จุดประสงค์คือแสดงวิธีนำไปใช้กับฟอรัม บอร์ดรูปภาพ เซิร์ฟเวอร์แชต ฯลฯ และตัวเลือกทั้งหมดปรับแต่งหรือปิดได้ ก่อนใช้งานจริงควรตรวจสอบบนเซิร์ฟเวอร์ทดสอบก่อน และจะหัวเราะเยาะแล้วข้ามไปก็ไม่เป็นไร
    • ที่บ้านผมไม่มีทางมี ลิงก์ 40Gbit กับเซิร์ฟเวอร์ที่รองรับมันได้ ต่อให้เป็น Google Cloud VPS ไม่กี่เครื่องที่รัน nmap กับการสแกนช่องโหว่เว็บสารพัดแบบจนกลายเป็นการโจมตีแบบปฏิเสธการให้บริการแบบกระจาย ประสิทธิภาพของเครื่องสเปกต่ำก็ลดลงได้ง่าย
      การที่ DMZ ถูกอุดตันจนต้องรอเพิ่มอีกสองสามวินาทีเพื่อเช็กเซิร์ฟเวอร์ IMAP ในเครื่องไม่ใช่เรื่องใหญ่ แต่ก็ไม่ได้แปลว่าผมจะชอบหรือมีเหตุผลให้ปล่อยต่อไปเรื่อย ๆ
    • ปัญหาใหญ่ที่สุดคือมันพรากเวลาที่ควรเอาไปทำสิ่งที่มีประโยชน์กว่าในการรับมือบอต
      สุดสัปดาห์ที่ผ่านมา ผมปิดเว็บอินเทอร์เฟซ viewvc(CVS·Subversion) และ hgweb(Mercurial) ที่เปิดมานาน 10–20 ปีแล้ว เพราะมีคำขอจาก IP พร็อกซีตามบ้านวันละ 2.7 ล้านครั้ง เฉลี่ย 30 ครั้งต่อวินาที ทำให้โปรแกรม uWSGI/CGI เก่า ๆ และเว็บอื่นบนเซิร์ฟเวอร์เดียวกันรับภาระหนัก แถมทราฟฟิกยังใกล้แตะโควตา VPS ที่เดือนละ 1TB
      URL ของ VCS แบบไดนามิกอาจมีชุดผสมได้เป็นล้าน ๆ แบบ จึงไม่แน่ใจว่าแคชจะช่วยได้แค่ไหน และไม่คุ้มจะเสียเวลาปรับจูนเซิร์ฟเวอร์เพิ่ม สุดท้ายเลยเป็นการตัดสินใจที่พาเราเข้าใกล้อินเทอร์เน็ตแบบรวมศูนย์ไปอีกก้าว
  • ถ้าบล็อกทุกอย่างยกเว้น user agent ที่ “ได้รับอนุมัติ” ก็เท่ากับช่วย การผูกขาดเบราว์เซอร์ ที่มีอยู่เดิม และเร่งให้ดิสโทเปียมาถึงเร็วขึ้น นี่ก็เป็นปัญหาที่ RMS เตือนมาหลายสิบปีแล้ว
    ถ้ามันเป็นปัญหา ก็ควรบล็อกตามปริมาณทราฟฟิกและความถี่ของคำขอ ผมเองก็เข้าเว็บไม่ได้เหมือนกัน แต่ไม่มีความคิดจะปรับพฤติกรรมตามนั้น และเหมือน DRM ฝ่ายตรงข้ามที่ตั้งใจจริงสุดท้ายก็จะผ่านเข้ามาได้อยู่ดี

    • ผมรับคำวิจารณ์นั้นได้ ผมเคยอยู่ร่วมกับ RMS อยู่ไม่กี่ครั้ง เขาเป็นคนที่น่าสนใจและฉลาดมาก และถ้าได้เจอกันเรื่องนี้ คงโดนบ่นไม่รู้จบแน่
      อย่างไรก็ตาม นอกเหนือจากข้ออ้างว่าใช้เบราว์เซอร์อะไรก็ได้แล้ว เบราว์เซอร์ที่เป็นโค้ดสร้างขึ้นเฉพาะหน้า หรือยังไม่ได้รับการตรวจสอบเพียงพอในการรับมือเว็บประสงค์ร้าย ต้องระวังเป็นพิเศษ แอปอ่านก็อาจเปราะบางต่อ เซิร์ฟเวอร์ประสงค์ร้าย ได้ หากไม่ได้ผ่านการตรวจทานโค้ดจากบุคคลที่สามอย่างกว้างขวางโดยผู้เชี่ยวชาญด้าน penetration testing
    • จะตัดสินจากพฤติกรรมก็ได้ go-away ตรวจว่ามีการโหลดรูปภาพและ CSS หรือไม่ รวมถึงตามการรีไดเรกต์แบบ meta refresh หรือเปล่า ส่วน Anubis ตรวจว่าสามารถ รัน JavaScript ได้เป็นเวลาหลายวินาทีหรือไม่
    • สตริง user agent เองโดยรวมแล้วค่อนข้างเป็นโทษ ถ้าเป็นเบราว์เซอร์ใหม่ ก็ควรคัดลอก user agent ของ Chrome ไปเลยดีกว่า
  • ผมชอบไอเดียที่ว่า ถ้าเพิ่ม โดเมนย่อย cpanel ปลอมที่ชี้ไปยัง 169.254.169.254 ผู้โจมตีมือใหม่ก็อาจไปสแกนพอร์ตผู้ให้บริการโฮสติงของตัวเอง จนถูกตรวจจับหรือถูกบล็อกได้

    • ตอนทดลองครั้งแรก ผมคิดว่าจะไม่มีอะไรเกิดขึ้น ภายในไม่กี่วัน มีคนคนหนึ่งจาก Amazon EC2 ในเยอรมนีพยายามทำ zone transfer กับบางส่วนของโดเมนผม ราวกับกำลังหาเรคคอร์ดที่ควรหลีกเลี่ยง จากนั้นก็ยกเว้นโดเมนของผมทั้งหมด และไม่นานการสแกนก็หยุดลง
      IP ต้นทางกระจายอยู่ทั่วโลก แต่เสียงรบกวนจากการสแกนจริง ๆ มาจาก คนเพียงคนเดียว เท่านั้น
    • ไม่เข้าใจว่าทำไม AWS ถึงต้องรัน fail2ban กับ Instance Metadata Service (IMDS) ไม่รู้ว่าไม่เชื่อมั่นในการใช้งานของตัวเอง หรืออยากให้ลูกค้ารายใหญ่ฟ้องร้องกันแน่
  • การบล็อกตาม IP ต้องระวัง ช่วง IP อาจถูกจัดสรรใหม่เป็นครั้งคราว ทำให้ไปบล็อกคนที่ไม่เกี่ยวข้องได้ และเคยเห็นหลายครั้งที่ช่วง IP ซึ่งเคยถูกบล็อกเพราะเป็นของภูมิภาคหรือดาต้าเซ็นเตอร์ ถูกย้ายไปอยู่กับ ISP สำหรับที่อยู่อาศัย
    การบล็อก HTTP/1.1 ก็มีความเสี่ยงสูงที่จะบล็อกผู้ใช้จริงที่ใช้เบราว์เซอร์เก่า นอกจากนี้ยังมีเบราว์เซอร์ที่ไม่ส่ง URL เต็มในการร้องขอข้ามต้นทาง ดังนั้นถ้ามีผู้เข้าจาก Google Search ค่า referrer อาจชี้ไปที่หน้า root ของ Google เท่านั้น หากด่วนสรุปว่านี่เป็นการโกหกของบอตแล้วบล็อก อาจทำให้ทราฟฟิกจาก Google Search หายไปด้วย

    • น่าเสียดายที่มีคนจำนวนมากที่เครือข่ายของตนถูกนำไปขายต่อเป็น VPN สำหรับที่อยู่อาศัย โดยไม่รู้ตัว
      แต่ในทางกลับกัน ผมมองว่าการบล็อก HTTP/1.1 สมเหตุสมผลแล้ว เบราว์เซอร์แทบทั้งหมดรองรับโปรโตคอลที่ใหม่กว่านี้มานานเกิน 10 ปีแล้ว และถ้าเป็นเบราว์เซอร์เก่าขนาดนั้น เว็บกระแสหลักส่วนใหญ่ก็น่าจะพังอยู่แล้ว ดังนั้นเว็บส่วนตัวอีกเว็บหนึ่งที่ใช้ไม่ได้ก็คงไม่ใช่ข้อยกเว้น แต่เป็นเรื่องปกติ
    • สำหรับเว็บงานอดิเรกและเว็บทดลอง ผมบล็อก ASN ทั้งหมดของ Google อย่างสมบูรณ์ ช่วงหลังไม่ได้รับทราฟฟิกที่มีประโยชน์เลย และมองว่าคุณภาพการค้นหาก็พังไปแล้ว
      ต่อให้พลาดผู้ใช้เบราว์เซอร์เก่าและเครื่องมือ API บางตัว ผมก็จะยังบล็อก HTTP/1.1 ต่อไป ถ้าเป็นโค้ดผูกขาดของระบบการเงินเก่า ๆ ก็พอเข้าใจได้ แต่อินเทอร์เน็ตสาธารณะควรอัปเดตตัวเองเพื่อประโยชน์ของตัวมันเอง
      เพราะผมบล็อก Google มานานแล้ว คำขอทั้งหมดที่อ้างว่ามาจาก Google จึงเป็นของปลอม ผมหมุนเวียนบล็อกไปตามโดเมนสุ่มหลายโดเมน เพื่อตัดความเชื่อมโยงและสแนปช็อต และพยายามควบคุมเส้นทางที่ผู้คนจะค้นพบบทความของผม
    • เมื่อไม่กี่ปีก่อน ผมบล็อกทราฟฟิกที่มาจาก AWS แล้วเขียนบทความเกี่ยวกับเรื่องนั้น ปกติผู้เข้าชมจริงมีแค่หลักสิบคนต่อสัปดาห์ แต่บทความนั้นมี คนจริง 15,000 คน อ่านในช่วงราว 3 เดือน แล้วก็ถูกลืมอย่างรวดเร็ว
      ผลพลอยได้คือผมได้รับการทดสอบเจาะระบบฟรี และได้ข้อสรุปว่ามาตรการป้องกันกับ pipeline การประมวลผลค่อนข้างแข็งแรง ด้วยแรงกดดันเพื่อความอยู่รอด ทราฟฟิกบอต 90% จึงย้ายไปอยู่บน VPN ทำให้ endpoint ของ VPN สว่างไสวเหมือนต้นคริสต์มาส
      ผมอาจให้ฟีด IP สำหรับการเข้าถึงครั้งเดียวได้ แต่ผู้ใช้ต้องผ่านการตรวจสอบอย่างเหมาะสม และวัตถุประสงค์การใช้งานก็ต้องได้รับอนุมัติ กระบวนการนี้เองก็สนุกดี
    • ผู้เขียนระบุชัดว่าโอเคกับการบล็อกผู้ใช้จริงหลายประเภท ดังนั้นผมจะไม่ทำตามคำแนะนำนั้น
  • ถ้าอ่านไม่ได้ สามารถดูฉบับเก็บถาวรได้ที่ https://archive.ph/d3236

    • เป็นการทำงานที่น่าเสียดายสำหรับผู้ใช้ iOS Safari ทั่วไป: https://i.ibb.co/vCDH79d0/IMG-0303.png
      ผมไม่อยากปิด iCloud Private Relay เพียงเพื่ออ่านอะไรสักอย่าง ทั้งที่ผมไม่ใช่บอต จากคำตอบอื่นของผู้เขียน ในฐานะเว็บทดสอบถือว่าเป็นการทำงานที่ดี แต่ถ้าเป็นผู้ดูแลเว็บรายอื่น ผมหวังว่าจะไม่ยกทุกวิธีไปใช้ตามตรงถ้าเป็นไปได้
    • น่าสนใจที่ผมเองเข้าไม่ได้ แต่ crawler ของ archive.ph กลับผ่านไปได้โดยไม่มีปัญหา
  • ดูจาก body ของ response ที่มีแค่ 410 กับสตริง Sec-Fetch-Mode: น่าจะตัดสินว่าผมเป็นบอต ไม่มีอะไรให้อ่านหรือดู ก็เลยได้แต่จากไป เว็บสมัยใหม่นี่แย่มาก

    • เบราว์เซอร์จริงส่ง header นั้น แต่แอปอ่านบางตัวและบอตส่วนใหญ่ที่ไม่ได้ใช้ Chrome Headless จะไม่ส่ง
      ดูสถานะการรองรับได้ที่ https://caniuse.com/?search=sec-fetch-mode และดู header บางส่วนได้ที่ https://nochan.net/.env
    • ผมไปไม่ถึงขั้นนั้นด้วยซ้ำ เจอ PR_END_OF_FILE_ERROR ซึ่งหมายความว่าแม้แต่ TLS handshake ก็ยังไม่ผ่าน
  • คาดว่า มากกว่า 99% ของเว็บทราฟฟิกเป็นบอตหรือเอเจนต์ เลยกำลังคิดว่าจะเอาตัวนับผู้เข้าชมออกดีไหม ตัวเลขไม่มีความหมายและทำให้เว็บดูคึกคักกว่าความเป็นจริงมาก แต่ก็ลังเลที่จะลงมือ เพราะกลัวว่าคนจริงจะอ่านบทความหรือดาวน์โหลดหนังสือไม่ได้

    • นิยายเทคโนทริลเลอร์, SF และลึกลับ ฟังดูน่าไปดูภายหลัง
  • ถ้าจำเป็นต้องบล็อก โดยทั่วไป allowlist จะได้ผลดีกว่า denylist และถ้าใช้ allowlist ไม่ได้ วิธีนี้ก็อาจไม่ใช่ทางออกที่ดี
    เครื่องมืออย่าง Cloudflare และ Anubis อาจก่อปัญหาด้านการเข้าถึงอย่างรุนแรง ผมจึงชอบจำกัดอัตราคำขอมากกว่า มันเรียบร้อยและไม่กระทบ accessibility และการบล็อก IP ชั่วคราวสั้น ๆ ก็ใช้ได้ดีกับปัญหาชั่วคราว
    โดยส่วนตัว ผมใช้ fail2ban วิเคราะห์ HTTP log แล้วบล็อก IP เป็นเวลา N ชั่วโมง หากขอ URL ที่ถูกห้ามไว้ใน robots.txt หรือเส้นทางอย่าง wp-login.php หรือเกิน rate limit บ่อยเกินไป ตอนนี้กำลังทดลองใช้ Anubis บน Git web UI

    • สำหรับการสื่อสารระหว่างองค์กร เราใช้ VPN ระหว่างเครือข่าย เพื่อทำ allowlist จากภายนอก VPN จะเข้าถึงเซิร์ฟเวอร์ไม่ได้ และพนักงานเข้าผ่าน VPN ของบริษัทได้
  • ใช้แค่ fail2ban ก็กันได้ค่อนข้างดี แต่ช่วงสองสามเดือนแรกต้องปรับละเอียดให้เข้ากับสภาพแวดล้อม
    ตอนแรกใช้ฟิลเตอร์ failregex = ^ - \S+ \[\] ".*?" 40[034] ตรวจจับก่อน แล้วค่อยเพิ่มเข้าไปในรายการที่เฉพาะเจาะจงกว่า ปัจจุบันใช้ regex ราว 80 รายการ บล็อกทราฟฟิกทั้งหมด จนไม่มีคำขอที่ไปถึงฟิลเตอร์ทั่วไป 40[034] มานานแล้ว
    อย่างไรก็ตาม ถ้าอยู่หลัง load balancer หรือ proxy ก็ต้องมีวิธีเอา IP จริงมาใช้ ซึ่งทำให้ทั้ง fail2ban และวิธีในบทความต้นฉบับยุ่งยากขึ้น

    • โหลดบาลานเซอร์เลเยอร์ 7 ส่วนใหญ่มีฟังก์ชันเพิ่ม header ที่ใส่ IP จริงได้ แค่ตั้งค่าเว็บเซิร์ฟเวอร์ให้บันทึก header นั้น ซึ่งคล้ายมากกับวิธีที่ CDN ส่งต่อ IP จริง
  • จากคอมเมนต์เหล่านี้และความพยายามเข้าเว็บของผม ดูเหมือนจะไม่ได้บล็อกแค่บอต แต่ บล็อกทราฟฟิกปกติทั้งหมด ด้วย

    • ถ้าดูแค่คอมเมนต์อาจเข้าใจผิดได้ จนถึงตอนนี้มีคนประมาณ 2,600 คน และบอตบางส่วนที่อ่านบทความได้
      วันอาทิตย์จะได้เห็นเบราว์เซอร์และแอปแปลก ๆ ที่ผู้คนใช้ท่องเว็บมากที่สุด ส่วนวันธรรมดาจะมีเบราว์เซอร์กระแสหลักทั่วไปมากกว่า จึงเป็นการทดสอบที่ดี