ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

Home ทำความเข้าใจสิทธิ์ไฟล์บน Linux ด้วย chmod และ chown

ทำความเข้าใจสิทธิ์ไฟล์บน Linux ด้วย chmod และ chown

ทุกไฟล์และโฟลเดอร์บน Linux มีเจ้าของ (User) กลุ่ม (Group) และชุดสิทธิ์ที่กำหนดว่าใครอ่าน เขียน หรือรันได้ ปัญหาหน้าเว็บขึ้น 403 Forbidden, WordPress อัปโหลดรูปไม่ได้ หรือ SSH Key ใช้ไม่ได้ ส่วนใหญ่มีต้นเหตุจากสิทธิ์ไฟล์ที่ไม่ถูกต้อง บทความนี้อธิบายวิธีอ่านสิทธิ์และวิธีแก้ด้วย chmod และ chown อย่างปลอดภัย

สิ่งที่ต้องเตรียม

  • เซิร์ฟเวอร์ Ubuntu 22.04/24.04 หรือ AlmaLinux/Rocky Linux 8-9 ที่เข้าผ่าน SSH ได้
  • ผู้ใช้ที่มีสิทธิ์ sudo (การเปลี่ยนเจ้าของไฟล์ต้องใช้สิทธิ์ root)
  • รู้ว่า Web Server ของเครื่องรันด้วยผู้ใช้อะไร: Ubuntu มักเป็น www-data ส่วน AlmaLinux/Rocky เป็น apache หรือ nginx

ขั้นตอนที่ 1: อ่านสิทธิ์จากคำสั่ง ls -l

ls -l /var/www/example.com

ผลลัพธ์จะมีลักษณะดังนี้

-rw-r--r-- 1 deploy www-data  4120 Sep 10 10:12 index.php
drwxr-xr-x 5 deploy www-data  4096 Sep 10 10:12 wp-content

ตัวอักษรตัวแรกบอกชนิด (- คือไฟล์ d คือโฟลเดอร์ l คือ Symbolic Link) จากนั้นเป็น 9 ตัวอักษรแบ่งเป็น 3 ชุด ชุดละ 3 ตัว คือสิทธิ์ของเจ้าของ (u) กลุ่ม (g) และคนอื่น (o) ตามลำดับ ถัดมาคือชื่อเจ้าของ (deploy) และกลุ่ม (www-data)

ตัวอักษรกับไฟล์กับโฟลเดอร์ค่าตัวเลข
rอ่านเนื้อหาได้ดูรายชื่อไฟล์ข้างในได้4
wแก้ไขเนื้อหาได้สร้าง ลบ เปลี่ยนชื่อไฟล์ข้างในได้2
xรันเป็นโปรแกรมได้เข้าไปในโฟลเดอร์ (cd) และเข้าถึงไฟล์ข้างในได้1

จุดที่คนมักพลาดคือสิทธิ์ x ของโฟลเดอร์ ถ้าโฟลเดอร์ไม่มี x แม้ไฟล์ข้างในจะอ่านได้ Web Server ก็เข้าไม่ถึง และสิทธิ์ลบไฟล์ขึ้นกับสิทธิ์ w ของโฟลเดอร์ที่เก็บไฟล์ ไม่ใช่ของตัวไฟล์

ขั้นตอนที่ 2: แปลงสิทธิ์เป็นตัวเลข

นำค่าตัวเลขของแต่ละชุดมาบวกกัน เช่น rw- คือ 4+2+0 = 6 และ r-x คือ 4+0+1 = 5 ดังนั้น rw-r--r-- คือ 644 และ rwxr-xr-x คือ 755 ค่าที่พบบ่อยมีดังนี้

ค่าสัญลักษณ์ใช้กับ
644rw-r--r--ไฟล์เว็บทั่วไป (PHP, HTML, CSS, รูป)
755rwxr-xr-xโฟลเดอร์ และสคริปต์ที่ต้องรันได้
640rw-r-----ไฟล์ Config ที่มีรหัสผ่าน ให้กลุ่มของ Web Server อ่านได้เท่านั้น
600rw-------Private Key, ~/.ssh/authorized_keys, ไฟล์ .env ที่เจ้าของอ่านคนเดียว
700rwx------โฟลเดอร์ ~/.ssh และโฟลเดอร์ส่วนตัว
775rwxrwxr-xโฟลเดอร์ที่ทั้งเจ้าของและกลุ่มต้องเขียนได้ เช่น โฟลเดอร์อัปโหลด

