hoatranlab.io.vn Zalo: 0917516878 Hotline: 0917516878 [email protected]
HoaTranLab Logo HoaTranLab
Linux Bible 11th Edition - Chapter 25

Enhancing Linux Security
with SELinux

Học SELinux để bảo vệ Linux server với MAC (Mandatory Access Control) — từ modes đến contexts đến troubleshooting

Learning Objectives

Mục Tiêu Chương 25

Sau khi hoàn thành chương này, bạn sẽ nắm vững các kỹ năng SELinux cần thiết để bảo vệ Linux server.

Hiểu SELinux Modes

Phân biệt enforcing / permissive / disabled và cách chuyển đổi giữa các mode bằng getenforce và setenforce.

Security Contexts

Hiểu cấu trúc user:role:type:level và cách đọc context bằng ls -Z, ps -Z, id -Z.

Quản lý File Context

Sử dụng chcon, restorecon, và semanage fcontext để gán và phục hồi context cho file.

SELinux Booleans

Xem và thay đổi boolean bằng getsebool -a, setsebool -P. Hiểu các boolean phổ biến cho httpd, samba, ftp.

Quản lý Ports

Liệt kê và thêm port được phép bằng semanage port -lsemanage port -a.

Troubleshooting

Phân tích AVC denials bằng ausearch, audit2why, audit2allow, và sealert.

Theory

Lý Thuyết SELinux

Nắm vững kiến trúc và các khái niệm cốt lõi của Security-Enhanced Linux.

1

SELinux Overview — MAC vs DAC

DAC — Discretionary Access Control

  • Kiểm soát quyền truy cập theo owner/group/other (chmod)
  • Owner có toàn quyền quyết định ai truy cập file của mình
  • Nếu process bị khai thác, attacker có quyền của user đó
  • Rủi ro: root có thể làm mọi thứ

MAC — Mandatory Access Control

  • Kernel enforce policy cho mọi subject/object
  • Process chỉ có quyền được policy cho phép
  • Ngay cả root cũng bị giới hạn bởi SELinux policy
  • An toàn hơn: damage containment

SELinux Modes

Enforcing

Policy được áp dụng đầy đủ. Hành động vi phạm bị từ chối và ghi AVC denial log. Đây là chế độ production.

Permissive

Policy không áp dụng nhưng vẫn ghi log AVC denial. Dùng để debug và test policy mới trước khi enforce.

Disabled

SELinux bị tắt hoàn toàn. Cần reboot khi bật lại để relabel toàn bộ filesystem.

/etc/selinux/config
# SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= can take one of these three values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy, # mls - Multi Level Security protection. SELINUXTYPE=targeted
Terminal — Kiểm tra và thay đổi SELinux mode
# Xem mode hiện tại (nhanh) $ getenforce Enforcing # Xem thông tin chi tiết $ sestatus -v SELinux status: enabled SELinuxfs mount: /sys/fs/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Max kernel policy version: 33 # Chuyển sang permissive (tạm thời, mất khi reboot) # setenforce 0 # getenforce Permissive # Chuyển sang enforcing (tạm thời) # setenforce 1 # Thay đổi vĩnh viễn: sửa /etc/selinux/config rồi reboot
2

Security Contexts — user:role:type:level

Cấu trúc Security Context

system_u:object_r:httpd_sys_content_t:s0
USER
system_u
SELinux user identity
ROLE
object_r
RBAC role
TYPE
httpd_sys_content_t
Type / domain (quan trọng nhất)
LEVEL
s0
MLS sensitivity level
Terminal — Xem Security Context
# Xem context của files trong web directory $ ls -Z /var/www/html/ system_u:object_r:httpd_sys_content_t:s0 index.html system_u:object_r:httpd_sys_content_t:s0 style.css # Xem context của processes đang chạy $ ps -Z | grep httpd system_u:system_r:httpd_t:s0 1234 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 1235 ? 00:00:00 httpd # Xem context của user hiện tại $ id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 # Xem cả DAC và MAC cùng lúc $ ls -lZ /var/www/html/index.html -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
3

Quản lý File Context

