SELinux คืออะไร ใช้งานอย่างไรไม่ให้ปวดหัว

SELinux คืออะไร ใช้งานอย่างไรไม่ให้ปวดหัว

เคยเจอ Permission Denied ทั้งที่ chmod ถูกต้องไหม

สำหรับผู้ดูแลระบบ Linux โดยเฉพาะสาย Rocky Linux, RHEL, AlmaLinux หรือ CentOS เดิม หลายคนคงเคยเจอเหตุการณ์แบบนี้

ตั้งค่า Apache ถูกแล้ว
กำหนด permission ถูกแล้ว
owner ก็ถูกแล้ว
แต่เว็บยังเปิดไม่ได้ หรือ application ยังเขียนไฟล์ไม่ได้

พอค้นไปค้นมาเจอคำแนะนำยอดนิยมว่า

sudo setenforce 0

หรือหนักกว่านั้นคือแก้ไฟล์ config เพื่อปิด SELinux ถาวร

ปัญหาคือ วิธีนี้อาจทำให้ระบบ “ใช้งานได้” จริง แต่เป็นการลดชั้นความปลอดภัยสำคัญของ Linux Server ลงทันที บทความนี้จะพาเข้าใจ SELinux แบบไม่ปวดหัว พร้อมแนวทางแก้ปัญหาแบบ SysAdmin ใช้งานจริง โดยไม่ต้องปิด SELinux เป็นคำตอบแรก


บทความนี้เหมาะสำหรับผู้เริ่มต้นถึงระดับกลางที่ดูแล Linux Server และต้องการเข้าใจ SELinux ให้ใช้งานได้จริง ไม่ใช่แค่ท่องจำคำสั่ง

เราจะเรียนรู้เรื่องสำคัญต่อไปนี้

  • SELinux คืออะไร และต่างจาก permission ปกติอย่างไร

  • โหมด Enforcing, Permissive, Disabled ต่างกันอย่างไร

  • วิธีตรวจสอบสถานะ SELinux

  • วิธีดู SELinux context ของไฟล์และ process

  • วิธีแก้ปัญหาเว็บหรือ service ถูก SELinux block

  • วิธีใช้ semanage, restorecon, setsebool, ausearch

  • แนวทาง Troubleshooting แบบไม่ต้องปิด SELinux ถาวร

ทดสอบแนวทางคำสั่งบน Rocky Linux 9/10 และใช้ได้กับระบบตระกูล RHEL-compatible เป็นหลัก


พื้นฐานที่จำเป็นก่อนเริ่ม

ก่อนทำตามบทความนี้ ควรมีพื้นฐานดังนี้

  • ใช้งาน command line บน Linux ได้

  • มีสิทธิ์ sudo

  • ใช้ Rocky Linux, RHEL, AlmaLinux หรือ CentOS Stream

  • เข้าใจ Linux permission เบื้องต้น เช่น chmod, chown, ls -l

  • มี service สำหรับทดลอง เช่น Apache HTTP Server หรือ Nginx

ติดตั้งเครื่องมือที่จำเป็นก่อน

sudo dnf install -y policycoreutils-python-utils setroubleshoot-server audit

คำอธิบาย:

  • policycoreutils-python-utils มีคำสั่งสำคัญ เช่น semanage

  • setroubleshoot-server ช่วยวิเคราะห์ SELinux denial

  • audit ใช้บันทึกเหตุการณ์ด้าน security รวมถึง SELinux block

เปิดใช้งาน audit service

sudo systemctl enable --now auditd

ตรวจสอบสถานะ

sudo systemctl status auditd

SELinux คืออะไร

SELinux ย่อมาจาก Security-Enhanced Linux เป็นระบบควบคุมสิทธิ์แบบ Mandatory Access Control หรือ MAC

ถ้าจะอธิบายให้ง่าย Linux permission ปกติ เช่น owner, group, mode 755, 644 เป็นระบบที่เรียกว่า Discretionary Access Control หรือ DAC หมายความว่าเจ้าของไฟล์มีอำนาจกำหนดสิทธิ์ไฟล์ของตัวเองได้

แต่ SELinux ทำงานอีกชั้นหนึ่ง โดยมี policy กลางของระบบคอยตัดสินว่า process ไหนสามารถเข้าถึง file, directory, port หรือ resource อะไรได้บ้าง