ขั้นตอนที่ 3: เปลี่ยนสิทธิ์ด้วย chmod

ใช้ได้ทั้งแบบตัวเลขและแบบสัญลักษณ์

chmod 644 index.php
chmod 600 ~/.ssh/authorized_keys
chmod u+x deploy.sh
chmod g+w uploads
chmod o-rwx config.php

แบบสัญลักษณ์ใช้ u, g, o, a (ทั้งหมด) ตามด้วย + เพิ่ม - ลบ หรือ = กำหนดทับ เหมาะเมื่อต้องการเปลี่ยนเพียงบิตเดียวโดยไม่กระทบส่วนอื่น

เมื่อต้องแก้ทั้งเว็บไซต์ อย่าใช้ chmod -R 755 เพราะจะทำให้ไฟล์ทุกไฟล์รันได้ด้วย ให้แยกไฟล์กับโฟลเดอร์ด้วย find

sudo find /var/www/example.com -type d -exec chmod 755 {} +
sudo find /var/www/example.com -type f -exec chmod 644 {} +

ขั้นตอนที่ 4: เปลี่ยนเจ้าของด้วย chown

sudo chown deploy index.php
sudo chown deploy:www-data index.php
sudo chown -R deploy:www-data /var/www/example.com
sudo chgrp www-data config.php

รูปแบบคือ ผู้ใช้:กลุ่ม และ -R ทำทั้งโฟลเดอร์ ก่อนใช้ -R ให้ตรวจ Path ให้แน่ใจ เพราะการรัน chown -R กับ / หรือ /var ผิดพลาดอาจทำให้ Service หลายตัวเสียและต้องกู้ระบบ ควรมีข้อมูลสำรองก่อน (ดู การ Backup Server บน Cloud ของ TDC)

ขั้นตอนที่ 5: ตัวอย่างการตั้งสิทธิ์เว็บไซต์ WordPress บน Nginx หรือ Apache

แนวทางที่นิยมคือให้ผู้ใช้ Deploy เป็นเจ้าของไฟล์ และให้ Web Server อยู่ในกลุ่ม โดยเขียนได้เฉพาะโฟลเดอร์ที่จำเป็น สมมติเว็บอยู่ที่ /var/www/example.com บน Ubuntu

sudo chown -R deploy:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} +
sudo find /var/www/example.com -type f -exec chmod 644 {} +
sudo chmod -R g+w /var/www/example.com/wp-content/uploads
sudo chmod 640 /var/www/example.com/wp-config.php

บน AlmaLinux/Rocky ให้เปลี่ยน www-data เป็นผู้ใช้ที่ PHP-FPM รันอยู่ ตรวจได้จากบรรทัด user = และ group = ในไฟล์ /etc/php-fpm.d/www.conf นอกจากนี้ SELinux ต้องมี Context ที่ถูกต้องด้วย ดู ใช้งาน SELinux บน AlmaLinux และ Rocky Linux โดยไม่ต้องปิด

หมายเหตุ: บนเซิร์ฟเวอร์ที่ใช้ Plesk หรือ DirectAdmin แผงควบคุมจะกำหนดเจ้าของไฟล์ของแต่ละเว็บไซต์ให้เอง (เช่น ผู้ใช้ระบบของ Subscription) ไม่ควรเปลี่ยนเจ้าของไฟล์เป็น www-data หรือ root ด้วยมือ ถ้าสิทธิ์เพี้ยนให้ใช้เครื่องมือของแผงควบคุมหรือแจ้งผู้ดูแลระบบ

ทำไมไม่ควรใช้ 777

777 ให้ทุกผู้ใช้บนเครื่องเขียนไฟล์ได้ ถ้าปลั๊กอินตัวใดตัวหนึ่งมีช่องโหว่ ผู้โจมตีจะเขียนไฟล์ PHP อันตรายลงไปได้ทันที และ Web Server บางตั้งค่า เช่น suEXEC หรือ PHP-FPM ที่ตรวจสิทธิ์ จะปฏิเสธการรันไฟล์ที่ใครก็เขียนได้ จนเกิด Error 500 ถ้าเว็บทำงานได้เฉพาะเมื่อตั้ง 777 แปลว่าเจ้าของหรือกลุ่มยังไม่ถูกต้อง ให้แก้ที่ chown แทน

