ใช้งาน SELinux บน AlmaLinux และ Rocky Linux โดยไม่ต้องปิด
SELinux (Security-Enhanced Linux) เปิดใช้งานมาตั้งแต่ติดตั้งบน AlmaLinux และ Rocky Linux เป็นชั้นป้องกันที่ทำงานเพิ่มจากสิทธิ์ไฟล์แบบปกติ แม้โปรแกรมจะรันเป็นผู้ใช้ที่อ่านไฟล์ได้ตาม chmod แต่ถ้านโยบายของ SELinux ไม่อนุญาต การเข้าถึงนั้นก็จะถูกปฏิเสธ ประโยชน์ที่ชัดเจนคือ ถ้าเว็บไซต์ถูกเจาะ ผู้โจมตีที่ได้สิทธิ์ของ Nginx หรือ Apache จะยังถูกจำกัดให้อยู่ในขอบเขตที่เว็บเซิร์ฟเวอร์ควรทำได้เท่านั้น
คำแนะนำในอินเทอร์เน็ตจำนวนมากบอกให้ "ปิด SELinux" ทันทีที่เจอ Permission denied บทความนี้แสดงวิธีที่ถูกต้องกว่า คือหาว่า SELinux ปฏิเสธอะไร แล้วแก้เฉพาะจุดด้วยเครื่องมือมาตรฐานสามตัว ได้แก่ File Context, Boolean และ Port Label ซึ่งครอบคลุมปัญหาที่พบบนเว็บเซิร์ฟเวอร์เกือบทั้งหมด
สิ่งที่ต้องเตรียม
- AlmaLinux หรือ Rocky Linux 8 หรือ 9 และผู้ใช้ที่มีสิทธิ์
sudo - ติดตั้งเครื่องมือจัดการ SELinux:
sudo dnf install -y policycoreutils-python-utils setroubleshoot-server
policycoreutils-python-utils ให้คำสั่ง semanage และ audit2why ส่วน setroubleshoot-server ให้คำสั่ง sealert ที่อธิบายสาเหตุเป็นภาษาคนอ่านเข้าใจ
ขั้นตอนที่ 1: ตรวจสถานะ SELinux
getenforce
sestatus
| โหมด | ความหมาย |
|---|---|
Enforcing | บังคับใช้นโยบาย ปฏิเสธและบันทึก Log (ค่าที่ควรใช้) |
Permissive | ไม่ปฏิเสธ แต่บันทึก Log ว่าจะปฏิเสธอะไร ใช้ตรวจหาปัญหาชั่วคราว |
Disabled | ปิดทั้งหมด ไม่มีการบันทึก |
ขั้นตอนที่ 2: เข้าใจ Label
SELinux ตัดสินจาก Label (Context) ที่ติดอยู่กับทุกไฟล์และทุกโปรเซส ดูได้ด้วยตัวเลือก -Z:
ls -Z /var/www/html
ps -eZ | grep -E "nginx|httpd"
ตัวอย่างผลลัพธ์:
unconfined_u:object_r:httpd_sys_content_t:s0 index.html
system_u:system_r:httpd_t:s0 1320 ? 00:00:00 nginx
ส่วนที่สำคัญคือส่วนที่สาม เรียกว่า Type โปรเซส Nginx และ Apache รันใน Type httpd_t และนโยบายอนุญาตให้ httpd_t อ่านไฟล์ที่เป็น httpd_sys_content_t ได้ ถ้าไฟล์เว็บมี Type อื่น เช่น user_home_t หรือ default_t เว็บเซิร์ฟเวอร์จะอ่านไม่ได้ แม้สิทธิ์ chmod จะเปิดเต็มที่ก็ตาม
Type ที่ใช้บ่อยกับเว็บ:
| Type | ใช้กับ |
|---|---|
httpd_sys_content_t | ไฟล์เว็บที่อ่านอย่างเดียว |
httpd_sys_rw_content_t | โฟลเดอร์ที่เว็บต้องเขียน เช่น wp-content/uploads, storage ของ Laravel |
httpd_log_t | ไฟล์ Log ของเว็บเซิร์ฟเวอร์ |
ขั้นตอนที่ 3: หาว่า SELinux ปฏิเสธอะไร
เมื่อเว็บขึ้น 403 หรือ 502 และ Log ของแอปแจ้ง Permission denied ทั้งที่สิทธิ์ไฟล์ถูกต้อง ให้ดูบันทึกการปฏิเสธ (AVC Denial):
sudo ausearch -m AVC,USER_AVC -ts recent
ตัวอย่างบรรทัดที่พบ:
type=AVC msg=audit(...): avc: denied { read } for pid=1320 comm="nginx"
name="index.html" scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0
อ่านได้ว่า โปรเซส nginx (Type httpd_t) ถูกปฏิเสธการ read ไฟล์ที่มี Type user_home_t ให้ส่งผลนี้เข้า audit2why หรือใช้ sealert เพื่อดูคำแนะนำ:
sudo ausearch -m AVC -ts recent | audit2why
sudo sealert -a /var/log/audit/audit.log
sealert มักบอกคำสั่งที่ควรใช้แก้มาให้ด้วย แต่ให้อ่านและเข้าใจก่อนทำตาม
ขั้นตอนที่ 4: แก้ปัญหาไฟล์ด้วย File Context
สาเหตุที่พบบ่อยที่สุดคือ ใช้ mv ย้ายไฟล์ จาก Home Directory ไปไว้ที่โฟลเดอร์เว็บ mv จะพา Label เดิม (user_home_t) ติดไปด้วย ส่วน cp จะให้ Label ตามโฟลเดอร์ปลายทาง วิธีแก้คือรีเซ็ต Label ให้ตรงกับนโยบาย:
sudo restorecon -Rv /var/www/example.com
ผลลัพธ์จะแสดงบรรทัด Relabeled ... from ... to ... สำหรับไฟล์ที่ถูกแก้
ถ้าเว็บอยู่นอกโฟลเดอร์มาตรฐาน เช่น /srv/www หรือ /data/sites ต้องเพิ่มกฎถาวรก่อน แล้วค่อย restorecon:
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
sudo restorecon -Rv /srv/www
โฟลเดอร์ที่เว็บต้องเขียนได้ ให้กำหนดเฉพาะโฟลเดอร์นั้น ไม่ใช่ทั้งเว็บ:
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/srv/www/example.com/wp-content/uploads(/.*)?"
sudo restorecon -Rv /srv/www/example.com/wp-content/uploads
ดูกฎที่คุณเพิ่มไว้ทั้งหมดด้วย sudo semanage fcontext -l -C อย่าใช้ chcon เป็นวิธีถาวร เพราะค่าจาก chcon จะหายเมื่อมีการ Relabel ทั้งระบบ
ขั้นตอนที่ 5: เปิดความสามารถด้วย Boolean
Boolean คือสวิตช์เปิดปิดพฤติกรรมที่นโยบายเตรียมไว้ให้ ดูรายการของเว็บเซิร์ฟเวอร์ได้ด้วย:
getsebool -a | grep httpd
ที่ใช้บ่อย:
| Boolean | เปิดเมื่อ |
|---|---|
httpd_can_network_connect | เว็บต้องเชื่อมต่อออกไปยังเครือข่าย เช่น Nginx เป็น Reverse Proxy ให้แอป Node.js ที่พอร์ต 3000 หรือ PHP เรียก API ภายนอก |
httpd_can_network_connect_db | เว็บต้องต่อฐานข้อมูลผ่าน TCP (เช่น ฐานข้อมูลอยู่อีกเครื่อง) |
httpd_can_sendmail | PHP ต้องส่งอีเมลผ่าน sendmail ในเครื่อง |
httpd_enable_homedirs | ต้องให้บริการไฟล์จาก Home Directory ของผู้ใช้ |
เปิดแบบถาวรด้วยตัวเลือก -P (ไม่มี -P ค่าจะหายเมื่อรีบูต):
sudo setsebool -P httpd_can_network_connect on
อาการที่บ่งบอกว่าต้องเปิด Boolean ตัวแรก คือ Nginx แจ้ง 502 Bad Gateway และ Error Log มีข้อความ connect() to 127.0.0.1:3000 failed (13: Permission denied) ซึ่งพบบ่อยในการตั้ง Node.js กับ Nginx Reverse Proxy
ขั้นตอนที่ 6: อนุญาตพอร์ตที่ไม่ใช่ค่ามาตรฐาน
SELinux กำหนดว่าแต่ละ Service Bind พอร์ตใดได้บ้าง ถ้าคุณเปลี่ยน SSH ไปพอร์ต 2222 หรือให้ Nginx ฟังที่พอร์ตที่ไม่อยู่ในรายการ Service จะเริ่มไม่ได้ ตรวจรายการก่อน:
sudo semanage port -l | grep -E "^(ssh_port_t|http_port_t)"
เพิ่มพอร์ตที่ต้องการ:
sudo semanage port -a -t ssh_port_t -p tcp 2222
sudo semanage port -a -t http_port_t -p tcp 8090
ถ้าคำสั่งแจ้งว่าพอร์ตนั้นมี Type อื่นกำหนดไว้แล้ว ให้ใช้ -m แทน -a เพื่อแก้ไข การเปลี่ยนพอร์ต SSH ต้องทำขั้นตอนนี้ก่อนรีสตาร์ต SSH เสมอ และต้องเปิด SSH Session เดิมค้างไว้ แล้วทดสอบเข้าด้วยหน้าต่างใหม่ก่อนปิด ดูขั้นตอนเต็มที่ วิธีเปลี่ยน SSH Port บน Linux Server
ตรวจสอบผลลัพธ์
getenforceยังเป็นEnforcing- ทดสอบเว็บหรือ Service ที่มีปัญหาอีกครั้ง แล้วรัน
sudo ausearch -m AVC -ts recentต้องไม่มีบรรทัดปฏิเสธใหม่ (อาจแสดง<no matches>) ls -Zบนโฟลเดอร์เว็บแสดง Type ตามที่ตั้งไว้
ใช้ Permissive เพื่อวินิจฉัยเท่านั้น
ถ้าต้องการยืนยันว่าปัญหามาจาก SELinux จริงหรือไม่ ให้สลับเป็น Permissive ชั่วคราว ทดสอบ แล้วสลับกลับทันที:
sudo setenforce 0
# ทดสอบเว็บ
sudo setenforce 1
วิธีที่แคบกว่าคือทำให้เฉพาะ Domain ของเว็บเซิร์ฟเวอร์เป็น Permissive ขณะที่ส่วนอื่นยัง Enforcing:
sudo semanage permissive -a httpd_t
# หลังตรวจเสร็จ
sudo semanage permissive -d httpd_t
ปัญหาที่พบบ่อย
ใช้ audit2allow สร้าง Module แล้วปัญหาหาย แต่ไม่รู้ว่าอนุญาตอะไรไป
audit2allow -M สร้างกฎจาก Log ทุกบรรทัดที่ได้รับ ซึ่งอาจอนุญาตกว้างเกินไป ใช้ได้เมื่อไม่มี Boolean หรือ File Context ที่ตรงกับกรณีของคุณแล้วเท่านั้น และต้องอ่านไฟล์ .te ที่สร้างขึ้นก่อนติดตั้ง
เคยปิด SELinux แล้วเปิดกลับ ระบบบูตแล้วมีปัญหาเต็มไปหมด
ขณะปิด ไฟล์ที่สร้างใหม่จะไม่มี Label ต้อง Relabel ทั้งระบบก่อนเปิดใช้งาน โดยตั้ง SELINUX=permissive ใน /etc/selinux/config แล้วรัน sudo touch /.autorelabel และรีบูต (ใช้เวลานานตามจำนวนไฟล์) เมื่อบูตเสร็จและไม่มี Denial สำคัญ จึงเปลี่ยนเป็น enforcing บน AlmaLinux/Rocky 9 การตั้ง SELINUX=disabled ในไฟล์นี้ไม่ได้ปิดทั้งหมดอีกต่อไป ต้องใช้ Kernel Parameter selinux=0 ซึ่งเป็นอีกเหตุผลที่ไม่ควรปิด
ไม่เห็น AVC ใน Log ทั้งที่สงสัยว่าเป็น SELinux
บางกฎถูกตั้งให้ปฏิเสธแบบไม่บันทึก (dontaudit) ปิดชั่วคราวด้วย sudo semodule -DB ทดสอบซ้ำ แล้วเปิดกลับด้วย sudo semodule -B
หากตรวจ Log แล้วยังหาทางแก้ที่ไม่ต้องปิด SELinux ไม่ได้ ติดต่อทีมซัพพอร์ต THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/
- Categories:
- Cloud
- Tags:
- Cloud
- Cloud Server
Related Posts
หมวดหมู่ที่น่าสนใจ
- Account Settings
- AD Server
- AI
- Alibaba Cloud
- Anti-Spam Gateway
- AWS Amazon Web Services
- Campaign
- CentOS/AlmaLinux
- Cloud
- Cloud Backup
- Cloud Communication
- Cloud Migration
- Cloud Security
- Cloud Server Management
- Cloud Solution
- Cloud Solution for Government
- Cloud Solutions by Industry
- Cloud Storage
- Cloud VPS App Plus +
- Cloud VPS DirectAdmin
- Cloud VPS Plesk
- CSR
- Cyber Security
- Cybersecurity
- Data Sovereignty
- Database Server
- DDoS
- Digital Tranformation
- Digital Transformation
- Direct Mail
- Directadmin
- Domainname
- Ecommerce
- ERP
- Generative AI
- Getting Started
- Google Cloud
- Google G Suite
- Huawei Cloud
- IT News
- Linux Server
- Managed Cloud Services
- Managed Service Provider
- Manual
- Microsoft
- Microsoft 365
- Microsoft Azure
- News
- On-premise
- Private Mail Server
- Promotion
- Recommend Solution (Enterprise)
- Server
- Sovereign Cloud
- THAI DATA CLOUD Platform
- Ubuntu
- Ubuntu
- Uncategorized
- VMware
- VPS Server
- Web Design
- Web Hosting
- Web Hosting (DirectAdmin)
- Web Hosting (Plesk)
- Web Technologies
- Windows Server
- Wordpress
- Zimbra
- เรื่องราวความประทับใจ
- โซลูชันสำหรับธุรกิจการผลิตและยานยนต์
- โซลูชันสำหรับธุรกิจการศึกษา
- โซลูชันสำหรับธุรกิจการเงิน
- โซลูชันสำหรับธุรกิจขนส่งและกระจายสินค้า
- โซลูชันสำหรับธุรกิจค้าปลีก
- โซลูชันสำหรับธุรกิจท่องเที่ยว
- โซลูชันสำหรับธุรกิจบริการสุขภาพและโรงพยาบาล
- โซลูชันสำหรับธุรกิจประกันภัย
- โซลูชันสำหรับธุรกิจพลังงานและสาธารณูปโภค
- โซลูชันสำหรับธุรกิจสื่อสารมวลชนและเอ็นเตอร์เทนเมนท์
- โซลูชันสำหรับธุรกิจอสังหาริมทรัพย์
- โซลูชันสำหรับธุรกิจเทคโนโลยี