ตัวอย่างเช่น

  • Apache process อาจมี domain เป็น httpd_t

  • ไฟล์เว็บปกติควรมี type เป็น httpd_sys_content_t

  • ไดเรกทอรีที่เว็บต้องเขียนไฟล์ได้ อาจต้องใช้ type เป็น httpd_sys_rw_content_t

ดังนั้น แม้ Linux permission จะอนุญาตแล้ว แต่ถ้า SELinux policy ไม่อนุญาต ระบบก็ยัง block ได้

นี่คือเหตุผลที่บางครั้งเราเจอปัญหา

Permission denied

ทั้งที่ chmod และ chown ดูเหมือนถูกต้องแล้ว


ทำไม SELinux ถึงมีประโยชน์

ให้จินตนาการว่าเว็บเซิร์ฟเวอร์ถูกโจมตีผ่านช่องโหว่ของ web application ถ้าไม่มี SELinux ผู้โจมตีอาจใช้สิทธิ์ของ process นั้นอ่านไฟล์อื่นในระบบ หรือเข้าถึง path ที่ไม่ควรแตะต้องได้ง่ายขึ้น

แต่ถ้าเปิด SELinux ในโหมด Enforcing ต่อให้ process ถูกเจาะได้ การเคลื่อนไหวของ process จะยังถูกจำกัดด้วย policy

พูดง่าย ๆ คือ SELinux ช่วย “กักบริเวณ” service ไม่ให้ทำเกินหน้าที่ของตัวเอง

ตัวอย่างแนวคิด:

  • Apache ควรอ่านไฟล์เว็บ ไม่ควรอ่านไฟล์ส่วนตัวของ user

  • Database ควรเขียนใน directory ของ database ไม่ควรเขียนมั่วทั้งระบบ

  • Service ที่ไม่ได้รับอนุญาต ไม่ควร bind port บางประเภท

  • Container หรือ daemon ควรถูกจำกัดขอบเขตการเข้าถึง resource

ดังนั้น SELinux ไม่ใช่ตัวปัญหา แต่เป็น security guard ที่เข้มงวดมาก ถ้าเราเข้าใจกฎของเขา การดูแลระบบจะปลอดภัยขึ้นมาก


โหมดของ SELinux

SELinux มีโหมดสำคัญที่ผู้ดูแลระบบต้องรู้

1. Enforcing

เป็นโหมดที่ SELinux ทำงานเต็มรูปแบบ ถ้า policy ไม่อนุญาต ระบบจะ block ทันที

ตรวจสอบได้ด้วยคำสั่ง

getenforce

ถ้าผลลัพธ์เป็นแบบนี้ แปลว่า SELinux กำลังบังคับใช้นโยบายจริง

Enforcing

โหมดนี้เหมาะกับ production server

2. Permissive

โหมดนี้ SELinux จะไม่ block การทำงานจริง แต่จะบันทึก log ว่า “ถ้าเป็น Enforcing จะถูก block”

เหมาะสำหรับใช้วิเคราะห์ปัญหาชั่วคราว เช่น เพิ่งติดตั้ง application ใหม่ แล้วต้องการดูว่า SELinux จะ block อะไรบ้าง

เปลี่ยนเป็น Permissive ชั่วคราว

sudo setenforce 0

กลับเป็น Enforcing

sudo setenforce 1

ตรวจสอบอีกครั้ง

getenforce

⚠️ คำสั่ง setenforce มีผลชั่วคราวเท่านั้น เมื่อ reboot ค่าอาจกลับไปตาม config เดิม

3. Disabled

เป็นการปิด SELinux ไม่ให้โหลด policy

ไม่แนะนำให้ใช้ในงาน production เพราะนอกจากระบบจะเสียชั้นป้องกันสำคัญแล้ว ยังอาจทำให้ไฟล์ใหม่ไม่มี label ที่ถูกต้อง เมื่อต้องการเปิด SELinux กลับมาในอนาคต อาจต้อง relabel filesystem ใหม่ ซึ่งใช้เวลานานและเสี่ยงต่อปัญหาระหว่าง boot


ตรวจสอบสถานะ SELinux

ใช้คำสั่งพื้นฐาน

getenforce

ดูรายละเอียดมากขึ้น

sestatus

ตัวอย่างผลลัพธ์

SELinux status:                 enabled
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing

จุดที่ควรดูคือ

  • SELinux status เปิดหรือไม่

  • Loaded policy name ใช้ policy อะไร

  • Current mode ตอนนี้เป็น Enforcing หรือ Permissive

  • Mode from config file ค่า default หลัง reboot คืออะไร