umask และสิทธิ์พิเศษที่ควรรู้จัก

umask กำหนดสิทธิ์เริ่มต้นของไฟล์ใหม่ ค่า 022 ทำให้ไฟล์ใหม่ได้ 644 และโฟลเดอร์ใหม่ได้ 755 ดูค่าปัจจุบันด้วยคำสั่ง umask ส่วนสิทธิ์พิเศษที่อาจเห็นในผลของ ls -l มีดังนี้

  • setgid บนโฟลเดอร์ (chmod g+s dir แสดงเป็น s ในชุดกลุ่ม): ไฟล์ใหม่ในโฟลเดอร์จะได้กลุ่มเดียวกับโฟลเดอร์ เหมาะกับโฟลเดอร์ที่หลายคนทำงานร่วมกัน
  • sticky bit (t ท้ายสุด เช่น /tmp เป็น drwxrwxrwt): ทุกคนสร้างไฟล์ได้ แต่ลบได้เฉพาะไฟล์ของตัวเอง
  • setuid บนไฟล์โปรแกรม: รันด้วยสิทธิ์ของเจ้าของไฟล์ ไม่ควรตั้งเองกับสคริปต์ใด ๆ

ตรวจสอบผลลัพธ์

ls -l /var/www/example.com
stat -c '%A %a %U:%G %n' /var/www/example.com/wp-config.php
sudo -u www-data test -r /var/www/example.com/index.php && echo "readable"

stat แสดงทั้งสัญลักษณ์และตัวเลข เช่น -rw-r----- 640 deploy:www-data ส่วนคำสั่งสุดท้ายทดสอบว่าผู้ใช้ www-data อ่านไฟล์ได้จริงหรือไม่ ถ้าอ่านได้จะพิมพ์ readable จากนั้นทดสอบเปิดเว็บและอัปโหลดรูปใน WordPress

ปัญหาที่พบบ่อย

เว็บขึ้น 403 Forbidden

ตรวจว่าโฟลเดอร์ทุกระดับตั้งแต่ /var/www ลงมามีสิทธิ์ x สำหรับ Web Server ใช้คำสั่ง namei -l /var/www/example.com/index.php เพื่อดูสิทธิ์ทุกชั้นของ Path ในคำสั่งเดียว บน AlmaLinux/Rocky ถ้าสิทธิ์ถูกแล้วยังขึ้น 403 ให้ตรวจ SELinux

WordPress ขอ FTP Credentials ตอนอัปเดตปลั๊กอิน

แปลว่า PHP เขียนไฟล์ในโฟลเดอร์เว็บไม่ได้ ให้ตรวจว่าผู้ใช้ที่ PHP-FPM รันอยู่มีสิทธิ์เขียน wp-content หรือพิจารณาอัปเดตด้วย WP-CLI ในนามผู้ใช้เจ้าของไฟล์

SSH Key ถูกปฏิเสธทั้งที่ Key ถูกต้อง

OpenSSH ไม่ยอมใช้ Key ถ้าสิทธิ์หลวมเกินไป ให้ตั้ง chmod 700 ~/.ssh และ chmod 600 ~/.ssh/authorized_keys และโฮมโฟลเดอร์ต้องไม่ให้กลุ่มหรือคนอื่นเขียนได้

chown: invalid user

ชื่อผู้ใช้หรือกลุ่มไม่มีในเครื่อง ตรวจด้วย id www-data หรือ getent group nginx เพราะชื่อผู้ใช้ของ Web Server ต่างกันตาม Distribution

หากทำตามขั้นตอนแล้วยังติดปัญหา สามารถติดต่อทีมงาน THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/ โดยแจ้งชื่อเซิร์ฟเวอร์ ระบบปฏิบัติการ คำสั่งที่ใช้ และข้อความ Error ที่พบ เพื่อให้ตรวจสอบได้รวดเร็วขึ้น

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security