SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-28

วิธีใช้ Claude ช่วยงานดูแลระบบ Linux เซิร์ฟเวอร์

แนะนำ 6 งานดูแลระบบที่ Claude ช่วยได้จริง ตั้งแต่การวิเคราะห์ log การเขียน systemd unit ไปจนถึงการตรวจทานไฟล์ nginx และ Compose พร้อมข้อควรระวังเรื่องข้อมูลห้ามคัดลอก

Claude สำหรับผู้ดูแลระบบ: คำแนะนำต้องมาก่อน การลงมือทำทีหลัง

Claude สำหรับผู้ดูแลระบบทำงานได้ดีที่สุดในฐานะผู้ตรวจสอบ คุณสามารถคัดลอกส่วนหนึ่งของ log, ไฟล์ config, คำสั่งที่คุณไม่คุ้นเคย หรือข้อความแจ้งเตือนความผิดพลาดมาวาง เพื่อรับคำอธิบายที่คุณสามารถตรวจสอบได้ก่อนที่จะเปลี่ยนแปลงใดๆ บนเซิร์ฟเวอร์ คำตอบที่ผิดจะไม่สร้างความเสียหายจนกว่าคุณจะนำไปรันจริง ดังนั้นการให้โมเดลทำหน้าที่เพียงให้คำแนะนำจึงเป็นโมเดลความปลอดภัยที่สำคัญที่สุด

งาน 6 ประเภทมักเกิดขึ้นทุกสัปดาห์บน Linux VPS (virtual private server) ที่เช่าไว้ แต่ละงานด้านล่างนี้มีรูปแบบ prompt ที่ใช้งานได้จริง คำสั่งที่ใช้ตรวจสอบคำตอบ และรูปแบบความล้มเหลวที่คุณควรคาดการณ์ไว้ งานเหล่านี้ไม่จำเป็นต้องให้โมเดลเข้าถึงเซิร์ฟเวอร์ของคุณ คุณสามารถคัดลอกข้อมูลจากแท็บเบราว์เซอร์หรือหน้าต่างบนเดสก์ท็อปของคุณเองได้ เนื่องจาก Claude ทำงานบน Linux ได้โดยตรงทั้งในรูปแบบแอปเดสก์ท็อปและ CLI

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

สิ่งที่คุณห้ามคัดลอกและวางโดยเด็ดขาด

ทุกสิ่งที่อยู่ในพรอมต์จะออกจากเซิร์ฟเวอร์ของคุณ ข้อมูล 4 ประเภทต่อไปนี้ต้องอยู่ภายในเครื่องเท่านั้น:

  • Private keys: ~/.ssh/id_ed25519, /etc/ssh/ssh_host_*_key และ TLS (transport layer security) key ใดๆ ภายใต้ /etc/letsencrypt/live/
  • ไฟล์ข้อมูลรับรอง (Credential files): .env, ~/.aws/credentials, /root/.docker/config.json และรหัสผ่านฐานข้อมูลในไฟล์ใดๆ หรือบรรทัดใดๆ ใน log
  • ข้อมูลบัญชี: /etc/shadow และ /etc/gshadow ไม่มีคำถามของผู้ดูแลระบบใดที่จำเป็นต้องใช้ password hash ในการตอบ
  • สิ่งใดก็ตามที่เป็นของผู้ใช้ของคุณ: ที่อยู่อีเมล, แถวข้อมูลคำสั่งซื้อ, request log ที่มี session cookie หรือ PII (ข้อมูลที่ระบุตัวตนได้)

Public key สามารถคัดลอกและวางได้อย่างปลอดภัย แต่ Private key ไม่สามารถทำได้ และไฟล์ทั้งสองประเภทนี้ดูคล้ายกันมากในแวบแรก ดังนั้นให้อ่านบรรทัดแรกก่อนที่คุณจะคัดลอก: ไฟล์ที่มีบรรทัดแรกประกอบด้วย BEGIN OPENSSH PRIVATE KEY ห้ามนำไปใส่ในพรอมต์โดยเด็ดขาด การจัดการ SSH key material ของคุณให้ถูกต้อง เป็นเรื่องที่คุ้มค่าที่จะใช้เวลาศึกษา 10 นาที

ให้ทำการปกปิดข้อมูล (Redact) ก่อนที่คุณจะวาง แทนที่จะเชื่อมั่นในตัวเองว่าจะมองเห็น token หนึ่งตัวใน 200 บรรทัด:

sudo journalctl -u myapp -n 200 --no-pager | sed -E 's/(token|secret|password|api[_-]?key)[=:][^[:space:]]+/\1=REDACTED/gI'

กับดักหนึ่งอย่างที่เฉพาะเจาะจงสำหรับ Docker คือ docker compose config ซึ่งจะทำการแทรกค่า .env ของคุณลงในผลลัพธ์ที่พิมพ์ออกมา ดังนั้นผลลัพธ์นั้นจึงเป็นความลับแม้ว่าไฟล์บนดิสก์จะไม่ใช่ก็ตาม ให้ใช้ docker compose config -q แทน ซึ่งจะทำการตรวจสอบความถูกต้องและไม่พิมพ์สิ่งใดออกมา สำหรับนโยบายในวงกว้างว่า agent ได้รับอนุญาตให้เห็นอะไรบ้าง การเก็บรักษาความลับให้ห่างจาก AI agents จะครอบคลุมถึงด้านสภาพแวดล้อม (environment)

งานที่ 1: ทำไมบริการนี้ถึงล้มเหลว?

เริ่มต้นด้วยคำสั่งสองคำสั่งที่เป็นกุญแจสำคัญในการหาคำตอบ:

systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 100 --no-pager -o short-iso

ให้คัดลอกคำสั่งทั้งสองพร้อมระบุบริบทที่โมเดลไม่สามารถคาดเดาได้ เช่น รุ่นของ distribution, สิ่งที่คุณเพิ่งแก้ไขล่าสุด, บริการนี้เคยทำงานได้หรือไม่ และหยุดทำงานไปนานเท่าใด ให้ถามถึงกลไกการทำงานก่อน

Ubuntu 24.04. myapp.service เคยทำงานได้ปกติจนกระทั่งฉันแก้ไขไฟล์ unit เมื่อหนึ่งชั่วโมงที่แล้ว นี่คือ systemctl status และ log จาก journal ย้อนหลัง 100 บรรทัด บรรทัดไหนคือข้อผิดพลาดที่แท้จริงบรรทัดแรก และมันหมายความว่าอย่างไร? ยังไม่ได้แก้ไขอะไร

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

ผลลัพธ์ที่ได้ควรเป็นบรรทัดในลักษณะ Main PID: 1841 (code=exited, status=203/EXEC) สถานะการออก (exit status) 203/EXEC หมายความว่า kernel ไม่สามารถรันไฟล์ที่ระบุใน ExecStart ได้: อาจเป็นเพราะไม่มี path ดังกล่าวอยู่จริง หรือไฟล์มีอยู่แต่ไม่มีสิทธิ์ในการรัน (executable) บรรทัด #! ที่ระบุถึง interpreter ที่ไม่ได้ติดตั้งไว้ก็ทำให้เกิดสถานะเดียวกัน ทั้งหมดนี้สามารถตรวจสอบได้ด้วย ls -l และ head -1

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

งานที่ 2: ร่าง systemd unit หรือ cron entry

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

sudo systemd-analyze verify /etc/systemd/system/myapp.service
sudo systemctl daemon-reload
sudo systemctl start myapp.service
systemctl status myapp.service --no-pager

systemd-analyze verify จะวิเคราะห์ไฟล์ในรูปแบบเดียวกับที่ systemd ทำ ทำให้ตรวจพบข้อผิดพลาดที่สายตามนุษย์มักมองข้าม หากสะกดคำสั่งผิดจะแสดง /etc/systemd/system/myapp.service:7: Unknown key name 'Enviroment' in section 'Service', ignoring. หากหาไฟล์ binary ไม่พบจะแสดง Command /usr/local/bin/myapp is not executable: No such file or directory ทั้งสองกรณีนี้จะไม่แจ้งเตือนระหว่างการรัน daemon-reload ซึ่งเป็นเหตุผลว่าทำไม unit ถึงโหลดผ่านได้ปกติแต่กลับล้มเหลวทันทีที่เริ่มทำงาน