ตั้งค่า SELinux ถาวร

ไฟล์ config หลักคือ

sudo nano /etc/selinux/config

ตัวอย่างค่าที่แนะนำ

SELINUX=enforcing
SELINUXTYPE=targeted

คำอธิบาย:

  • SELINUX=enforcing ให้ SELinux ทำงานจริง

  • SELINUX=permissive ใช้สำหรับทดสอบหรือ debug

  • SELINUX=disabled ไม่แนะนำ ยกเว้นมีเหตุผลเฉพาะและเข้าใจผลกระทบ

  • SELINUXTYPE=targeted เป็น policy ที่ใช้ทั่วไปในระบบตระกูล RHEL

หลังแก้ไขไฟล์ config ต้อง reboot เพื่อให้มีผลเต็มรูปแบบ

sudo reboot

⚠️ ถ้าเครื่องเคยปิด SELinux มาก่อน แล้วต้องการเปิดกลับมา ควรวางแผน maintenance window เพราะระบบอาจต้อง relabel filesystem


ทำความเข้าใจ SELinux Context

SELinux ใช้ label หรือ context ในการตัดสินสิทธิ์

ดู context ของไฟล์

ls -Z /var/www/html

ดู context ของ directory

ls -Zd /var/www/html

ตัวอย่างผลลัพธ์

system_u:object_r:httpd_sys_content_t:s0 /var/www/html

ส่วนที่ SysAdmin มักต้องสนใจมากที่สุดคือ type

จากตัวอย่างนี้คือ

httpd_sys_content_t

แปลว่าไฟล์หรือ directory นี้เป็น content ที่ Apache/httpd สามารถอ่านได้ตาม policy

ดู context ของ process

ps -eZ | grep httpd

ตัวอย่าง

system_u:system_r:httpd_t:s0  1234 ?  00:00:01 httpd

ในกรณีนี้ process ของ Apache ทำงานใน domain httpd_t

หลักคิดง่าย ๆ คือ

process domain ต้องเข้ากันได้กับ file type ตาม policy ของ SELinux


ตัวอย่างปัญหา: Apache อ่านเว็บจาก /srv/www ไม่ได้

สมมุติเราต้องการเก็บไฟล์เว็บไซต์ไว้ที่

/srv/www/sysadmin

สร้าง directory และไฟล์ทดสอบ

sudo mkdir -p /srv/www/sysadmin
echo "Hello SELinux" | sudo tee /srv/www/sysadmin/index.html

กำหนด owner และ permission ตามปกติ

sudo chown -R apache:apache /srv/www/sysadmin
sudo chmod -R 755 /srv/www/sysadmin

ตรวจ context

ls -Zd /srv/www/sysadmin

ถ้าเห็น type เช่น var_t หรือ default_t Apache อาจยังเข้าไม่ได้ แม้ permission จะถูกต้อง

วิธีแก้ที่ถูกต้องคือบอก SELinux ว่า directory นี้เป็น web content

sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www/sysadmin(/.*)?"

จากนั้น apply context จริงด้วย restorecon

sudo restorecon -Rv /srv/www/sysadmin

ตรวจสอบอีกครั้ง

ls -Zd /srv/www/sysadmin

ควรเห็น type เป็น

httpd_sys_content_t

สรุปคือ

  • semanage fcontext ใช้เพิ่มกฎ context แบบถาวร

  • restorecon ใช้ apply label ให้ไฟล์จริง

  • อย่าใช้ chcon เป็นทางเลือกหลักใน production เพราะมักไม่ถาวรเท่า semanage fcontext


กรณีเว็บต้องเขียนไฟล์ เช่น uploads

ถ้า web application ต้องเขียนไฟล์ใน directory เช่น

/var/www/html/uploads

การใช้ httpd_sys_content_t อาจไม่พอ เพราะ type นี้เหมาะกับการอ่าน content เป็นหลัก

ให้ใช้ type ที่อนุญาตการเขียนสำหรับ httpd

sudo mkdir -p /var/www/html/uploads
sudo chown -R apache:apache /var/www/html/uploads

กำหนด SELinux context

sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/uploads(/.*)?"

Apply context

sudo restorecon -Rv /var/www/html/uploads

ตรวจสอบ

ls -Zd /var/www/html/uploads

ควรเห็น

httpd_sys_rw_content_t