Lệnh Mục đích Lưu vào Policy DB?
chcon Đổi context trực tiếp trên file (tạm thời) Không
restorecon Phục hồi context theo policy DB Đọc DB
semanage fcontext Ghi rule regex vào policy DB (vĩnh viễn) Ghi vào DB
Terminal — Quản lý File Context
# chcon: thay đổi context tạm thời (sẽ mất nếu restorecon chạy) $ chcon -t httpd_sys_content_t /var/myapp/html/index.html $ chcon -Rt httpd_sys_content_t /var/myapp/html/ # restorecon: phục hồi context theo policy database $ restorecon -Rv /var/www/html/ Relabeled /var/www/html/index.html from unconfined_u:object_r:default_t:s0 to system_u:object_r:httpd_sys_content_t:s0 # semanage fcontext: xem context rules trong policy $ semanage fcontext -l | grep httpd /var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 /srv/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 # Thêm rule mới vào policy DB (bước 1: ghi rule) $ semanage fcontext -a -t httpd_sys_content_t "/var/myapp/html(/.*)?" # Áp dụng rule vừa thêm vào filesystem (bước 2: relabel) $ restorecon -Rv /var/myapp/html/ Relabeled /var/myapp/html/ ... Relabeled /var/myapp/html/index.html ...
4

SELinux Booleans

Boolean là công tắc on/off cho phép bật/tắt tính năng trong SELinux policy mà không cần viết policy mới. Flag -P làm thay đổi tồn tại sau khi reboot.

Terminal — SELinux Booleans
# Liệt kê tất cả booleans liên quan httpd $ getsebool -a | grep httpd httpd_can_network_connect --> off httpd_can_network_connect_db --> off httpd_enable_homedirs --> off httpd_use_nfs --> off httpd_use_cifs --> off # Xem một boolean cụ thể $ getsebool httpd_enable_homedirs httpd_enable_homedirs --> off # Bật boolean tạm thời (mất khi reboot) # setsebool httpd_enable_homedirs on # Bật boolean vĩnh viễn (-P = Persistent, lưu vào policy DB) # setsebool -P httpd_enable_homedirs on # Xem mô tả chi tiết và trạng thái booleans $ semanage boolean -l | grep httpd httpd_enable_homedirs (off , off) Allow httpd to read home directories httpd_can_network_connect (off , off) Allow httpd to make network connections

Booleans phổ biến cần nhớ

httpd_can_network_connect — cho phép Apache kết nối mạng
httpd_enable_homedirs — cho phép Apache đọc home dir
httpd_use_nfs — cho phép Apache dùng NFS share
samba_enable_home_dirs — Samba share home directory
ftp_home_dir — FTP truy cập home directory
ssh_chroot_rw_homedirs — SSH chroot read/write
5

Quản lý Ports với SELinux

SELinux kiểm soát port nào service được phép lắng nghe. Nếu service dùng port không chuẩn, cần thêm port vào policy.

Terminal — SELinux Port Management
# Xem tất cả ports được phép theo type $ semanage port -l | grep http http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000 http_cache_port_t tcp 8080, 8118, 8123, 10001-10010 # Thêm port mới vào policy (-a=add, -t=type, -p=protocol) # semanage port -a -t http_port_t -p tcp 8080 # Xóa port khỏi policy # semanage port -d -t http_port_t -p tcp 8080 # Sửa type của port đã có trong policy (-m=modify) # semanage port -m -t http_port_t -p tcp 8888 # Kiểm tra sau khi thêm port 8080 $ semanage port -l | grep "http_port_t" http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8080, 8443, 9000
6

Troubleshooting SELinux

Terminal — Phân tích AVC Denials
# Xem AVC denials gần đây (~10 phút qua) $ ausearch -m avc -ts recent ---- time->Tue Apr 1 10:15:23 2026 type=AVC msg=audit(1743498923.001:1234): avc: denied { read } for pid=2345 comm="httpd" name="index.html" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file # Giải thích nguyên nhân denial bằng audit2why $ ausearch -m avc -ts today | audit2why Was caused by: Missing type enforcement (TE) allow rule. You can use audit2allow to generate a loadable module to allow this access. # Tạo policy module tự động từ AVC denials $ ausearch -m avc -ts recent | audit2allow -M mypolicy ******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i mypolicy.pp # Load policy module vào kernel # semodule -i mypolicy.pp # Dùng sealert để phân tích toàn bộ audit log (cần setroubleshoot) $ sealert -a /var/log/audit/audit.log # Tìm kiếm nhanh AVC denials trong audit log $ grep "avc: denied" /var/log/audit/audit.log | tail -20
7

Các Vấn Đề SELinux Thường Gặp

Dùng mv thay vì cp

Khi dùng mv, file giữ nguyên context cũ từ vị trí gốc. Dùng cp hoặc chạy restorecon sau khi mv.