ข้อผิดพลาดในการร่างไฟล์ที่พบบ่อยมีอยู่สองประการ ประการแรกคือ After=network.target ซึ่งหมายถึงเพียงแค่ว่า network stack ถูกตั้งค่าแล้ว แต่ไม่ได้หมายความว่ามี IP address พร้อมใช้งานจริง บริการที่ผูกกับ IP เฉพาะจะล้มเหลวตอนบูตด้วยข้อความ bind: Cannot assign requested address วิธีแก้ไขคือใช้ Wants=network-online.target ร่วมกับ After=network-online.target ประการที่สองคือการใช้ Type=simple กับโปรแกรมที่ทำ daemonize ตัวเอง: systemd จะมองว่า process แรกคือตัวบริการ เมื่อ parent process จบการทำงาน systemd จะถือว่า unit นั้นตายไปแล้ว ทั้งที่ process จริงยังคงรันอยู่โดยไม่มีการควบคุม นี่คือข้อผิดพลาดที่โมเดล AI มักจะสร้างให้คุณ เพราะมันไม่สามารถบอกได้จากคำสั่งของคุณว่า binary นั้นมีการ fork หรือไม่ ดังนั้นจึงควรศึกษา สิ่งที่ค่า Type= แต่ละแบบรับประกันกับ systemd ก่อนที่จะยอมรับร่างคำสั่งนั้น

สำหรับการตั้งเวลา ให้ตรวจสอบแทนการอ่านด้วยตา:

systemd-analyze calendar 'Mon *-*-* 04:00:00'

คำสั่งนี้จะแสดงรูปแบบที่ปรับให้เป็นมาตรฐานและเวลาถัดไปที่คำสั่งจะทำงาน ซึ่งช่วยยุติข้อโต้แย้งเกี่ยวกับความหมายของนิพจน์นั้น หากคุณกำลังเลือกระหว่าง timer กับ crontab บทความ systemd services และ timers บน VPS จะช่วยเปรียบเทียบข้อดีข้อเสียให้

Cron มีกับดักที่ไม่มีโมเดลไหนเตือนคุณเว้นแต่คุณจะถาม Cron รันงานด้วยสภาพแวดล้อมที่จำกัดมาก ดังนั้น PATH จึงมีค่าเท่ากับ /usr/bin:/bin โดยประมาณ และ shell profile ของคุณจะไม่มีการถูกอ่าน งานที่รันได้ปกติเมื่อวางลงใน terminal จะล้มเหลวเมื่อรันผ่าน cron ด้วยข้อความ /bin/sh: 1: docker: not found เพราะ binary นั้นอยู่ใน /usr/local/bin ให้ใช้ absolute path ใน crontab เสมอ หากการที่ไฟล์ unit บังคับให้ระบุผู้ใช้, สภาพแวดล้อม และ dependency ดูเป็นเรื่องยุ่งยากเมื่อเทียบกับบรรทัดเดียวใน crontab บทความ ปัญหาที่ systemd ถูกสร้างขึ้นเพื่อแก้ไข จะอธิบายว่าทำไมความละเอียดรอบคอบเหล่านั้นถึงจำเป็น

งานที่ 3: ตรวจสอบไฟล์ Nginx หรือ Compose ก่อนใช้งานจริง

งานนี้ให้ผลลัพธ์คุ้มค่าที่สุด ให้วางไฟล์ ระบุสิ่งที่ต้องการให้ทำ และขอคำอธิบายทีละบรรทัดว่าไฟล์นั้นทำงานอย่างไรจริง ๆ

vhost นี้ควรให้บริการ example.com ผ่าน HTTPS และทำ proxy ไปยัง /api ที่บริการภายในพอร์ต 8080 ช่วยอ่านทวนให้ฟังและระบุส่วนที่ไม่ตรงกับคำอธิบายนี้

จากนั้นให้รันเครื่องมือที่ตรวจสอบไวยากรณ์:

sudo nginx -t
docker compose config -q

nginx -t จะแสดง nginx: configuration file /etc/nginx/nginx.conf test is successful หรือระบุชื่อไฟล์และบรรทัดที่ผิดพลาด เช่น nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12 ส่วน docker compose config -q จะไม่แสดงผลลัพธ์ใด ๆ หากไฟล์ถูกต้อง และจะแสดงข้อความตรงไปตรงมาเช่น yaml: line 7: did not find expected key เมื่อการย่อหน้าของคุณคลาดเคลื่อน

เครื่องมือทั้งสองไม่ได้ตรวจสอบเจตนา (intent) ไฟล์ config ที่ผ่านการตรวจสอบด้วย nginx -t อาจยังคงทำ proxy ไปยังพอร์ตที่ผิด หรือเปิดฟังบน 0.0.0.0 ในขณะที่คุณตั้งใจจะใช้ 127.0.0.1 ช่องว่างตรงนี้คือจุดที่โมเดลมีประโยชน์ แต่ก็เป็นจุดที่อาจเกิดความผิดพลาดได้เช่นกัน: เมื่อถูกขอให้แก้ไข directive เดียว โมเดลมักจะส่งไฟล์ที่เขียนใหม่ทั้งหมดกลับมาโดยที่ directive ของคุณหายไปสองรายการโดยไม่แจ้งให้ทราบ ดังนั้นควรขอให้ระบุเฉพาะบรรทัดที่เปลี่ยนและเหตุผลของแต่ละจุด แล้วจึงแก้ไขด้วยตนเอง