⚠️ อย่ากำหนด writable context ให้ทั้ง /var/www/html ถ้าไม่จำเป็น ควรจำกัดเฉพาะ directory ที่ต้องเขียนจริง เช่น uploads, cache, storage


จัดการ SELinux Boolean

SELinux Boolean คือ switch เปิด/ปิดพฤติกรรมบางอย่างของ service โดยไม่ต้องเขียน policy ใหม่

ดู boolean ที่เกี่ยวกับ Apache

getsebool -a | grep httpd

ตัวอย่างที่พบบ่อยคือ ถ้า Apache ต้องเชื่อมต่อ network ออกไปหา backend, API หรือ database บางกรณี อาจต้องเปิด boolean นี้

sudo setsebool -P httpd_can_network_connect on

คำอธิบาย:

  • setsebool ใช้เปลี่ยนค่า boolean

  • -P หมายถึง persistent หรือถาวรหลัง reboot

  • on คือเปิดใช้งาน

ตรวจสอบค่า

getsebool httpd_can_network_connect

⚠️ เปิดเฉพาะ boolean ที่จำเป็นจริง อย่าเปิดทุกอย่างเพราะต้องการให้ service ทำงานง่ายขึ้น เพราะจะทำให้ขอบเขต security กว้างเกินไป


จัดการ Port ที่ SELinux อนุญาต

บางครั้ง service ทำงานถูกต้อง แต่ย้าย port แล้ว SELinux ไม่อนุญาต เช่น Apache ต้องการใช้ port 8080 หรือ 8888

ตรวจ port ที่ SELinux อนุญาตให้ httpd ใช้

sudo semanage port -l | grep http_port_t

ถ้าต้องการเพิ่ม port 8080 ให้ Apache ใช้

sudo semanage port -a -t http_port_t -p tcp 8080

ถ้า port นั้นมีอยู่แล้วและต้องการแก้ไข type ให้ใช้

sudo semanage port -m -t http_port_t -p tcp 8080

ตรวจสอบอีกครั้ง

sudo semanage port -l | grep http_port_t

จากนั้น restart service

sudo systemctl restart httpd

วิธี Troubleshoot เมื่อสงสัยว่า SELinux block

เมื่อ service ใช้งานไม่ได้ อย่าเพิ่งปิด SELinux ให้ไล่ตรวจตามลำดับนี้

ขั้นที่ 1 ตรวจ Linux permission ปกติก่อน

ls -l /path/to/file

ตรวจ path ทั้งเส้นทาง

namei -l /path/to/file

ถ้า permission ปกติผิด ให้แก้ chmod หรือ chown ก่อน เพราะ SELinux ไม่ได้มาแทนที่ Linux permission แต่ทำงานเป็นชั้นเสริม

ขั้นที่ 2 ตรวจ context

ls -Z /path/to/file
ls -Zd /path/to/directory

ดูว่า type ถูกต้องหรือไม่ เช่น web content ควรเป็น httpd_sys_content_t

ขั้นที่ 3 ดู log ของ SELinux

ค้นหา AVC denial ล่าสุด

sudo ausearch -m AVC,USER_AVC -ts recent

ถ้าต้องการดูเฉพาะ service เช่น httpd

sudo ausearch -m AVC,USER_AVC -c httpd -ts recent

ขั้นที่ 4 ใช้ sealert วิเคราะห์

sudo sealert -a /var/log/audit/audit.log

เครื่องมือนี้มักให้คำแนะนำว่า denial เกิดจากอะไร และควรแก้ด้วย context, boolean หรือ policy

ขั้นที่ 5 ใช้ audit2why เพื่ออ่านเหตุผล

sudo ausearch -m AVC,USER_AVC -ts recent | audit2why

คำสั่งนี้ช่วยแปล denial ให้อ่านง่ายขึ้น


แล้ว audit2allow ใช้ได้ไหม?

ใช้ได้ แต่ควรใช้เป็นทางเลือกท้าย ๆ ไม่ใช่คำสั่งแรก

หลายคนเห็น denial แล้วสั่งประมาณนี้ทันที

sudo ausearch -m AVC -ts recent | audit2allow -M mypolicy
sudo semodule -i mypolicy.pp

แม้วิธีนี้จะทำให้ service ผ่านได้ แต่มีความเสี่ยงคือเราอาจสร้าง policy ที่อนุญาตกว้างเกินไปโดยไม่เข้าใจปัญหาจริง

