ความปลอดภัย + อัปเกรดและแก้ปัญหา
Security and monitoring · upgrade runbook and troubleshooting
TL;DR — สรุปใน 30 วินาทีtldr
สรุปหลักความปลอดภัยของ BOMLLM ในหนึ่งประโยค: ทุกอย่าง bind อยู่ที่ localhost หรือ Tailscale ของที่เปิดสู่โลกคือ Cloudflare Tunnel ประตูเดียว ทุก API มีกุญแจ ทุกกุญแจมีงบ และไม่มีความลับถูก commit ลง repo เลย
บทสุดท้ายคือ "คู่มือผู้รอดชีวิต" — ทุกบทอื่นชี้กลับมาที่นี่เมื่อมีปัญหา มีสองส่วน: วินัยการอัปเกรดที่ทำให้ระบบไม่พังตอนอัป และ สูตรแก้เมื่อมันพังตอนตี 2
เมื่อไหร่ควรใช้ / When to usewhen to use
บทนี้ไม่ใช่ "อ่านผ่าน" — กลับมาอ่านซ้ำทุกครั้งที่ (1) เพิ่มช่องทางใหม่ (2) เปิดพอร์ต/บริการใหม่ (3) ก่อนอัปเกรดใหญ่ นะครับ
กลับมาที่บทนี้ทุกครั้งที่: จะอัปเกรดส่วนไหนก็ตาม, เจออาการผิดปกติ, หรืออ่านเจอคำว่า "ถ้าติดตรงไหน" ในบทอื่นนะครับ
วิธีทำ / How-tohow to
ตาราง bind ของทุก service (นโยบายจริงจาก ss -tlnp):
| Service | bind ที่ | เหตุผล |
|---|---|---|
| LiteLLM :4000 | 127.0.0.1 (+ Tailscale ผ่าน forward สำหรับ probe) | เส้นทางสาธารณะคือ tunnel เท่านั้น |
| Open WebUI :3000 | 127.0.0.1 | อยู่หลัง tunnel |
| SearXNG :8888 | 127.0.0.1 | ภายในเท่านั้น |
| Qdrant :6333 | 127.0.0.1 | ไม่มีเวกเตอร์สาธารณะ |
| Postgres / Valkey | เครือข่าย container เท่านั้น | ไม่เปิด host port เลย |
| Ollama (Mac) :11434 | Tailscale IP เท่านั้น | mesh เท่านั้น + firewall เปิด |
| SSH | พอร์ตไม่มาตรฐาน + key เท่านั้น | ufw ตั้ง DROP เป็นค่าตั้งต้น |
คุณสมบัติที่ตรวจซ้ำทุกรอบ audit:
# ตรวจเบื้องต้นด้วยตัวเองได้ (รันบน VPS)
curl -o /dev/null -w "%{http_code}" -X POST https://llm.example.com/v1/chat/completions
# ต้องได้ 401 — ไม่มีกุญแจห้ามผ่าน (ตรวจทุกรอบ)
curl -o /dev/null -w "%{http_code}" https://chat.example.com/api/models
# ต้องได้ 401 — ไม่มี session ห้ามเห็นโมเดล
ss -tlnp | grep -v 127.0.0.1 # ดูว่ามีอะไร Listen นอก localhost ที่ไม่ควรมีถ้าผลใดผิดจากนี้ = หยุดทุกอย่าง แก้ให้กลับมาถูกก่อนครับ
สุขลักษณะความลับ (ทบทวนจากบทที่ ๔): master key อยู่ใน .env บน VPS เท่านั้น, กุญแจรายช่องทางหมุนเวียนได้โดยไม่แตะ master, .env chmod 600 + gitignore, ใน log/รายงานพูดแค่ "โหลดคีย์แล้ว ยาว N ตัว", n8n เก็บความลับใน credential store เท่านั้น
การเฝ้าระวัง: Uptime Kuma บน NAS probe ทุก 5 นาที (ยิง GET /api/version ผ่าน mesh) และยิงแจ้งเตือน Telegram เมื่อสถานะพลิก — สถานะเฝ้าระวังสรุปไว้ในบอร์ดภายใน
ถ้าติดตรงไหน → บทที่ ๙
กฎ 6 ข้อของการอัปเกรด (ไม่มีข้อไหนต่อรอง):
- ปักเวอร์ชันทุกอย่าง — ห้าม latest เด็ดขาด (เคยโดน latest เปลี่ยนพฤติกรรมใต้มือ)
- หนึ่งองค์ประกอบต่อหนึ่งหน้าต่างเวลา — อัปสองอย่างพร้อมกันแล้วพัง = เรียนรู้อะไรไม่ได้เลย
- สำรองก่อนแตะ — dump Postgres + snapshot config และต้อง "กู้กลับได้จริง" (แบ็กอัพที่ไม่เคยกู้ = ข่าวลือ)
- เขียนแผนถอยก่อนพิมพ์คำสั่งอัป
- รันชุดตรวจ 6 ข้อหลังทุกการเปลี่ยน — เขียวทั้ง 6 หรือถอยกลับ
- นอกชั่วโมงเร่ง — หลัง 23:00 ของทุกวัน เว้นหน้าต่างรีสตาร์ทอัตโนมัติของเราเอง
ชุดตรวจ 6 ข้อ (รันหลังทุกการเปลี่ยนแปลง):
ต้นฉบับเต็มอยู่ใน docs/upgrade.md ของ repo — คัดลอกไปเป็นสคริปต์ของคุณได้เลยครับ
อาการที่พบบ่อยกับทางแก้บนมือ:
| อาการ | สาเหตุที่พบบ่อย | ทางแก้ |
|---|---|---|
| บอทตอบว่างเปล่า | think เปิด + num_predict น้อย | pin think:false บน route (บทที่ ๔) |
| ข้อความไหลช้า ๆ ขึ้นเป็นพัก ๆ | สองโมเดล resident จน swap | ไล่โมเดลรอง (keep_alive 0) แล้วดูบทที่ ๒ |
| เข้าเว็บแชทไม่ได้ 401 รัว ๆ | กุญแจ/เซสชันหมดอายุ | ตรวจ master key ใน .env แล้ว up -d ใหม่ |
| คำตอบไทยเริ่มมีตัวจีนชุก | system prompt หลุด / route ใหม่ไม่ได้ใส่ Config G | กลับไปดู route + บทที่ ๖ |
| ค่าคลาวด์วันนี้สูงผิดปกติ | Mac ล่มนาน จน Tier 3 ทำงานหนัก | ดู spend log รายชั่วโมง + เช็คสาเหตุที่ Mac |
| อัปเดตแล้วพัง | เวอร์ชันลอย / param ถูกตัดเงียบ | ถอยกลับแท็กเดิมก่อน แล้วหาสาเหตุทีหลัง |
สูตรตี 2 (พังตอนกลางคืน): (1) อย่า debug ลึก ๆ ตอนง่วง — ถอยกลับแท็กเดิมก่อน (2) เก็บ log 30 นาทีล่าสุดใส่โฟลเดอร์เหตุการณ์ (3) นอน (4) ทำ post-mortem หนึ่งหน้าใน 48 ชม. ระบุสาเหตุราก + กฎข้อไหนที่ถ้าทำตามจะกันเหตุนี้ แล้วเพิ่มกฎนั้นเข้าคู่มือ
ตัวอย่างการตั้งค่า / Config exampleconfig example
ตารางภัยคุกคามกับมาตรการ (ฉบับย่อจาก docs/security.md):
| ภัย | มาตรการที่ระบบทำ |
|---|---|
| กุญแจรั่ว (git/ภาพ/log) | ระบบ gitignore + ตรวจก่อน push + งบต่อกุญแจจำกัดความเสียหาย |
| สแกนเนอร์อินเทอร์เน็ต | เปิดผ่าน tunnel เท่านั้น + 401 ถ้าไม่มีกุญแจ |
| VPS โดนบุก | ไม่มีโมเดล/ข้อมูลหนักบน VPS; Mac อยู่ใน mesh; สำรองข้อมูลออกกล่องทุกคืน |
| Prompt injection ผ่านผลค้นเว็บ | ผลค้นเป็นบริบท ไม่ใช่คำสั่ง + system prompt ตรึงพฤติกรรม + บอทมี post-process |
| ค่าใช้จ่ายหนีบ | งบรายวันรายกุญแจ + เพดานรวม $5 + แจ้งเตือน |
| อุปทาน (image) เปลี่ยนใต้มือ | ปักแท็กเวอร์ชันทุกตัว ห้าม latest |
ขั้นตอนอัปเกรดยอดฮิตแบบย่อ (เต็มอยู่ใน docs/upgrade.md) ครับ:
# --- Ollama บน Mac ---
brew upgrade ollama # แล้ว restart service ครับ
ollama --version # client == server ต้องตรงกันครับ
ollama ps # โมเดลหลักต้องกลับมา resident ครับ
# แชทอุ่นเครื่องแรก < 5 วิ จึงนับว่าเสร็จ
# --- LiteLLM / WebUI บน VPS ---
docker compose pull litellm # แท็กที่ปักไว้ ครับ
docker compose up -d litellm # recreate ตัวเดียวครับ
docker compose logs -f litellm # ดู boot: parse config + DB migrate ครับ
# หลังอัป: diff /model/info กับ snapshot ก่อนอัป + รัน smoke 6 ข้อความเสี่ยงสุด = migration ของฐานข้อมูล ดังนั้น dump Postgres ทุกครั้งก่อน pull ครับ
Pro tip — เคล็ดลับจากสนามจริงpro tip
คำถามที่พบบ่อย / FAQfaq
ถาม: ข้อมูลออกนอกบ้านไหม? — ไม่ ยกเว้นกรณี Tier 3 คลาวด์ถูกดึงใช้ (สามารถปิดขาดได้ในบทที่ ๔) และการค้นเว็บที่ออนไลน์เพื่อดึงผลลัพธ์กลับ (ตัวค้นตั้งในเครื่องแต่ตัวเว็บไซต์เป้าหมายเห็น IP ของ VPS ตามปกติ)
ถาม: ถ้าอยากล็อกแน่นสุด ๆ? — ปิด signup บน WebUI + ครอบ Cloudflare Access ทุกหน้า admin + ปิด Tier 3 + เปิด ufw DROP ทั้งขาเข้ายกเว้น SSH/Tailscale — ระบบจะเงียบสนิทกับโลกภายนอก
คำถามอื่น ๆ ดูที่ FAQ
ถาม: ควรอัปเดตถี่แค่ไหน? — มี CVE ด่วน = ทันทีแต่ตามกฎ 6 ข้อ, ปกติ = เดือนละครั้งในหน้าต่างกลางคืน, macOS = เลือกสัปดาห์ว่าง ๆ เท่านั้น
ถาม: พังจนไม่รู้จะทำไง? — ถอยทั้ง stack กลับแท็กเดิมทั้งหมด (ทำได้เพราะทุกอย่างปักเวอร์ชัน + มี dump) แล้วค่อยหาสาเหตุบนสำเนา ไม่ใช่บนของจริงที่ลูกค้ากำลังใช้
ดูเพิ่ม / See alsosee also
- บทที่ ๒ · เตรียมเครือข่าย — ที่มาของสถาปัตยกรรมนี้
- docs/upgrade.md — ฉบับอังกฤษเต็ม
ภาพประกอบ / Figuresfigures

คลิปหน้าจอจริงตามบทเรียน · คลิกเล่นเพื่อฟังสรุป · ไม่ใช่คำแนะนำการลงทุนครับ
▶ ดูวิดีโอคู่มือ: https://youtu.be/O4hM39cgDCY