ยืนยันสิ่งที่คุณเปิดใช้งานจริง:

sudo ss -tulpn

หากไม่มี sudo คุณจะเห็นเพียง socket ที่เปิดฟังอยู่แต่ไม่เห็น process ที่เป็นเจ้าของ หากผลลัพธ์นั้นทำให้คุณประหลาดใจ พอร์ตคืออะไรและ Linux ผูกพอร์ตอย่างไร เป็นบทความที่อ่านได้รวดเร็วและเข้าใจง่ายกว่า

งานที่ 4: อธิบายคำสั่งที่ไม่คุ้นเคยก่อนใช้งาน

ให้วางคำสั่งนั้นลงแล้วตั้งคำถาม 4 ข้อเกี่ยวกับคำสั่งดังกล่าว: แต่ละ flag ทำหน้าที่อะไร, คำสั่งนี้เขียนข้อมูลลงที่ใด, คำสั่งนี้ลบข้อมูลอะไรบ้าง และจะเกิดอะไรขึ้นหากรันคำสั่งเดิมซ้ำสองครั้ง คำถามข้อสุดท้ายนี้ช่วยป้องกันความเสียหายได้มากกว่าข้ออื่น

ลองดู find /var/log -name '*.gz' -mtime +7 -delete คำตอบที่ดีจะบอกคุณว่า -mtime +7 จะนับช่วงเวลา 24 ชั่วโมงเต็มและตัดเศษทิ้ง ดังนั้นมันจึงจับคู่ไฟล์ที่มีอายุอย่างน้อยแปดวันแทนที่จะเป็นเจ็ดวัน นอกจากนี้ยังบอกด้วยว่า find จะประเมินนิพจน์จากซ้ายไปขวา ดังนั้นการย้าย -delete ไปไว้หน้า -name จะลบทุกอย่างภายใต้ path เริ่มต้น ประเด็นที่สองนี้ระบุไว้ในหน้า man page ของ find ในฐานะคำเตือน และมันเคยสร้างความเสียหายให้กับ /var/log ของผู้ใช้งานมาแล้ว

หรือลองดู rsync -a --delete /srv/app/ /backup/app/ เครื่องหมาย slash ปิดท้ายที่ source หมายถึง "เนื้อหาภายในไดเรกทอรีนี้" หากตัดออก คุณจะได้ /backup/app/app/ หากเพิ่ม --delete สิ่งใดก็ตามในปลายทางที่ไม่มีอยู่ในต้นทางจะถูกลบออก ซึ่งถูกต้องสำหรับการทำ mirror แต่จะเป็นหายนะหากระบุ path ต้นทางผิด

ตรวจสอบด้วยเครื่องมือ ไม่ใช่ด้วยโมเดล:

rsync -a --delete --dry-run /srv/app/ /backup/app/ | head -20
find /var/log -name '*.gz' -mtime +7

รัน find โดยไม่มี -delete แล้วคุณจะได้รายการผลลัพธ์แทนที่จะเป็นการสูญเสียข้อมูล

โหมดความล้มเหลว: การสร้าง flag ขึ้นมาเอง (hallucination) โมเดลมีความน่าเชื่อถือสูงกับเครื่องมือที่มีเอกสารประกอบมานานกว่าสามสิบปี แต่จะอ่อนกว่ามากกับ CLI (command line interface) ของผู้จำหน่ายและคำสั่งย่อยที่เพิ่งออกมาใหม่ ซึ่งโมเดลมักจะสร้าง flag ที่อ่านดูสมเหตุสมผลแต่ไม่มีอยู่จริง --help สามารถตรวจสอบเรื่องนี้ได้ในหนึ่งวินาที การใส่เครื่องหมายคำพูด (quoting) เป็นอีกจุดที่ผิดพลาดได้ง่าย ดังนั้นเมื่อคำสั่งมีการครอบนิพจน์ $(...) ให้ศึกษา วิธีที่ command substitution ขยายตัวก่อนที่คำสั่งจะทำงาน แทนที่จะเชื่อคำอธิบายเพียงอย่างเดียว

