วิธีแก้ปัญหาที่น่ารำคาญที่สุดใน Homelab ของผม

Homelab ของผมเริ่มต้นจากจุดเล็กๆ และความน่ารำคาญก็เช่นกัน

เมื่อก่อนเวลาจะเปิดใช้งาน Jellyfin ผมต้องพิมพ์ 192.168.0.x:8097 ส่วน Home Assistant ก็ต้องใช้อีก IP พร้อมพอร์ต :8123 ยิ่งมีบริการอย่าง Karakeep หรือ Ollama เพิ่มเข้ามา จำนวนตัวเลขที่ต้องจดจำหรือทำ Bookmark ไว้ก็ยิ่งเพิ่มพูนขึ้นเรื่อยๆ

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

ในที่สุดผมจึงตัดสินใจแก้ปัญหานี้ในช่วงวันหยุด โดยเริ่มจากการกำหนด IP คงที่ให้กับอุปกรณ์ Zima (ZimaBoard และ ZimaCube) และจบลงด้วยการจัดระเบียบเครือข่ายใหม่ทั้งหมด

ปัจจุบันการตั้งค่าของผมราบรื่นมาก บริการต่างๆ ทำงานผ่านโดเมน .internal เช่น jellyfin.internal โดยไม่ต้องพิมพ์ IP หรือเลขพอร์ตให้วุ่นวายอีกต่อไป

การตั้งค่าก่อนและหลังปรับปรุง

ก่อนหน้านี้ เครือข่ายของผมเริ่มจากเราเตอร์ ISP ส่งต่อไปยังเราเตอร์ TP-Link ที่รันระบบ Homelab โดยมี OneMesh ช่วยขยายสัญญาณ Wi-Fi

ผมใช้ ZimaBoard สำหรับบริการที่ต้องเปิดทิ้งไว้ตลอดเวลาอย่าง Jellyfin เพราะประหยัดไฟ ส่วน ZimaCube ที่สเปกสูงและติดตั้ง Nvidia Ada RTX จะเปิดเฉพาะตอนใช้งาน AI เพื่อประหยัดค่าไฟ

My original homelab setup before the DNS changes

หลังการปรับปรุง อุปกรณ์ Zima ทั้งสองเครื่องใช้ Fixed IP โดยให้ ZimaBoard ทำหน้าที่เป็น DNS และ Reverse Proxy ทำให้ทุกบริการมีชื่อเรียกที่ชัดเจน

my homelab setup after dns and reverse proxy manager

แนวคิดหลัก: AdGuard DNS และ Nginx Proxy Manager

ระบบนี้อาศัยการทำงานร่วมกันของสองส่วนหลัก คือ AdGuard Home ที่ทำหน้าที่เป็น DNS server เพื่อแปลงชื่ออย่าง jellyfin.internal ให้เป็น IP address

จากนั้น Nginx Proxy Manager จะรับช่วงต่อเพื่อดูว่ามีการเรียกใช้ชื่ออะไร แล้วส่งต่อไปยังพอร์ตที่ถูกต้อง เนื่องจาก AdGuard สามารถจัดการได้เฉพาะ IP แต่ไม่สามารถจัดการเลขพอร์ตได้

เมื่อวางระบบนี้เสร็จ การเพิ่มบริการใหม่จะมีเพียง 2 ขั้นตอน คือเพิ่ม DNS rewrite ใน AdGuard และเพิ่ม Proxy Host ใน Nginx Proxy Manager เท่านั้น

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

ขั้นตอนที่ 1: กำหนด Fixed IP ให้กับอุปกรณ์หลัก

หัวใจสำคัญของระบบนี้คือ IP address ที่ไม่เปลี่ยนแปลง หาก IP ของ DNS server เปลี่ยน ระบบทั้งหมดจะพังทันที งานแรกจึงเป็นการตั้งค่า DHCP Reservation บนเราเตอร์

สำหรับเราเตอร์ TP-Link เข้าไปที่เมนู Advanced -> Network -> DHCP Server -> Address Reservation เพื่อเลือกจอง IP ให้อุปกรณ์ที่ต้องการ

reserving ip address for devices on local

