SSD Nodes Learn 🎉 VPS เริ่ม $5.50/เดือน
คู่มือ Matt Connorโดย Matt Connor

วิธีแก้ปัญหา SearXNG ขึ้น Error 429 และ Rate Limit

แก้ไขปัญหา SearXNG ขึ้นสถานะ 429 อย่างตรงจุดด้วยการตรวจสอบ Log เพื่อแยกแยะระหว่างการจำกัดอัตราภายในระบบหรือการถูกบล็อก IP จากเครื่องมือค้นหาต้นทาง พร้อมวิธีตั้งค่าที่ถูกต้อง

เหตุใด SearXNG จึงส่งคืนข้อผิดพลาด 429

อินสแตนซ์ SearXNG ที่โฮสต์ด้วยตนเองส่งคืนข้อผิดพลาด 429 ด้วยเหตุผลสองประการที่ไม่เกี่ยวข้องกัน และการจำกัดอัตรา (rate limit) ที่คุณต้องแก้ไขมักไม่ใช่สิ่งที่คุณคาดคิด เหตุผลแรกคือปัญหาภายใน: ตัวจำกัดของ SearXNG เองตัดสินว่าคำขอมาจากบอทและตอบกลับ Too Many Requests ด้วยสถานะ 429 เหตุผลที่สองคือปัญหาจากต้นทาง (upstream): เครื่องมือค้นหาปฏิเสธที่อยู่ IP ของเซิร์ฟเวอร์คุณ ซึ่งส่งผลให้ผู้ใช้ของคุณได้รับหน้าผลลัพธ์ที่ข้อมูลบางส่วนหายไป ไม่ใช่ข้อผิดพลาด 429

ทั้งสองกรณีไม่มีวิธีแก้ไขร่วมกัน ตัวจำกัดเป็นของคุณ ดังนั้นคุณจึงสามารถปรับเปลี่ยนได้ ส่วนการบล็อกที่ต้นทางเกิดขึ้นจากฝั่ง Google ดังนั้นจึงไม่มีการตั้งค่าใดใน settings.yml ของคุณที่จะแก้ไขปัญหานี้ได้ บันทึก (log) จะบอกคุณว่าคุณกำลังเผชิญกับกรณีใดภายในเวลาประมาณหนึ่งนาที ดังนั้นให้เริ่มตรวจสอบจากจุดนั้น

คู่มือนี้อ้างอิงการติดตั้งแบบคอนเทนเนอร์ที่อธิบายไว้ใน อินสแตนซ์ SearXNG ที่โฮสต์ด้วยตนเองบน VPS ของคุณ ชื่อการตั้งค่าทั้งหมดด้านล่างมาจากเอกสารประกอบและซอร์สโค้ดต้นทางปัจจุบัน ซึ่งตรวจสอบเมื่อเดือนสิงหาคม 2026

อ่าน log ก่อนที่คุณจะเปลี่ยนการตั้งค่า

จำลองปัญหาที่เกิดขึ้นโดยเปิดหน้าต่าง log ทิ้งไว้

cd ./searxng/
docker compose logs -f searxng-core

ข้อความจากตัวจำกัด (limiter) จะมาจาก logger ที่ชื่อ searx.limiter และจะระบุที่อยู่ IP ไว้ด้วย หากมีการบล็อกจะแสดงข้อความ BLOCK 203.0.113.10: matched BLOCKLIST และหากผ่านการอนุญาตจะแสดงข้อความ PASS 203.0.113.10: matched PASSLIST หากตัวจำกัดไม่สามารถเข้าถึงที่เก็บข้อมูลตัวนับได้ log จะแสดงข้อความ The limiter requires Valkey, please consult the documentation ซึ่งหมายความว่าไม่มีการนับจำนวนใดๆ เกิดขึ้นเลย

การตรวจสอบบอทแต่ละรายการจะถูกบันทึกไว้ในระดับ debug ดังนั้นคุณจะไม่เห็นข้อมูลเหล่านี้โดยค่าเริ่มต้น ให้เปิดใช้งาน debug สำหรับการทดสอบหนึ่งครั้งใน settings.yml:

general:
  debug: true

จากนั้น log จะเพิ่มบรรทัดที่มีรูปแบบเหมือน NOT OK (http_accept_language) ถัดจากเครือข่ายของไคลเอนต์ โดยระบุชื่อการตรวจสอบที่ล้มเหลว ให้ปิดการใช้งาน debug หลังจากทดสอบเสร็จสิ้น เนื่องจากคำแนะนำจากต้นทางระบุว่าไม่ควรเรียกใช้งาน instance ในสภาพแวดล้อมจริงโดยเปิดโหมด debug ทิ้งไว้