งานที่ 5: เปลี่ยนประวัติการใช้งาน shell ของคุณให้เป็นคู่มือการปฏิบัติงาน (runbook)

คุณเพิ่งใช้เวลาสองชั่วโมงในการทำให้บางอย่างทำงานได้ ความรู้นั้นอยู่ในหน้าต่าง terminal ของคุณและมันจะหายไปในเดือนหน้า

history 200 > /tmp/session.txt

อ่านไฟล์นั้นและลบทุกบรรทัดที่มีรหัสผ่าน, token หรือข้อมูลระบุตัวตนของลูกค้าออกก่อนที่จะนำไปใช้ที่อื่น ประวัติการใช้งาน shell เป็นหนึ่งในแหล่งที่เชื่อถือได้มากที่สุดในการค้นหาความลับบนเครื่อง Linux เพราะทุกคนมักจะเผลอพิมพ์ข้อมูลเหล่านี้ลงไปอย่างน้อยหนึ่งครั้ง ให้ตั้งค่า HISTCONTROL=ignorespace ใน ~/.bashrc ของคุณ แล้วคำสั่งที่พิมพ์โดยเว้นวรรคหน้าคำสั่งจะไม่ถูกบันทึกลงในประวัติการใช้งานเลย

คำสั่ง (prompt) ที่จะสร้าง runbook ที่ใช้งานได้จริงต้องขอให้มีการตรวจสอบ ไม่ใช่แค่ขั้นตอนการทำงาน:

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

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

งานที่ 6: เปลี่ยนข้อความแสดงข้อผิดพลาดให้เป็นวิธีแก้ไข

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

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use). จัดลำดับสาเหตุที่เป็นไปได้และให้คำสั่ง 1 คำสั่งต่อสาเหตุเพื่อยืนยันหรือตัดประเด็นนั้นออก

สำหรับข้อผิดพลาดนั้น กลไกของมันไม่มีความคลุมเครือ: มีกระบวนการอื่นถือครองพอร์ต 80 อยู่แล้ว และ sudo ss -tulpn | grep ':80 ' จะระบุชื่อกระบวนการนั้น บ่อยครั้งที่มันเป็นกระบวนการ Nginx master ตัวที่สองที่ค้างอยู่จากการโหลดซ้ำ (reload) ที่ล้มเหลว หรือเป็น Apache ที่ถูกดึงเข้ามาเป็น dependency และถูกเริ่มทำงานโดยแพ็กเกจของมันเอง

รูปแบบความล้มเหลว: วิธีแก้ไขที่ได้ผลโดยการซ่อนสาเหตุที่แท้จริง การใช้ chmod 777, --privileged, การปิดใช้งาน SELinux และการรัน service ในฐานะ root ล้วนทำให้ข้อผิดพลาดหายไป ให้ปฏิเสธวิธีแก้ไขใดๆ ที่เป็นการขยายสิทธิ์จนกว่าโมเดลจะอธิบายได้ว่าเหตุใดสิทธิ์ที่จำกัดจึงใช้งานไม่ได้ คำอธิบายนั้นคือคำตอบที่แท้จริง ส่วนวิธีแก้ปัญหาชั่วคราว (workaround) เพียงแค่ทำให้ข้อผิดพลาดเงียบลงเท่านั้น

สิ่งที่ระบบมักเข้าใจผิดอย่างสม่ำเสมอ

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

ปัญหาข้อสุดท้ายนี้เป็นปัญหาด้านการทำงานมากกว่าปัญหาของตัวโมเดล โดยมีวิธีแก้ไขในทางปฏิบัติคือ การจัดการบริบทในการใช้งาน Claude Code ระยะยาว ได้แก่ การแบ่งเซสชันให้สั้นลงและทำทีละงาน

การติดตั้ง agent ลงบนเซิร์ฟเวอร์โดยตรง