หากเราเตอร์ของคุณไม่มีเมนูนี้ คุณสามารถหา MAC address ของเครื่อง Linux ได้โดยใช้คำสั่ง:

ip link show

คุณอาจใช้ คำสั่งเครือข่าย เช่น arp สแกนหาอุปกรณ์อื่น แต่การเช็กผ่านหน้าตั้งค่าเราเตอร์โดยตรงมักจะง่ายที่สุด

ผมตั้งค่า Dynamic IP pool ให้เริ่มที่ 192.168.0.10 เพื่อไม่ให้ชนกับ IP ที่จองไว้ ดังนี้:

อุปกรณ์IPหมายเหตุ
เราเตอร์192.168.0.1Homelab network gateway
ZimaBoard192.168.0.4รัน 24x7, โฮสต์ AdGuard และ NPM
ZimaCube 2 Pro192.168.0.5เปิดเฉพาะตอนใช้งานบริการหนักๆ
Dynamic pool192.168.0.10 - 253สำหรับอุปกรณ์ทั่วไป

หลังจากนั้นให้ทำการ ติดตั้ง AdGuard DNS และ Nginx Proxy Manager ตามขั้นตอนของแต่ละบริการ

ขั้นตอนที่ 2: ติดตั้ง AdGuard Home บนเครื่องที่เปิดตลอดเวลา

AdGuard Home ต้องรันบนเครื่องที่เปิดทิ้งไว้ตลอดเวลา ผมจึงเลือกติดตั้งบน ZimaBoard ผ่าน ZimaOS App Store โดยเลือกเวอร์ชัน AdGuard Home (HOST) เพื่อให้ผูกกับพอร์ต 53 ได้โดยตรง

ในการติดตั้ง ผมพบปัญหาคำสั่ง wget ล้มเหลว จึงเปลี่ยนมาใช้ curl แทนดังนี้:

sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/bigbeartechworld/big-bear-scripts/master/generate-adguard-home-config/run.sh)"

สำคัญ: ต้องใช้ sudo เสมอ มิฉะนั้นการสร้างไดเรกทอรีจะล้มเหลว หลังจากรีสตาร์ทแอปแล้ว ให้เปิดหน้าตั้งค่าผ่าน http://192.168.0.4:3000 (ไอคอนในแอปอาจใช้ไม่ได้ในโหมด host)

ปัญหาพอร์ตชนกัน

ตอนตั้งค่า ผมพบว่าพอร์ต 80 ถูกใช้งานอยู่ จึงเปลี่ยนพอร์ต Admin ของ AdGuard เป็น 3786 แทน ส่วนพอร์ต 53 ที่ชนกัน เกิดจาก container Pi-hole ที่ผมลืมทิ้งไว้ ซึ่งเช็กได้ด้วยคำสั่ง:

sudo docker ps --format "{{.Names}}: {{.Ports}}"
``` เนื่องจากทั้งคู่ทำหน้าที่เหมือนกัน ผมจึงเลือกลบ Pi-hole ออก
 
![วิธีแก้ปัญหาที่น่ารำคาญที่สุดใน Homelab ของผม](https://cdn.ai4bro.com/articles/1942/content/83b65d551e9ad74e.webp)
 
## ขั้นตอนที่ 3: ชี้เครือข่ายไปยัง AdGuard
 
ขั้นตอนถัดไปคือการบอกให้เราเตอร์ใช้ AdGuard เป็น DNS server โดยไปที่ **Advanced -> Network -> Internet** และเปลี่ยน DNS Address เป็น:
 
- **Primary DNS:** 192.168.0.4 (ZimaBoard)
- **Secondary DNS:** 1.1.1.1 (Cloudflare)
 
![AdGuard setup as DNS in the router](https://cdn.ai4bro.com/articles/1942/content/d14d7180fbf750d2.png)
 
การตั้ง Secondary เป็น `1.1.1.1` ช่วยให้อินเทอร์เน็ตไม่ดับหาก ZimaBoard ปิดตัวลง แต่มีข้อเสียคือบางครั้งอุปกรณ์อาจข้ามไปใช้ Cloudflare ทำให้ตัวกรองโฆษณาไม่ทำงานและชื่อ `.internal` จะใช้งานไม่ได้ชั่วคราว
 
### หากอุปกรณ์ไม่ยอมใช้ DNS ใหม่
 
หากตั้งค่าแล้วแต่เบราว์เซอร์ยังไม่แสดงใน Log ของ AdGuard ให้ลองเชื่อมต่อ Wi-Fi ใหม่ หรือใช้คำสั่ง `nmcli` ใน Linux:
 
```bash
nmcli connection modify "<connection-name>" ipv4.dns "192.168.0.4"
nmcli connection modify "<connection-name>" ipv4.ignore-auto-dns yes
nmcli connection down "<connection-name>" && nmcli connection up "<connection-name>"