ความล้มเหลวของ engine จะมีลักษณะต่างออกไป โดยจะระบุชื่อ engine แทนที่จะเป็น IP และปัญหาที่พบบ่อยที่สุดคือการหมดเวลา (timeout):

HTTP requests timeout (search duration : 3.1 s, timeout: 3.0 s)

นอกจากนี้ยังมีหน้าสำหรับตรวจสอบเรื่องนี้โดยเฉพาะ หากค่า enable_metrics ยังคงเป็นค่าเริ่มต้นที่ true instance ของคุณจะบันทึกข้อผิดพลาดของ engine ไว้ที่ /stats/errors และ /preferences จะแสดงรายการ engine ที่กำลังตอบสนองอยู่ในปัจจุบัน หาก /stats/errors เต็มและใน log ไม่มีบรรทัด searx.limiter แสดงว่าปัญหาไม่ได้เกิดจากตัวจำกัด (limiter)

กำหนดเวอร์ชันให้คงที่ก่อนเริ่มแก้ไขปัญหาใดๆ

การตั้งค่าคอนเทนเนอร์จากต้นทางประกอบด้วยไฟล์สองไฟล์

mkdir -p ./searxng/core-config/
cd ./searxng/

curl -fsSL \
    -O https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml \
    -O https://raw.githubusercontent.com/searxng/searxng/master/container/.env.example

cp -i .env.example .env

ไฟล์ compose ดึง docker.io/searxng/searxng:${SEARXNG_VERSION:-latest} มาใช้งาน การไม่กำหนดค่าตัวแปรหมายถึง latest และ latest หมายความว่าอินสแตนซ์จะเปลี่ยนไปโดยที่คุณไม่รู้ตัวในการทำ docker compose pull ครั้งถัดไป ดังนั้นการตั้งค่าที่เคยใช้งานได้เมื่อสัปดาห์ก่อนอาจไม่ตรงกับโค้ดที่อ่านค่าเหล่านั้นอีกต่อไป แท็กของ SearXNG จะระบุวันที่และ commit ไว้ แท็กตัวอย่างใน .env.example ของต้นทาง ณ เดือนสิงหาคม 2026 คือ 2026.3.25-541c6c3cb ดังนั้นให้กำหนดค่าที่แน่นอนลงใน .env:

SEARXNG_VERSION=2026.3.25-541c6c3cb

ตรวจสอบแท็กที่เผยแพร่และกำหนดเวอร์ชันที่คุณทดสอบจริงให้คงที่ จากนั้นจึงค่อยแก้ไขปัญหาโดยเทียบกับเป้าหมายที่แน่นอน ไฟล์ .env เดียวกันนี้ยังเก็บ secret key ของคุณไว้ด้วย ดังนั้นโปรดอ่าน วิธีการทำงานของไฟล์ env และ secret ใน Docker Compose ก่อนที่คุณจะ commit ไดเรกทอรีนั้นไปยังที่ใดก็ตาม

ตัวจำกัดอัตราการเข้าถึงจำเป็นต้องใช้ Valkey มิฉะนั้นจะไม่สามารถทำงานได้

ตัวจำกัดอัตราการเข้าถึง (limiter) จะทำหน้าที่นับจำนวนคำขอต่อไคลเอนต์ ซึ่งค่าที่นับได้นี้จะต้องถูกแชร์ระหว่าง worker process ต่างๆ โดยมี Valkey ซึ่งเป็น fork ของ Redis ที่ยังคงมีการดูแลรักษาอยู่ ทำหน้าที่เป็นที่จัดเก็บข้อมูล คู่มือการใช้งาน SearXNG รุ่นเก่าจะเรียกการตั้งค่านี้ว่า redis: แต่ในรุ่นปัจจุบันจะใช้ชื่อว่า valkey: ดังนั้นควรคัดลอกชื่อคีย์มาจากเอกสารประกอบฉบับปัจจุบันแทนที่จะคัดลอกมาจากบทความเก่า

use_default_settings: true
server:
  secret_key: "change-this-value"
  limiter: true
  public_instance: false
valkey:
  url: valkey://searxng-valkey:6379/0