เนื้อหาทั้งหมดข้างต้นเป็นการคัดลอกและวาง ดังนั้นโมเดลจะไม่เข้าถึงเครื่องของคุณโดยตรง เมื่อใดก็ตามที่มันเริ่มทำงานบนเครื่อง อ่านไฟล์ และรันคำสั่ง รูปแบบของความเสี่ยงจะเปลี่ยนไป: คำสั่งที่ผิดพลาดอาจทำให้บริการของคุณเสียหายได้ ควรสร้างผู้ใช้ที่ไม่มีสิทธิ์ระดับ root ให้กับมัน ทดสอบการใช้งานนอกเครื่อง production จนกว่าจะเข้าใจพฤติกรรมของมัน และทำ snapshot ไว้ก่อนเสมอ การรัน Claude Code อย่างปลอดภัยบน VPS ครอบคลุมเรื่องการทำ sandboxing และโมเดลการจัดการสิทธิ์ การใช้งาน Claude Code ภายใน tmux ช่วยแก้ปัญหาอีกด้าน เนื่องจากหากเซสชัน SSH (secure shell) หลุด จะทำให้ agent ที่ทำงานอยู่เบื้องหน้าหยุดชะงักกลางคัน ให้สร้างบัญชีผู้ใช้ตามมาตรฐานเดียวกับการสร้าง service account ทั่วไป ซึ่ง ผู้ใช้ที่มีสิทธิ์น้อยที่สุดบน VPS ได้อธิบายรายละเอียดไว้แล้ว

FAQ

Claude สามารถอ่าน log ของเซิร์ฟเวอร์โดยตรงได้หรือไม่?

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

สิ่งใดที่ไม่ควรคัดลอกมาจากเซิร์ฟเวอร์เด็ดขาด?

Private keys, ไฟล์ .env และที่เก็บข้อมูล credential อื่นๆ, /etc/shadow รวมถึงข้อมูลใดๆ ที่เป็นของผู้ใช้ของคุณ ให้ปกปิด token ออกจากข้อความ log ก่อนที่จะส่งเข้าสู่ prompt กรณีหนึ่งที่ไม่ชัดเจนนักคือ ผลลัพธ์ของ docker compose config จะมีการแทรกค่า .env ของคุณลงไป ดังนั้นให้ใช้ docker compose config -q แทน ซึ่งจะตรวจสอบความถูกต้องของไฟล์โดยไม่แสดงผลลัพธ์ใดๆ ออกมา

การให้ Claude รันคำสั่งบน VPS ที่ใช้งานจริงปลอดภัยหรือไม่?

ให้ปฏิบัติกับมันเหมือนผู้ดูแลระบบคนใหม่ที่ไม่มีบริบท: ปลอดภัยสำหรับการอ่าน แต่ต้องมีการตรวจสอบก่อนสำหรับการเขียน ในระบบที่ใช้งานจริง ให้ขอคำอธิบายแล้วรันคำสั่งด้วยตัวคุณเอง หากคุณต้องการให้ agent เป็นผู้ดำเนินการ ให้สร้างบัญชีผู้ใช้ที่ไม่มีสิทธิ์พิเศษโดยเฉพาะโดยไม่ให้สิทธิ์ sudo แบบครอบคลุม และเริ่มต้นบน staging box ซึ่งหากเกิดข้อผิดพลาด คุณเพียงแค่สร้างระบบใหม่แทนที่จะเกิดเหตุการณ์ระบบล่ม

ทำไม Claude ถึงแนะนำ flag ที่ไม่มีอยู่จริง?

เพราะมันคาดการณ์ข้อความที่ดูสมเหตุสมผล และ flag ที่ดูสมเหตุสมผลก็มีลักษณะเหมือนกับ flag จริง เหตุการณ์นี้มักเกิดขึ้นกับ CLI ของผู้จำหน่ายและคำสั่งย่อยใหม่ๆ ซึ่งเอกสารประกอบเบื้องหลังโมเดลมีข้อมูลน้อยหรือมีการเปลี่ยนแปลงไปแล้ว --help และ man คือผู้ตัดสิน และคำสั่งใดก็ตามที่ลบหรือเขียนทับข้อมูลควรได้รับการทดสอบด้วยการรันแบบ dry run ก่อนเสมอ

ฉันจะตรวจสอบ systemd unit ก่อนเปิดใช้งานได้อย่างไร?

ให้รัน sudo systemd-analyze verify /etc/systemd/system/myapp.service มันจะวิเคราะห์ไฟล์ด้วยตัววิเคราะห์ของ systemd เอง โดยจะรายงานคำสั่งที่ไม่รู้จักพร้อมระบุหมายเลขบรรทัด และแจ้งเตือนหากไฟล์ไบนารี ExecStart หายไปหรือไม่สามารถเรียกใช้งานได้ จากนั้นให้รัน daemon-reload, start และอ่าน systemctl status ก่อนที่คุณจะ enable เพราะ unit ที่โหลดได้อย่างราบรื่นอาจยังคงล้มเหลวในการรันครั้งแรกได้