ขั้นตอนที่ 4: สร้างชื่อโดเมนด้วย DNS Rewrite

ใน AdGuard ไปที่ Filters -> DNS rewrites -> Add DNS rewrite แล้วป้อนโดเมนที่ต้องการ เช่น jellyfin.internal ชี้ไปที่ IP 192.168.0.4

AdGuard DNS rewrites

อย่างไรก็ตาม DNS rewrite จัดการได้แค่ IP แต่ไม่รองรับเลขพอร์ต หากมีหลายบริการบน IP เดียวกัน เราจึงจำเป็นต้องใช้ Reverse Proxy เข้ามาช่วย

AdGuard DNS rewrites

ทำไมต้องใช้ .internal? เพราะ .local ถูกจองไว้สำหรับ mDNS ส่วน .lan หรือ .home อาจกลายเป็นโดเมนจริงในอนาคต แต่สำหรับ .internal นั้น ICANN ได้จองไว้ถาวร เพื่อใช้ในเครือข่ายส่วนตัวเท่านั้น

ขั้นตอนที่ 5: จัดการพอร์ตด้วย Nginx Proxy Manager เพื่อให้ http://jellyfin.internal ทำงานได้โดยไม่ต้องใส่พอร์ต เราต้องมีตัวดักฟังที่พอร์ต 80 ซึ่งผมเลือกใช้ Nginx Proxy Manager (NPM) บน ZimaBoard

แก้ปัญหาพอร์ต 80 ซ้ำซ้อน

พอร์ต 80 มักถูกจองโดย zimaos-gateway ผมจึงย้ายแดชบอร์ด ZimaOS ไปที่พอร์ต 8888 แทนผ่านเมนู Settings เพื่อคืนพอร์ต 80 ให้กับ NPM

ตรวจสอบพอร์ตที่ใช้งานอยู่ได้ด้วยคำสั่ง:

sudo ss -tulpn | grep :80

การเพิ่ม Proxy Host

เข้าหน้า Admin ของ NPM ที่ http://192.168.0.4:81 แล้วไปที่ Hosts -> Proxy Hosts -> Add Proxy Host โดยกรอกข้อมูลดังนี้:

  • Domain Names: jellyfin.internal
  • Forward Hostname / IP: IP ของเครื่องที่รันบริการ
  • Forward Port: พอร์ตของบริการนั้นๆ (เช่น 8097)
  • Websockets Support: แนะนำให้เปิดไว้สำหรับบริการอย่าง Home Assistant

Nginx Proxy Manager Settings

การแก้ปัญหาที่พบบ่อย

Home Assistant Error 400: แก้ไขโดยเพิ่มการเชื่อถือ Proxy ใน configuration.yaml:

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.17.0.0/16 # Subnet ของ Docker bridge

Netflix ใช้งานไม่ได้: หาก AdGuard บล็อกโดเมน telemetry ของ Netflix ให้เพิ่มกฎใน Custom filtering rules:

@@||logs.netflix.com^
@@||nrdp26.logs.netflix.com^

บทสรุป

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

Source: It's FOSS
ดูแลงานแปลและเรียบเรียงโดย AttapolK
Nginx Proxy Manager

ความคิดเห็น (0)

เข้าสู่ระบบเพื่อร่วมแสดงความเห็น

สมัครสมาชิก

มาเป็นคนแรกที่แสดงความเห็นกันเลยโบร