restorecon -Rv /destination/

Non-standard directory

Service dùng thư mục ngoài path chuẩn (ví dụ /data thay vì /var/www). Giải pháp: thêm rule vào policy DB.

semanage fcontext -a -t TYPE "/path(/.*)?"

Non-standard port

Service lắng nghe trên port không có trong policy. Giải pháp: thêm port bằng semanage.

semanage port -a -t http_port_t -p tcp PORT

Boolean chưa được bật

Tính năng cần boolean cụ thể nhưng boolean đang off. Ví dụ: Apache truy cập home directory cần boolean.

setsebool -P httpd_enable_homedirs on
Hands-on Lab

Lab Thực Hành

Cấu hình Apache với SELinux non-standard directory — kịch bản hoàn chỉnh phục vụ web từ /data/website

1

Kiểm tra SELinux mode hiện tại

Xác nhận SELinux đang ở chế độ enforcing trước khi bắt đầu.

Step 1
$ getenforce Enforcing $ sestatus SELinux status: enabled Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing
2

Tạo thư mục web non-standard

Tạo thư mục /data/website và nội dung test.

Step 2
# mkdir -p /data/website # echo '<h1>Hello from SELinux Lab!</h1>' > /data/website/index.html # chmod -R 755 /data/website $ ls -la /data/website/ total 8 drwxr-xr-x. 2 root root 26 Apr 1 10:00 . drwxr-xr-x. 3 root root 18 Apr 1 10:00 .. -rw-r--r--. 1 root root 34 Apr 1 10:00 index.html
3

Cấu hình Apache DocumentRoot

Sửa file cấu hình Apache để trỏ DocumentRoot đến thư mục mới.

/etc/httpd/conf/httpd.conf
# Thay đổi DocumentRoot DocumentRoot "/data/website" # Thêm Directory block cho path mới <Directory "/data/website"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>
4

Kiểm tra SELinux context của thư mục

Xem context hiện tại — sẽ là default_t, không phải httpd_sys_content_t.

Step 4
$ ls -Z /data/website/ unconfined_u:object_r:default_t:s0 index.html $ ls -Zd /data/ unconfined_u:object_r:default_t:s0 /data/ # Context "default_t" KHÔNG được phép bởi httpd_t process!
5

Thử start Apache và kiểm tra lỗi

Apache start được nhưng SELinux chặn việc đọc file — trả về 403 Forbidden.

Step 5 — Gặp lỗi SELinux
# systemctl start httpd # systemctl status httpd Active: active (running) since Tue 2026-04-01 $ curl localhost <!DOCTYPE HTML PUBLIC ...> <title>403 Forbidden</title> <h1>Forbidden</h1> <p>You don't have permission to access this resource.</p> # 403 = SELinux đang chặn (không phải vấn đề DAC permission)
6

Phân tích AVC denial trong audit log

Dùng audit2why để hiểu nguyên nhân và gợi ý cách sửa.

Step 6 — Phân tích AVC
$ ausearch -m avc -ts recent type=AVC msg=audit(...): avc: denied { getattr } for pid=2100 comm="httpd" path="/data/website/index.html" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file $ ausearch -m avc -ts today | audit2why Was caused by: Missing type enforcement (TE) allow rule. Fix: apply a file context to /data/website using semanage fcontext and restorecon
7

Fix SELinux context cho thư mục

Ghi rule vào policy DB bằng semanage fcontext, sau đó áp dụng bằng restorecon.

Step 7 — Fix Context
# Bước 1: Ghi rule vào policy database (vĩnh viễn) # semanage fcontext -a -t httpd_sys_content_t "/data/website(/.*)?" # semanage fcontext -a -t httpd_sys_content_t "/data/website" # Bước 2: Áp dụng rule lên filesystem (relabel) # restorecon -Rv /data/website/ Relabeled /data/website from unconfined_u:object_r:default_t:s0 to system_u:object_r:httpd_sys_content_t:s0 Relabeled /data/website/index.html from unconfined_u:object_r:default_t:s0 to system_u:object_r:httpd_sys_content_t:s0 # Kiểm tra context sau khi fix $ ls -Z /data/website/ system_u:object_r:httpd_sys_content_t:s0 index.html
8

Xác nhận Apache hoạt động

Test lại curl — lần này trả về nội dung thành công với SELinux enforcing.

