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

ให้สิทธิ์ไฟล์แบบละเอียดด้วย ACL (setfacl และ getfacl)
Home ให้สิทธิ์ไฟล์แบบละเอียดด้วย ACL (setfacl และ getfacl)

ให้สิทธิ์ไฟล์แบบละเอียดด้วย ACL (setfacl และ getfacl)

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

ทางแก้ที่หลายคนใช้คือ chmod 777 ซึ่งเปิดให้ทุกคนในเครื่องเขียนได้และเป็นช่องโหว่ที่ถูกใช้โจมตีบ่อย ACL คือทางแก้ที่ถูกต้อง คู่มือนี้ใช้กรณีจริงของเว็บเซิร์ฟเวอร์เป็นตัวอย่าง

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

  • Linux Server และสิทธิ์ sudo
  • ระบบไฟล์ที่รองรับ ACL ซึ่ง ext4 และ xfs รองรับอยู่แล้วโดยค่าเริ่มต้น
# Ubuntu / Debian
sudo apt install -y acl

# AlmaLinux / Rocky Linux
sudo dnf install -y acl

ตรวจว่าระบบไฟล์เปิด ACL อยู่

mount | grep ' / '
sudo tune2fs -l /dev/sda1 | grep 'Default mount options'

ถ้าเห็นคำว่า acl แปลว่าใช้ได้เลย เกือบทุกดิสทริบิวชันสมัยใหม่เปิดไว้ให้แล้ว

ขั้นตอนที่ 1: ดูสิทธิ์ที่มีอยู่

ls -l /var/www/example.com
getfacl /var/www/example.com

ผลของ getfacl จะแสดงบรรทัด user::, group:: และ other:: ซึ่งตรงกับสิทธิ์แบบเดิม หากมี ACL เพิ่มเติมจะเห็นบรรทัดที่ระบุชื่อผู้ใช้ เช่น user:deploy:rwx

สังเกตจาก ls -l ได้เช่นกัน ถ้ามีเครื่องหมาย + ต่อท้ายสิทธิ์ แปลว่าไฟล์นั้นมี ACL อยู่

ขั้นตอนที่ 2: กรณีใช้งานจริง — เว็บเซิร์ฟเวอร์กับผู้ใช้ Deploy

สถานการณ์ที่พบบ่อยที่สุด ไฟล์เว็บอยู่ที่ /var/www/example.com โดยมีเงื่อนไข

  • ผู้ใช้ deploy ต้องอัปโหลดและแก้ไฟล์ได้
  • ผู้ใช้ www-data (Nginx/PHP-FPM) ต้องอ่านได้ และเขียนได้เฉพาะโฟลเดอร์อัปโหลด
  • ผู้ใช้อื่นในเครื่องไม่ควรเห็นอะไรเลย

เริ่มจากตั้งสิทธิ์พื้นฐานให้แน่นก่อน

sudo chown -R deploy:deploy /var/www/example.com
sudo chmod -R 750 /var/www/example.com
sudo find /var/www/example.com -type f -exec chmod 640 {} \;

ตอนนี้ www-data ยังเข้าไม่ได้ ให้สิทธิ์อ่านด้วย ACL

sudo setfacl -R -m u:www-data:rX /var/www/example.com

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

ขั้นตอนที่ 3: ให้สิทธิ์เขียนเฉพาะโฟลเดอร์ที่จำเป็น

sudo setfacl -R -m u:www-data:rwX /var/www/example.com/storage
sudo setfacl -R -m u:www-data:rwX /var/www/example.com/public/uploads

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

ขั้นตอนที่ 4: ตั้ง Default ACL ให้ไฟล์ใหม่สืบทอดสิทธิ์

นี่คือจุดที่ ACL มีค่าที่สุด ไฟล์ที่สร้างใหม่ในอนาคตจะได้สิทธิ์ตามที่กำหนดไว้โดยอัตโนมัติ ไม่ต้องมาไล่ตั้งใหม่ทุกครั้งที่ Deploy

sudo setfacl -R -d -m u:www-data:rX /var/www/example.com
sudo setfacl -R -d -m u:deploy:rwX /var/www/example.com
sudo setfacl -R -d -m u:www-data:rwX /var/www/example.com/storage