แนวทางที่ปลอดภัยกว่าคือ

  1. ตรวจ Linux permission ก่อน

  2. ตรวจ SELinux context

  3. แก้ด้วย semanage fcontext และ restorecon

  4. ตรวจ boolean ที่เกี่ยวข้อง

  5. ตรวจ port type

  6. ใช้ custom policy เฉพาะเมื่อจำเป็นจริง

ถ้าต้องใช้ audit2allow ควรอ่านไฟล์ .te ก่อนเสมอ

cat mypolicy.te

ติดตั้ง policy เฉพาะเมื่อเข้าใจว่าอนุญาตอะไร

sudo semodule -i mypolicy.pp

⚠️ ไม่ควร copy-paste policy จากอินเทอร์เน็ตเข้าระบบ production โดยไม่อ่านรายละเอียดก่อน


Checklist ใช้งาน SELinux แบบไม่ปวดหัว

ใช้ checklist นี้ทุกครั้งเมื่อเจอ Permission Denied

[ ] ตรวจ getenforce ว่าอยู่ใน Enforcing หรือไม่
[ ] ตรวจ permission ปกติด้วย ls -l
[ ] ตรวจ path permission ด้วย namei -l
[ ] ตรวจ context ด้วย ls -Z / ls -Zd
[ ] ดู audit log ด้วย ausearch
[ ] วิเคราะห์ด้วย sealert หรือ audit2why
[ ] แก้ label ด้วย semanage fcontext + restorecon
[ ] ตรวจ boolean ด้วย getsebool
[ ] ตรวจ port type ด้วย semanage port -l
[ ] ใช้ audit2allow เป็นทางเลือกสุดท้าย

คำสั่งสรุปที่ควรจำ

ตรวจสถานะ

getenforce
sestatus

เปลี่ยนโหมดชั่วคราว

sudo setenforce 0   # เปลี่ยนเป็น Permissive ชั่วคราว
sudo setenforce 1   # กลับเป็น Enforcing

ดู context

ls -Z /path/to/file
ls -Zd /path/to/directory
ps -eZ | grep service-name

แก้ context แบบถาวร

sudo semanage fcontext -a -t TYPE_T "/path(/.*)?"
sudo restorecon -Rv /path

ดู denial log

sudo ausearch -m AVC,USER_AVC -ts recent

วิเคราะห์ denial

sudo sealert -a /var/log/audit/audit.log
sudo ausearch -m AVC,USER_AVC -ts recent | audit2why

จัดการ boolean

getsebool -a | grep keyword
sudo setsebool -P boolean_name on

จัดการ port

sudo semanage port -l | grep service
sudo semanage port -a -t http_port_t -p tcp 8080

แนะนำ Screenshot สำหรับบทความ

ควรเพิ่มภาพประกอบในบทความตามจุดต่อไปนี้

  1. ผลลัพธ์คำสั่ง sestatus

  2. ตัวอย่าง ls -Z ก่อนแก้ context

  3. ตัวอย่าง semanage fcontext และ restorecon

  4. ตัวอย่าง ausearch -m AVC -ts recent

  5. Diagram สั้น ๆ แสดงความสัมพันธ์ระหว่าง Process Domain → File Type → SELinux Policy


สรุป

SELinux ไม่ใช่ศัตรูของ SysAdmin แต่เป็นระบบรักษาความปลอดภัยอีกชั้นที่ช่วยลดความเสียหายเมื่อ service ถูกโจมตีหรือทำงานผิดพลาด

หัวใจสำคัญคืออย่าแก้ปัญหาด้วยการปิด SELinux ทันที แต่ให้เปลี่ยนวิธีคิดใหม่ว่า เมื่อระบบ block บางอย่าง แปลว่าเราต้องตรวจว่า permission ปกติถูกไหม context ถูกไหม boolean เหมาะสมไหม และ port ได้รับอนุญาตหรือยัง

ถ้าจำ workflow ได้เพียงชุดเดียว ให้จำชุดนี้

ตรวจ permission → ตรวจ context → อ่าน audit log → แก้ label/boolean/port → ใช้ custom policy เมื่อจำเป็น

เมื่อเข้าใจหลักนี้ SELinux จะไม่ใช่เรื่องปวดหัวอีกต่อไป แต่จะกลายเป็นเครื่องมือสำคัญที่ช่วยให้ Linux Server ของเราปลอดภัยและเป็นมืออาชีพมากขึ้น



Write by Dr.Arnut Ruttanatirakul
SysAdmin Knowledge
https://www.sysadmin.in.th
June 11, 2026