Step 8 — Verify Success
$ curl localhost <h1>Hello from SELinux Lab!</h1> $ sestatus SELinux status: enabled Current mode: enforcing # systemctl status httpd Active: active (running) # Lab hoàn thành! Apache phục vụ từ /data/website # với SELinux enforcing mode - bảo mật và hoạt động tốt

Tóm tắt quy trình Lab

1. Kiểm tra mode 2. Tạo directory 3. Config Apache 4. Kiểm tra context 5. Test lỗi 403 6. Phân tích AVC 7. Fix context 8. Verify OK
Review

Câu Hỏi Ôn Tập

10 câu hỏi và đáp án giúp củng cố kiến thức Chapter 25.

1

SELinux MAC khác DAC như thế nào?

DAC (Discretionary) cho phép owner quyết định ai được truy cập file của mình dựa trên rwx permissions. MAC (Mandatory) do kernel enforce policy cho mọi process và file — ngay cả root cũng bị kiểm soát. Nếu httpd bị exploit, DAC không ngăn được attacker leo thang quyền; MAC giới hạn httpd chỉ làm những gì policy cho phép.

2

Sự khác nhau giữa enforcing và permissive mode?

Enforcing: policy được áp dụng đầy đủ — hành động vi phạm bị từ chối và ghi AVC denial log. Permissive: policy không áp dụng (không chặn) nhưng vẫn ghi log như thể đang bị chặn. Permissive hữu ích để debug và test policy trước khi áp dụng trên production.

3

Cấu trúc security context (user:role:type:level) là gì?

User: SELinux user identity (system_u, unconfined_u). Role: RBAC role (object_r cho file, system_r cho process). Type: phần quan trọng nhất — xác định domain/type để policy kiểm soát truy cập (httpd_t, httpd_sys_content_t). Level: MLS sensitivity (s0, s0-s0:c0.c1023).

4

Tại sao nên dùng cp thay vì mv khi làm việc với SELinux?

Khi dùng mv, file mang theo SELinux context từ vị trí cũ. Ví dụ: mv file từ /home (user_home_t) sang /var/www/html — file vẫn giữ context user_home_t thay vì httpd_sys_content_t. Với cp, file mới được tạo và nhận context của thư mục đích. Nếu phải dùng mv, hãy chạy restorecon sau.

5

semanage fcontext và chcon khác nhau như thế nào?

chcon thay đổi context trực tiếp trên file ngay lập tức nhưng không lưu vào policy DB — thay đổi sẽ mất khi restorecon chạy hoặc filesystem được relabel. semanage fcontext ghi rule regex vào policy DB (vĩnh viễn qua reboot) nhưng cần chạy thêm restorecon để áp dụng lên filesystem.

6

setsebool -P có nghĩa gì? Tại sao cần flag -P?

Flag -P viết thay đổi boolean vào policy database (Persistent), làm thay đổi tồn tại sau khi reboot. Nếu không có -P, thay đổi chỉ có hiệu lực trong session hiện tại và sẽ mất sau khi khởi động lại. Luôn dùng -P trong môi trường production.

7

Lệnh nào xem tất cả AVC denials gần đây?

Dùng ausearch -m avc -ts recent để xem AVC denials trong ~10 phút qua. Dùng -ts today cho toàn bộ hôm nay. Kết hợp với audit2why để giải thích: ausearch -m avc -ts recent | audit2why.

8

audit2allow được dùng để làm gì? Có rủi ro gì?

audit2allow tự động tạo policy module (.pp file) cho phép các hành động bị deny trong AVC log. Rủi ro: có thể tạo policy quá rộng, cho phép nhiều hơn cần thiết, làm yếu bảo mật. Nên dùng như giải pháp cuối cùng. Luôn kiểm tra nội dung policy trước khi load bằng semodule -i.

9

Làm thế nào để cho phép Apache nghe trên port 8080 với SELinux?

Dùng semanage port -a -t http_port_t -p tcp 8080. Giải thích: -a (add), -t http_port_t (type phù hợp với httpd), -p tcp (protocol). Sau đó restart Apache. Kiểm tra bằng semanage port -l | grep http.

10

semanage port -a và semanage port -m khác nhau thế nào?

-a (add) thêm port mới chưa có trong policy — dùng khi port chưa được định nghĩa ở bất kỳ type nào. -m (modify) sửa type của port đã tồn tại trong policy — dùng khi port đã có nhưng gán cho type sai. Nếu dùng -a cho port đã có sẽ báo lỗi "already defined".