ตัวเลือก -d คือ default ซึ่งมีผลกับไดเรกทอรีเท่านั้นและใช้กับไฟล์ที่สร้างขึ้นใหม่ภายในเท่านั้น ไฟล์ที่มีอยู่แล้วไม่เปลี่ยน จึงต้องสั่งทั้งสองแบบคู่กันเสมอ

ตรวจผล

getfacl /var/www/example.com

บรรทัดที่ขึ้นต้นด้วย default: คือสิทธิ์ที่จะสืบทอด ทดสอบด้วยการสร้างไฟล์ใหม่

sudo -u deploy touch /var/www/example.com/test.txt
getfacl /var/www/example.com/test.txt
sudo rm /var/www/example.com/test.txt

ขั้นตอนที่ 5: ให้สิทธิ์รายกลุ่ม

sudo groupadd developers
sudo usermod -aG developers somchai
sudo setfacl -R -m g:developers:rX /var/www/example.com
sudo setfacl -R -d -m g:developers:rX /var/www/example.com

การใช้กลุ่มดูแลง่ายกว่าการใส่รายชื่อผู้ใช้ทีละคน เมื่อมีคนเข้าใหม่หรือลาออก แก้ที่สมาชิกกลุ่มจุดเดียว

ขั้นตอนที่ 6: ลบและล้าง ACL

# ลบสิทธิ์ของผู้ใช้หนึ่งคน
sudo setfacl -x u:www-data /var/www/example.com

# ลบ Default ACL ทั้งหมดของไดเรกทอรี
sudo setfacl -k /var/www/example.com

# ล้าง ACL ทั้งหมด กลับไปใช้สิทธิ์แบบเดิม
sudo setfacl -b -R /var/www/example.com

ขั้นตอนที่ 7: สำรองและกู้คืน ACL

คำสั่ง cp และ tar แบบปกติไม่เก็บ ACL ไปด้วย ให้สำรองแยกไว้

sudo getfacl -R /var/www/example.com > /root/acl-backup.txt
sudo setfacl --restore=/root/acl-backup.txt

หากคัดลอกไฟล์ ให้ใช้ตัวเลือกที่รักษา ACL ไว้

sudo cp -a /var/www/example.com /var/www/backup
sudo rsync -aAX /var/www/example.com/ /var/www/backup/
sudo tar --acls -czf site.tar.gz /var/www/example.com

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

ตั้ง ACL แล้วแต่ Nginx ยังขึ้น 403

สิทธิ์ต้องเปิดตลอดเส้นทางของไดเรกทอรี ตั้งแต่ /var, /var/www ไปจนถึงโฟลเดอร์ปลายทาง ตรวจได้ด้วย namei -l /var/www/example.com/index.php ซึ่งจะแสดงสิทธิ์ทุกชั้นในบรรทัดเดียว

สิทธิ์หายหลัง Deploy

เครื่องมือ Deploy บางตัวสร้างโฟลเดอร์ใหม่ทั้งชุดแล้วสลับลิงก์ ทำให้ Default ACL ของโฟลเดอร์เดิมไม่ถูกใช้ ให้ตั้ง Default ACL ที่โฟลเดอร์แม่ซึ่งไม่ถูกสร้างใหม่ หรือสั่ง setfacl เป็นขั้นตอนสุดท้ายของการ Deploy

getfacl แสดง mask ที่ตัดสิทธิ์ลง

บรรทัด mask:: คือเพดานสูงสุดของสิทธิ์ที่ ACL ให้ได้ หากคุณสั่ง chmod ทีหลัง mask จะถูกคำนวณใหม่และอาจตัดสิทธิ์ที่ตั้งไว้ ให้สั่ง setfacl หลัง chmod เสมอ หรือกำหนด mask ตรง ๆ ด้วย setfacl -m m::rwx

ไฟล์ใหม่ยังไม่ได้สิทธิ์ที่ตั้งไว้

ตรวจว่าตั้ง Default ACL ด้วยตัวเลือก -d แล้วหรือยัง และ Default ACL มีผลกับไฟล์ที่สร้างหลังจากตั้งเท่านั้น ไฟล์เดิมต้องสั่งแยกโดยไม่ใส่ -d

หากต้องการให้ทีมงานช่วยวางโครงสร้างสิทธิ์ให้ระบบของคุณ ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

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

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