ไฟล์ compose ของ upstream ได้รันบริการ searxng-valkey โดยใช้ image docker.io/valkey/valkey:9-alpine ไว้แล้ว ดังนั้นชื่อโฮสต์ดังกล่าวจึงสามารถ resolve ได้ภายในเครือข่ายของ compose ค่าเดียวกันนี้สามารถกำหนดได้ผ่านตัวแปรสภาพแวดล้อม SEARXNG_VALKEY_URL และยังสามารถใช้ URL แบบ Unix socket (unix:///path/to/socket.sock?db=0) ได้ในกรณีที่ SearXNG และ Valkey อยู่บนโฮสต์เดียวกัน

สิ่งที่เกิดขึ้นเมื่อไม่มีที่จัดเก็บข้อมูลจะขึ้นอยู่กับอีกหนึ่งคีย์ หากตั้งค่าเป็น public_instance: false ตัวจำกัดอัตราการเข้าถึงจะบันทึกข้อผิดพลาดของ Valkey ลงใน log แล้วปล่อยผ่านไป ทำให้ instance ยังคงให้บริการต่อไปได้โดยไม่มีการจำกัดอัตราการเข้าถึงเลย แต่หากตั้งค่าเป็น public_instance: true กระบวนการจะเรียกใช้ sys.exit(1) แทน เนื่องจาก instance ที่เปิดใช้งานโดยไม่มีระบบป้องกันบอทจะถูก engine ต่างๆ ตรวจพบและส่ง CAPTCHA (การทดสอบทัวริงสาธารณะแบบอัตโนมัติเพื่อแยกแยะคอมพิวเตอร์ออกจากมนุษย์) กลับมาจนเต็มภายในหนึ่งวัน หากคอนเทนเนอร์รีสตาร์ทวนลูปทันทีหลังจากที่คุณตั้งค่า public_instance: true ให้สันนิษฐานว่าเป็นกรณีนี้ และบรรทัดสุดท้ายก่อนที่โปรแกรมจะปิดตัวลงในแต่ละครั้งจะระบุถึง Valkey

สิ่งที่ตัวจำกัดจำนวนคำขอ (limiter) นับจริง ๆ

ChartSearXNG limiter: requests allowed per client IP, defaults in ip_limit.py
The data behind this chart
[
  {
    "label": "Burst, normal client",
    "max_requests": 15,
    "window": "20 seconds"
  },
  {
    "label": "Burst, flagged client",
    "max_requests": 2,
    "window": "20 seconds"
  },
  {
    "label": "Sustained, normal client",
    "max_requests": 150,
    "window": "10 minutes"
  },
  {
    "label": "Sustained, flagged client",
    "max_requests": 10,
    "window": "10 minutes"
  },
  {
    "label": "Any non-HTML format",
    "max_requests": 4,
    "window": "1 hour"
  },
  {
    "label": "Flagged requests before block",
    "max_requests": 3,
    "window": "30 days"
  }
]

ไคลเอนต์ทั่วไปสามารถส่งคำขอได้ 15 ครั้งภายในช่วงเวลา 20 วินาที และ 150 ครั้งภายในช่วงเวลา 10 นาที เมื่อคำขอใดถูกทำเครื่องหมายว่าน่าสงสัย ไคลเอนต์นั้นจะถูกลดจำนวนคำขอลงเหลือ 2 ครั้งต่อช่วงเวลา แถวสุดท้ายคือมาตรการที่เข้มงวดที่สุด: หลังจากมีคำขอที่ถูกทำเครื่องหมายว่าน่าสงสัยครบ 3 ครั้งภายในช่วงเวลา 30 วัน ที่อยู่ IP นั้นจะถูกเปลี่ยนเส้นทางไปยังหน้าเริ่มต้นแทนการค้นหา และ log จะแสดงข้อความ BLOCK: too many request from ... in SUSPICIOUS_IP_WINDOW (redirect to /)

ตัวเลขเหล่านี้เป็นค่าคงที่ใน searx/botdetection/ip_limit.py ซึ่งไม่ใช่การตั้งค่า และ limiter.toml ไม่ได้เปิดให้ปรับแต่ง ดังนั้นการเปลี่ยนแปลงค่าเหล่านี้จึงต้องแก้ไขที่ซอร์สโค้ด สิ่งที่ /etc/searxng/limiter.toml ควบคุมได้คือ prefix ของที่อยู่ที่ใช้จัดกลุ่มไคลเอนต์, รายการ trusted proxies, การตรวจสอบ link token (ถ้ามี), รวมถึงรายการอนุญาต (pass list) และรายการบล็อก (block list)

คำขอจะถูกทำเครื่องหมายว่าน่าสงสัยโดยการตรวจสอบ header ซึ่งแต่ละการตรวจสอบจะมีชื่อปรากฏใน debug log ดังนี้:

  • http_accept: header Accept ไม่มีค่า text/html
  • http_accept_encoding: header Accept-Encoding ไม่ระบุชื่อ gzip หรือ deflate
  • http_accept_language: ไม่มี header Accept-Language
  • http_connection: header Connection ถูกตั้งค่าเป็น close
  • http_user_agent: User-Agent หายไปหรือตรงกับรูปแบบของบอทที่รู้จัก
  • http_sec_fetch: header Sec-Fetch-Mode หรือ Sec-Fetch-Dest ไม่ใช่สิ่งที่เบราว์เซอร์ส่งมาตามปกติ

เบราว์เซอร์จะส่งข้อมูลเหล่านี้ทั้งหมด ในขณะที่การเรียกใช้ผ่าน curl แบบปกติแทบจะไม่ส่งข้อมูลเหล่านี้เลย ดังนั้นคำขอทดสอบที่เขียนขึ้นเองจึงถูกทำเครื่องหมายว่าน่าสงสัยตั้งแต่ครั้งแรกที่ส่ง ในขณะที่การค้นหาเดียวกันนั้นสามารถทำงานได้ในแท็บเบราว์เซอร์ นี่คือเหตุผลว่าทำไม "ใช้งานในเบราว์เซอร์ได้ แต่สคริปต์ของฉันกลับได้ 429" จึงเป็นผลลัพธ์ปกติ ไม่ใช่เรื่องลึกลับแต่อย่างใด

เมื่ออยู่หลัง reverse proxy ตัวจำกัดอัตราการเข้าถึงจะบล็อกทุกคนพร้อมกัน

นี่เป็นวิธีที่พบบ่อยที่สุดที่ทำให้ instance ที่ทำงานอยู่เกิดปัญหา SearXNG จะดึงที่อยู่ของไคลเอนต์จาก IP ที่ไม่น่าเชื่อถือตัวแรกใน X-Forwarded-For หากไม่พบจะใช้ X-Real-IP แทน และหากยังไม่พบอีกจะใช้ที่อยู่ที่เปิดการเชื่อมต่อเข้ามา การตัดสินใจว่าจะเชื่อถือ header เหล่านี้หรือไม่นั้นถูกกำหนดโดย trusted_proxies ใน limiter.toml

หากที่อยู่ของ proxy ของคุณไม่อยู่ในรายการดังกล่าว header เหล่านี้จะถูกเพิกเฉย และผู้เข้าชมทุกคนจะปรากฏตัวด้วยที่อยู่ของ proxy ทำให้ทุกคนใช้ตัวนับร่วมกัน ส่งผลให้ทั้งเว็บไซต์ถูกบล็อกทันทีเมื่อยอดรวมเกิน 150 คำขอภายใน 10 นาที ผู้ใช้เพียงคนเดียวที่กดโหลดหน้าผลลัพธ์ซ้ำไม่กี่ครั้งก็สามารถทำให้ทุกคนใช้งานไม่ได้

การเชื่อถือมากเกินไปก็ส่งผลเสียเช่นกัน หากมีการระบุช่วง IP สาธารณะไว้ ผู้เข้าชมทุกคนสามารถส่ง header X-Forwarded-For ของตนเองเพื่อสวมรอยเป็นตัวตนใหม่ในทุกคำขอ ซึ่งเป็นการปิดการทำงานของตัวจำกัดอัตราสำหรับใครก็ตามที่รู้วิธีนี้ ให้ระบุเฉพาะที่อยู่ที่ proxy ของคุณใช้เชื่อมต่อเข้ามาเท่านั้น ใน Docker โดยปกติจะเป็น bridge network ภายใน 172.16.0.0/12 และบรรทัดนั้นจะถูกใส่ comment ไว้โดยค่าเริ่มต้น

[botdetection]
ipv4_prefix = 32
ipv6_prefix = 48

trusted_proxies = [
  '127.0.0.0/8',
  '::1',
  '172.16.0.0/12',
]

ตัว proxy เองก็ต้องส่ง header เหล่านี้มาด้วยเช่นกัน Nginx จะไม่เพิ่ม header เหล่านี้ให้โดยอัตโนมัติ:

location / {
    proxy_pass http://127.0.0.1:8080;

    proxy_set_header Host              $host;
    proxy_set_header Connection        $http_connection;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
}

Caddy และ Traefik จะตั้งค่า forwarded headers ให้คุณ ดังนั้นหากใช้เครื่องมือเหล่านี้ คุณเพียงแค่ต้องจัดการส่วนของ trusted_proxies ให้เรียบร้อย ข้อดีข้อเสียของแต่ละตัวได้อธิบายไว้ใน การเลือก reverse proxy สำหรับบริการที่โฮสต์เอง เพื่อตรวจสอบว่าการตั้งค่าถูกต้องหรือไม่ ให้เปิด debug แล้วลองค้นหาผ่านเครือข่ายมือถือจากโทรศัพท์ของคุณ จากนั้นตรวจสอบใน log ว่าเครือข่ายที่ปรากฏเป็นที่อยู่ของโทรศัพท์ของคุณ ไม่ใช่ที่อยู่ของ proxy

เอเจนต์ของคุณได้รับคำขอ API สี่ครั้งต่อชั่วโมง

โดยปกติแล้วเอาต์พุต JSON จะถูกปิดใช้งานไว้เป็นค่าเริ่มต้น ดังนั้นเอเจนต์จึงจำเป็นต้องเพิ่มส่วนนี้เข้าไป:

search:
  formats:
    - html
    - json

ตอนนี้ให้ตรวจสอบแถวในตารางอีกครั้ง คำขอใดก็ตามที่ร้องขอรูปแบบอื่นที่ไม่ใช่ HTML จะถูกนับแยกในหน้าต่างของตนเอง โดยจำกัดที่ 4 คำขอต่อ 1 hour ต่อหนึ่งที่อยู่ IP เอเจนต์สำหรับการวิจัยมักใช้โควตานี้หมดภายในงานเดียว และทุกการเรียกใช้งานหลังจากนั้นจะได้รับสถานะ 429 การเพิ่มขีดจำกัดไม่ใช่ทางเลือกที่เหมาะสมเนื่องจากตัวเลขนี้ถูกกำหนดไว้ในซอร์สโค้ด

วิธีแก้ไขที่สะอาดที่สุดคือการแจ้งให้ตัวจำกัด (limiter) ทราบว่าไคลเอนต์นี้ไม่ใช่คนแปลกหน้า ให้เพิ่มที่อยู่ของไคลเอนต์ลงในรายการอนุญาต (pass list) ใน limiter.toml:

[botdetection.ip_lists]
block_ip = []

pass_ip = [
  '10.8.0.0/24',
]

pass_searxng_org = true

pass_ip มีลำดับความสำคัญเหนือกว่าวิธีอื่นทั้งหมด ดังนั้นไคลเอนต์ที่อยู่ในรายการอนุญาตจะข้ามการตรวจสอบส่วนหัว (header) ไปด้วย ทำให้การเรียกใช้งาน curl แบบปกติสามารถทำได้ ควรจำกัดช่วง IP ให้แคบที่สุดเท่าที่จะทำได้ และควรเลือกใช้ VPN subnet หรือ container network แทนเครือข่ายที่สามารถเข้าถึงได้จากสาธารณะ อีกวิธีหนึ่งที่สะอาดคือการไม่ให้เอเจนต์เข้าถึงผ่านเส้นทางสาธารณะเลย โดยให้ชี้ไปที่ที่อยู่ของคอนเทนเนอร์บนเครือข่ายภายใน ซึ่งเป็นจุดที่พร็อกซีและตัวจำกัดจะไม่เห็นทราฟฟิกดังกล่าว การตั้งค่านี้ครอบคลุมอยู่ใน การเพิ่มทักษะการค้นหา SearXNG ให้กับเอเจนต์ AI

ตัวเลือกที่ควรหลีกเลี่ยงคือการชี้เอเจนต์ไปยังอินสแตนซ์สาธารณะที่ผู้อื่นเป็นผู้ดูแล เพราะนั่นเป็นวิธีที่เร็วที่สุดที่จะทำให้ที่อยู่ IP ของอาสาสมัครถูกบล็อกโดยเครื่องมือค้นหาต้นทาง และนั่นคือเหตุผลว่าทำไมรูปแบบ JSON จึงถูกปิดใช้งานไว้เป็นค่าเริ่มต้นตั้งแต่แรก

เมื่อเครื่องมือค้นหาบล็อกคุณ

ChartHow long SearXNG suspends an engine, search.suspended_times defaults
The data behind this chart
[
  {
    "label": "SearxEngineTooManyRequests",
    "suspended_seconds": 3600,
    "roughly": "1 hour"
  },
  {
    "label": "SearxEngineAccessDenied",
    "suspended_seconds": 86400,
    "roughly": "1 day"
  },
  {
    "label": "SearxEngineCaptcha",
    "suspended_seconds": 86400,
    "roughly": "1 day"
  },
  {
    "label": "recaptcha_SearxEngineCaptcha",
    "suspended_seconds": 604800,
    "roughly": "7 days"
  },
  {
    "label": "cf_SearxEngineCaptcha",
    "suspended_seconds": 1296000,
    "roughly": "15 days"
  }
]

เมื่อเครื่องมือค้นหาตอบกลับด้วยสถานะ 429 หรือหน้า CAPTCHA ของตนเอง SearXNG จะสร้างข้อยกเว้นที่มีชื่อระบุและหยุดการสอบถามเครื่องมือค้นหานั้นชั่วคราว การตอบกลับแบบ too-many-requests จะระงับการทำงานเป็นเวลา 3600 วินาที ส่วนหน้า CAPTCHA ปกติหรือการตอบกลับแบบ access-denied จะระงับการทำงานเป็นเวลา 1 day สำหรับ CAPTCHA ที่ส่งผ่าน Cloudflare จะระงับการทำงานเป็นเวลา 15 days ซึ่งเป็นค่าเริ่มต้นที่นานที่สุดในรายการ เนื่องจากคำตอบนี้หมายความว่าการบล็อกเกิดขึ้นที่ระดับ edge และการลองใหม่จะไม่ช่วยให้สำเร็จ

ความล้มเหลวทั่วไปจะใช้การตั้งค่าที่แตกต่างกัน กรณี timeout หรือ parse error จะระงับเครื่องมือค้นหาเป็นเวลาสั้นๆ โดยคำนวณจาก search.ban_time_on_fail ซึ่งมีค่าเริ่มต้นที่ 5 วินาทีและถูกจำกัดสูงสุดไว้ที่ 120 วินาทีด้วย search.max_ban_time_on_fail ดังนั้นเครื่องมือค้นหาที่ทำงานช้าจะฟื้นตัวได้เองภายในเวลาไม่กี่นาที ในขณะที่เครื่องมือค้นหาที่ถูกบล็อกจะหายไปนานหลายชั่วโมง ความแตกต่างนี้อธิบายอาการที่ผู้ใช้มักรายงานว่าเป็นปัญหาแบบสุ่ม คือผลลัพธ์แสดงผลได้ปกติ แต่แล้วผลลัพธ์จากเครื่องมือค้นหาหนึ่งก็หายไปตลอดช่วงบ่าย

ควรแก้ไขปัญหา timeout ก่อนที่จะโทษปัจจัยอื่น ค่าเริ่มต้นของ request_timeout คือ 2.0 วินาที ซึ่งถือว่าค่อนข้างสั้นสำหรับ VPS ขนาดเล็กที่ตั้งอยู่ไกลจาก edge server ที่ใกล้ที่สุดของเครื่องมือค้นหานั้น

outgoing:
  request_timeout: 3.0
  max_request_timeout: 10.0
engines:
  - name: bing
    timeout: 5.0

request_timeout คือค่าเริ่มต้นสำหรับทุกเครื่องมือค้นหา max_request_timeout คือเพดานสูงสุด และเครื่องมือค้นหาแต่ละตัวสามารถกำหนด timeout เฉพาะของตนเองได้ การเพิ่มค่าเหล่านี้เป็นการแลกเปลี่ยนระหว่างความหน่วงของหน้าเว็บกับจำนวนความล้มเหลวที่ลดลง ดังนั้นควรปรับเพิ่มทีละ 0.5 วินาทีและคอยสังเกต /stats/errors แทนที่จะปรับเพิ่มไปถึง 10 ทันที

สำหรับเครื่องมือค้นหาที่บล็อก IP address ของคุณอย่างแท้จริง ให้ลบออกเสีย การค้นหาทุกครั้งต้องรอเครื่องมือค้นหาที่ช้าที่สุด ดังนั้นการเก็บเครื่องมือค้นหาที่ถูกระงับถาวรไว้จะทำให้เสียความหน่วงโดยเปล่าประโยชน์และไม่ได้รับผลลัพธ์ใดๆ

use_default_settings:
  engines:
    remove:
      - google

ใช้การเปลี่ยนแปลงด้วย docker compose restart searxng-core จากนั้นทำการค้นหาทดสอบสองสามครั้งและโหลด /stats/errors ใหม่ หากหน้าเว็บไม่ว่างเปล่าหลังจากใช้งานจริงไปแล้วห้านาที แสดงว่าการเปลี่ยนแปลงนั้นได้ผล

IP ของศูนย์ข้อมูลจะถูกระบุว่าเป็นบอท

ที่อยู่ IP ของ VPS ของคุณอยู่ในช่วงของโฮสติ้ง ซึ่งเครื่องมือค้นหาขนาดใหญ่จะจัดอันดับช่วง IP เหล่านี้ว่าเป็นระบบอัตโนมัติ เครื่องมือบางตัวจะแสดง CAPTCHA สำหรับทุกคำขอที่มาจากที่อยู่ดังกล่าว โดยไม่คำนึงว่าส่วนหัว (header) จะถูกต้องหรือความถี่ในการส่งคำขอจะช้าเพียงใด ไม่มีการตั้งค่าใดใน settings.yml ที่จะเปลี่ยนการตัดสินใจนี้ได้

สิ่งที่คุณสามารถเปลี่ยนได้คือการเลือกเครื่องมือค้นหาที่คุณใช้งาน และการเลือกว่าจะเปิดเผย instance ของคุณต่อสาธารณะหรือไม่ instance ส่วนตัวที่ใช้งานภายในครัวเรือนเดียวมักไม่ค่อยพบปัญหาดังกล่าว แต่ instance สาธารณะที่ใช้ IP ของโฮสติ้งจะถูกระงับการใช้งานจากเครื่องมือค้นหาที่เข้มงวดที่สุด ซึ่งถือเป็นสถานะปกติของซอฟต์แวร์ ไม่ใช่ข้อผิดพลาดในการตั้งค่าของคุณ SearXNG สามารถกำหนดเส้นทางคำขอไปยังเครื่องมือค้นหาผ่านพร็อกซีด้วย outgoing.proxies หรือ outgoing.using_tor_proxy ซึ่งเป็นการย้ายทราฟฟิกไปยังที่อยู่อื่น อย่างไรก็ตาม exit node และพร็อกซีราคาถูกมักถูกจัดอันดับแย่กว่าช่วง IP ของโฮสติ้ง ดังนั้นควรคาดการณ์ว่าการย้ายดังกล่าวอาจทำให้ผลลัพธ์การค้นหาแย่ลง

เฝ้าติดตามอินสแตนซ์เพื่อให้คุณทราบปัญหาเป็นคนแรก

SearXNG จะตอบสนองบนพอร์ตของตนเองเสมอแม้ว่า engine ทุกตัวจะถูกระงับการทำงาน ดังนั้นการตรวจสอบ uptime ที่ดูเพียง status code จะแสดงสถานะเป็นสีเขียวตลอดเวลาแม้ว่าอินสแตนซ์จะไม่ส่งผลลัพธ์ใดๆ ออกมาก็ตาม ให้ตรวจสอบที่เนื้อหาแทน โดยการส่งคำขอค้นหาจริงและจับคู่คำที่คาดว่าจะพบในเนื้อหาการตอบกลับ การตรวจสอบด้วยคีย์เวิร์ดใน Uptime Kuma สามารถทำสิ่งนี้ได้โดยไม่ต้องใช้เครื่องมือเพิ่มเติม นอกจากนี้ให้เฝ้าติดตาม /stats/errors หลังจากการอัปเดตเวอร์ชันทุกครั้ง เนื่องจาก engine อาจมีการเปลี่ยนแปลง HTML ซึ่งจะทำให้ตัวแยกวิเคราะห์ (parser) ทำงานผิดพลาดโดยไม่เกี่ยวข้องกับข้อจำกัดด้านอัตราการเข้าถึง (rate limit)

FAQ

ทำไม SearXNG ถึงตอบกลับด้วย 429 ให้ผู้เข้าชมทุกคนหลังจากที่ฉันนำไปไว้หลัง reverse proxy?

เพราะตัวจำกัดจำนวนคำขอ (limiter) นับว่า proxy คือไคลเอนต์ SearXNG จะอ่านค่า X-Forwarded-For ก็ต่อเมื่อที่อยู่ของผู้เชื่อมต่อถูกระบุไว้ใน trusted_proxies ภายในไฟล์ /etc/searxng/limiter.toml เท่านั้น หากไม่ได้ระบุไว้ ผู้เข้าชมทุกคนจะใช้ตัวนับร่วมกันและทำให้ทุกคนเกินขีดจำกัด 150 คำขอต่อ 10 นาทีพร้อมกัน ให้เพิ่มที่อยู่ IP ที่ proxy ของคุณใช้เชื่อมต่อ ซึ่งใน Docker มักจะเป็นช่วง bridge network 172.16.0.0/12 และตรวจสอบให้แน่ใจว่า proxy ได้ส่งค่า X-Real-IP และ X-Forwarded-For มาด้วย ห้ามระบุช่วง IP ที่คุณไม่ได้ควบคุมเด็ดขาด เพราะเครือข่ายที่เชื่อถือได้จะยอมให้ผู้เข้าชมคนใดก็ได้กำหนด header ดังกล่าวและเลือกตัวตนใหม่สำหรับทุกคำขอ

ตัวจำกัดของ SearXNG อนุญาตให้ทำ API request ได้กี่ครั้งต่อชั่วโมง?

สี่ครั้งต่อหนึ่งที่อยู่ IP ต่อชั่วโมง คำขอใดก็ตามที่ร้องขอรูปแบบอื่นที่ไม่ใช่ HTML จะถูกนับแยกในหน้าต่างเวลาหนึ่งชั่วโมง และขีดจำกัดนั้นถูกกำหนดไว้ใน searx/botdetection/ip_limit.py ไม่ใช่ใน limiter.toml จึงไม่สามารถเพิ่มค่าจากไฟล์ config ได้ หากเป็น agent หรือสคริปต์ที่ส่งคำขอเข้ามาในงานเดียว ให้เพิ่มที่อยู่ของไคลเอนต์ลงใน pass_ip ในไฟล์ limiter.toml หรือเข้าถึง instance ผ่านเครือข่ายภายในที่ตัวจำกัดมองไม่เห็นคำขอนั้น

ทำไมผลการค้นหาของฉันถึงว่างเปล่าโดยไม่มีข้อผิดพลาด 429?

เครื่องมือค้นหา (engines) กำลังปฏิเสธเซิร์ฟเวอร์ของคุณ ไม่ใช่ผู้ใช้งานของคุณ ให้เปิด /stats/errors บน instance ของคุณเอง มันจะระบุชื่อเครื่องมือค้นหาแต่ละตัวที่ล้มเหลวและสาเหตุ หากพบข้อความ CAPTCHA หรือ access-denied แสดงว่าเครื่องมือค้นหานั้นบล็อกที่อยู่ IP ของเซิร์ฟเวอร์คุณ จากนั้น SearXNG จะระงับการใช้งานเครื่องมือนั้นเป็นเวลาหนึ่งชั่วโมงหลังจากได้รับคำตอบว่ามีการร้องขอมากเกินไป และหนึ่งวันหลังจากติด CAPTCHA ไม่มีการตั้งค่าภายในเครื่องใดที่จะปลดบล็อกที่มาจากต้นทางได้ ดังนั้นให้ลบเครื่องมือค้นหาที่บล็อกที่อยู่ของคุณออกและเก็บไว้เฉพาะตัวที่ตอบกลับได้ปกติ

ฉันควรเปิดใช้งานตัวจำกัดบน instance ส่วนตัวหรือไม่?

หากไม่มีสิ่งใดเข้าถึง instance ได้นอกจากตัวคุณ ให้ปิด limiter: false ไว้ เพราะมันจะเพิ่ม dependency ของ Valkey และบล็อกสคริปต์ของคุณเอง อีกทั้งยังเป็นการป้องกันการจราจรข้อมูลที่คุณไม่ได้มีอยู่จริง ให้เปิดใช้งานทันทีที่ instance มีที่อยู่สาธารณะ พร้อมกับ public_instance: true ทั้งสองค่านี้ทำงานร่วมกันอย่างตั้งใจ: หากเปิด public_instance: true ไว้แต่ Valkey ไม่ทำงาน กระบวนการจะหยุดการทำงานด้วยสถานะ 1 แทนที่จะปล่อยให้รันโดยไม่มีการป้องกัน