SELinux Và AppArmor Trên Linux: Hướng Dẫn Kiểm Soát Truy Cập Bắt Buộc (MAC) 2026

Hướng dẫn thực hành cấu hình SELinux và AppArmor trên Linux — từ viết policy với audit2allow, tạo profile với aa-genprof, đến gia cố máy chủ web production. Kèm checklist kiểm tra và tích hợp DevSecOps.

Tại Sao Kiểm Soát Truy Cập Bắt Buộc Không Còn Là Tùy Chọn Trong 2026

Nếu bạn đang quản trị máy chủ Linux mà SELinux vẫn đang ở trạng thái disabled hoặc AppArmor đang ở chế độ complain cho tất cả profile — thì nói thẳng, bạn đang bỏ lỡ lớp phòng thủ quan trọng nhất của hệ thống. Đây không phải ý kiến cá nhân đâu: theo thống kê mới nhất, 55,6% môi trường Linux doanh nghiệp đã triển khai SELinux hoặc AppArmor ở chế độ enforcing vào năm 2025, và con số này tiếp tục tăng mạnh trong 2026.

Lý do thì đơn giản thôi.

Tường lửa bảo vệ bạn khỏi bên ngoài, nhưng khi kẻ tấn công đã lọt vào — thông qua zero-day, supply chain attack, hay một lỗ hổng trong ứng dụng web — thì MAC (Mandatory Access Control) là thứ duy nhất ngăn chúng leo thang đặc quyền. Với cơ chế DAC truyền thống, một tiến trình bị chiếm quyền sẽ kế thừa toàn bộ quyền của người dùng chạy nó. Với MAC, tiến trình đó bị nhốt trong "chiếc hộp" mà policy đã định sẵn — dù người dùng có quyền root đi chăng nữa.

Mình đã từng chứng kiến một đồng nghiệp mất nguyên một ngày cuối tuần để xử lý sự cố vì máy chủ web bị xâm nhập qua lỗ hổng plugin, và kẻ tấn công leo thang lên root trong vòng vài phút. Nếu SELinux được bật đúng cách, câu chuyện đã rất khác.

Bài viết này sẽ hướng dẫn bạn cấu hình và sử dụng cả hai hệ thống MAC chính trên Linux — SELinux và AppArmor — từ cơ bản đến nâng cao. Không phải để tắt chúng đi (như rất nhiều hướng dẫn trên mạng vẫn khuyên), mà để thực sự tận dụng chúng bảo vệ hệ thống production.

SELinux: Kiểm Soát Truy Cập Dựa Trên Nhãn Bảo Mật

Tổng quan và kiến trúc

SELinux (Security-Enhanced Linux) được phát triển bởi NSA và tích hợp vào nhân Linux từ phiên bản 2.6. Nó sử dụng hệ thống nhãn bảo mật (security labels) để kiểm soát truy cập — mỗi tiến trình, tệp, thư mục, cổng mạng đều được gắn một security context theo định dạng:

user:role:type:level
# Ví dụ:
system_u:system_r:httpd_t:s0        # Tiến trình Apache
system_u:object_r:httpd_sys_content_t:s0  # Tệp web content

Thành phần quan trọng nhất ở đây là type — nó là nền tảng của Type Enforcement (TE), cơ chế chính mà SELinux dùng để quyết định tiến trình nào được truy cập tài nguyên nào. Nói đơn giản: tiến trình có type httpd_t chỉ được đọc tệp có type httpd_sys_content_t, không được đụng vào tệp có type khác.

SELinux là mặc định trên RHEL, Fedora, CentOS Stream, AlmaLinux và Rocky Linux. RHEL 10 (phát hành 2025) tiếp tục duy trì SELinux ở chế độ enforcing mặc định. Một thay đổi đáng chú ý là openSUSE Tumbleweed đã chuyển từ AppArmor sang SELinux làm MAC mặc định cho cài đặt mới — đây là bước chuyển khá lớn trong hệ sinh thái Linux.

Ba chế độ hoạt động

SELinux hoạt động ở ba chế độ, và bạn cần hiểu rõ từng cái:

  • Enforcing: Thực thi chính sách — từ chối và ghi log các truy cập vi phạm
  • Permissive: Chỉ ghi log vi phạm, không từ chối — rất hữu ích để debug
  • Disabled: Tắt hoàn toàn — đừng bao giờ dùng trên production nhé
# Kiểm tra chế độ hiện tại
getenforce
# Kết quả: Enforcing, Permissive, hoặc Disabled

# Xem thông tin chi tiết
sestatus
# SELinux status:                 enabled
# SELinuxfs mount:                /sys/fs/selinux
# SELinux root directory:         /etc/selinux
# Loaded policy name:             targeted
# Current mode:                   enforcing
# Mode from config file:          enforcing

# Chuyển tạm thời sang Permissive (không cần reboot)
sudo setenforce 0

# Chuyển lại Enforcing
sudo setenforce 1

Để thay đổi vĩnh viễn, bạn cần chỉnh sửa tệp /etc/selinux/config:

# /etc/selinux/config
SELINUX=enforcing
SELINUXTYPE=targeted

Quản lý Security Context

Hiểu và quản lý security context là kỹ năng cốt lõi khi làm việc với SELinux. Thú thật là lúc mới bắt đầu, mình cũng thấy khá rối với đống label này, nhưng quen rồi thì nó trở nên rất trực quan:

# Xem context của tệp
ls -Z /var/www/html/
# -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html

# Xem context của tiến trình
ps auxZ | grep httpd
# system_u:system_r:httpd_t:s0   root  1234  ... /usr/sbin/httpd

# Xem context của cổng mạng
semanage port -l | grep http
# http_port_t    tcp    80, 81, 443, 488, 8008, 8009, 8443, 9000

# Thay đổi context của tệp
sudo chcon -t httpd_sys_content_t /var/www/custom/index.html

# Khôi phục context mặc định (quan trọng sau khi di chuyển tệp)
sudo restorecon -Rv /var/www/html/

# Thêm quy tắc context mặc định cho thư mục tùy chỉnh
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/website(/.*)?"
sudo restorecon -Rv /srv/website/

SELinux Booleans — Điều chỉnh nhanh chính sách

SELinux Booleans giống như những "công tắc" cho phép bật/tắt các quy tắc policy cụ thể mà không cần viết policy mới. Đây là cách nhanh nhất (và an toàn nhất) để điều chỉnh hành vi SELinux:

# Liệt kê tất cả booleans (khoảng 300+ tùy distro)
getsebool -a

# Xem booleans kèm mô tả chi tiết
sudo semanage boolean -l | grep httpd
# httpd_can_network_connect    (off  ,  off)  Allow httpd to make network connections
# httpd_can_sendmail           (off  ,  off)  Allow httpd to send mail
# httpd_enable_homedirs        (off  ,  off)  Allow httpd to read user home directories

# Bật boolean tạm thời (để test)
sudo setsebool httpd_can_network_connect on

# Bật boolean vĩnh viễn (cho production — luôn dùng -P)
sudo setsebool -P httpd_can_network_connect on

# Kiểm tra boolean đã thay đổi
getsebool httpd_can_network_connect
# httpd_can_network_connect --> on

# Xem chi tiết quy tắc mà boolean kiểm soát
sesearch --bool httpd_can_network_connect -C -A

Một lưu ý quan trọng: luôn dùng -P trên production để thay đổi tồn tại qua reboot. Và trước khi bật boolean nào, hãy đọc mô tả để hiểu rõ nó cho phép điều gì — đừng bật mù quáng, bạn có thể vô tình mở ra lỗ hổng bảo mật.

Xử lý AVC Denial và viết Policy tùy chỉnh với audit2allow

Đây có lẽ là phần quan trọng nhất của bài viết. Khi ứng dụng bị SELinux chặn, phản xạ tự nhiên của nhiều người là tắt SELinux đi. Đừng làm vậy! Thay vào đó, hãy phân tích và tạo policy phù hợp:

# Bước 1: Tìm các AVC denial gần đây
sudo ausearch -m AVC -ts recent
# Hoặc xem trực tiếp trong audit log
sudo ausearch -m AVC -ts today | audit2why

# Ví dụ output:
# type=AVC msg=audit(1709234567.123:456): avc:  denied  { read } 
# for  pid=1234 comm="myapp" name="config.json" 
# scontext=system_u:system_r:myapp_t:s0 
# tcontext=system_u:object_r:var_lib_t:s0 tclass=file

# Bước 2: Dùng audit2why để hiểu nguyên nhân
sudo ausearch -m AVC -ts recent | audit2why
# Kết quả sẽ cho biết: thiếu boolean, thiếu allow rule, hay sai context

# Bước 3: Tạo policy module với audit2allow
sudo ausearch -m AVC -ts recent | audit2allow -M myapp_policy
# Tạo ra: myapp_policy.te và myapp_policy.pp

# Bước 4: QUAN TRỌNG — Đọc và kiểm tra tệp .te trước khi cài
cat myapp_policy.te
# module myapp_policy 1.0;
# require {
#     type myapp_t;
#     type var_lib_t;
#     class file read;
# }
# allow myapp_t var_lib_t:file read;

# Bước 5: Cài đặt policy module
sudo semodule -i myapp_policy.pp

# Bước 6: Xác minh module đã được cài
sudo semodule -l | grep myapp

Quy tắc vàng mà bạn nên nhớ: không bao giờ chạy audit2allow rồi cài ngay kết quả mà không đọc tệp .te. Mình đã thấy không ít trường hợp policy tự động tạo ra quá rộng vì gom nhiều denial khác nhau lại. Hãy lọc theo tiến trình cụ thể:

# Lọc denial theo tiến trình cụ thể
sudo ausearch -m AVC -c myapp | audit2allow -M myapp_custom

# Dùng -R để sử dụng reference policy interfaces (an toàn hơn)
sudo ausearch -m AVC -c myapp | audit2allow -R

Ví dụ thực tế: Cho phép Nginx phục vụ tệp từ thư mục tùy chỉnh

Đây là tình huống mà hầu như ai cấu hình Nginx trên RHEL đều sẽ gặp:

# Tình huống: Nginx cần đọc tệp từ /data/webapp thay vì /var/www/html

# 1. Gán đúng SELinux type cho thư mục mới
sudo semanage fcontext -a -t httpd_sys_content_t "/data/webapp(/.*)?"

# 2. Áp dụng context
sudo restorecon -Rv /data/webapp/

# 3. Nếu Nginx cần ghi vào thư mục upload
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/data/webapp/uploads(/.*)?"
sudo restorecon -Rv /data/webapp/uploads/

# 4. Nếu Nginx cần kết nối đến backend (ví dụ: proxy_pass)
sudo setsebool -P httpd_can_network_connect on

# 5. Nếu Nginx chạy trên cổng không chuẩn (ví dụ: 8080)
sudo semanage port -a -t http_port_t -p tcp 8080

# 6. Xác minh toàn bộ
ls -Zd /data/webapp/
sudo semanage port -l | grep 8080
getsebool httpd_can_network_connect

AppArmor: Kiểm Soát Truy Cập Dựa Trên Đường Dẫn

Tổng quan và kiến trúc

AppArmor (Application Armor) là hệ thống MAC dùng đường dẫn tệp (path-based) thay vì nhãn bảo mật như SELinux. Nói cách khác, thay vì gắn nhãn cho mọi thứ, AppArmor định nghĩa trực tiếp: "ứng dụng X được đọc tệp Y, được ghi vào thư mục Z". Cách tiếp cận này dễ hiểu hơn nhiều so với SELinux.

AppArmor là mặc định trên Ubuntu, Debian, và các biến thể. Hơn 86% máy chủ Ubuntu có AppArmor được bật mặc định. Với việc Ubuntu chiếm hơn 60% instance Linux trên cloud công cộng, AppArmor thực tế đang bảo vệ phần lớn workload cloud toàn cầu — một con số khá ấn tượng.

Phiên bản mới nhất AppArmor 4.0.2 đã được phát hành, và Ubuntu 26.04 LTS sẽ đi kèm nhân Linux 7.0 với các cải tiến quan trọng — bao gồm per-permission tagging và hỗ trợ execpath trong user namespace.

Các chế độ hoạt động

# Kiểm tra trạng thái AppArmor
sudo aa-status
# apparmor module is loaded.
# 42 profiles are loaded.
# 38 profiles are in enforce mode.
# 4 profiles are in complain mode.

# Kiểm tra profile của một ứng dụng cụ thể
sudo aa-status | grep nginx

AppArmor có hai chế độ cho mỗi profile:

  • Enforce: Thực thi — chặn và ghi log các truy cập vi phạm
  • Complain: Chỉ ghi log, không chặn (tương tự Permissive của SELinux)
# Chuyển profile sang chế độ complain (để debug)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

# Chuyển profile sang chế độ enforce (cho production)
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

# Tắt một profile cụ thể (không khuyến nghị trên production)
sudo aa-disable /etc/apparmor.d/usr.sbin.nginx

# Tải lại tất cả profiles
sudo systemctl reload apparmor

Cấu trúc Profile AppArmor

Hiểu cấu trúc profile là chìa khóa để tùy chỉnh AppArmor hiệu quả. Nếu bạn đã từng viết firewall rule, thì đọc AppArmor profile sẽ thấy quen thuộc:

# Ví dụ profile cho /usr/sbin/nginx
# File: /etc/apparmor.d/usr.sbin.nginx

#include 

/usr/sbin/nginx {
  #include 
  #include 

  # Khả năng hệ thống (capabilities)
  capability net_bind_service,
  capability setuid,
  capability setgid,
  capability dac_override,

  # Truy cập tệp cấu hình
  /etc/nginx/** r,
  /etc/ssl/certs/** r,
  /etc/ssl/private/** r,

  # Truy cập nội dung web
  /var/www/** r,
  /data/webapp/** r,

  # Ghi log
  /var/log/nginx/** rw,

  # PID và socket
  /run/nginx.pid rw,
  /run/nginx/** rw,

  # Truy cập mạng
  network inet stream,
  network inet6 stream,

  # Thư mục tạm
  /tmp/** rw,
}

Các ký hiệu quyền: r (đọc), w (ghi), x (thực thi), m (mmap), k (khóa tệp), l (tạo liên kết). Ký tự ** đại diện cho mọi tệp và thư mục con đệ quy. Khá đơn giản đúng không?

Tạo Profile tùy chỉnh với aa-genprof

Nếu bạn không muốn viết profile thủ công (thú thật là ít ai muốn), công cụ aa-genprof sẽ tự động tạo profile bằng cách giám sát hành vi thực tế của ứng dụng:

# Cài đặt công cụ (nếu chưa có)
sudo apt install apparmor-utils apparmor-profiles

# Bước 1: Chạy aa-genprof cho ứng dụng cần tạo profile
sudo aa-genprof /usr/local/bin/myapp

# aa-genprof sẽ:
# - Đặt profile vào chế độ complain
# - Yêu cầu bạn mở terminal khác và chạy ứng dụng
# - Bạn thực hiện TẤT CẢ các thao tác mà ứng dụng cần làm
# - Quay lại terminal aa-genprof, nhấn (S) để quét log
# - Duyệt từng quyền truy cập, chọn Allow/Deny/Glob
# - Nhấn (F) khi hoàn tất — profile được chuyển sang enforce

# Bước 2: Xem profile đã tạo
cat /etc/apparmor.d/usr.local.bin.myapp

# Bước 3: Tinh chỉnh profile sau khi chạy thêm
sudo aa-logprof
# aa-logprof quét log và đề xuất cập nhật cho profiles hiện có

Ví dụ thực tế: Tạo profile cho dịch vụ backup tùy chỉnh

Giả sử bạn có script backup chạy hàng đêm và muốn đảm bảo nó chỉ truy cập đúng những gì cần thiết (nguyên tắc least privilege):

# Giả sử script backup tại /usr/local/bin/backup-daemon
# Script cần: đọc /etc/backup.conf, đọc /data/, ghi /backup/, ghi log

# 1. Tạo profile ban đầu
sudo aa-genprof /usr/local/bin/backup-daemon

# 2. Trong terminal khác, chạy backup-daemon và thực hiện backup thử
sudo /usr/local/bin/backup-daemon --run

# 3. Quay lại terminal aa-genprof, nhấn S rồi F

# 4. Chỉnh sửa thủ công nếu cần
sudo nano /etc/apparmor.d/usr.local.bin.backup-daemon

Profile được tạo sẽ trông kiểu như thế này:

#include 

/usr/local/bin/backup-daemon {
  #include 

  # Đọc cấu hình
  /etc/backup.conf r,

  # Đọc dữ liệu nguồn
  /data/** r,

  # Ghi vào thư mục backup
  /backup/** rw,
  /backup/ rw,

  # Ghi log
  /var/log/backup-daemon.log rw,

  # Lệnh hệ thống cần thiết
  /usr/bin/rsync mrix,
  /usr/bin/gzip mrix,

  # Từ chối mọi truy cập khác (ngầm định)
}
# 5. Tải lại profile
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.backup-daemon

# 6. Xác minh profile đang enforce
sudo aa-status | grep backup

So Sánh SELinux Và AppArmor: Nên Chọn Cái Nào?

Câu hỏi "SELinux hay AppArmor?" xuất hiện trong gần như mọi cuộc tranh luận về bảo mật Linux. Câu trả lời thành thật? Không có cái nào tốt hơn tuyệt đối — mỗi hệ thống có điểm mạnh riêng:

Tiêu chíSELinuxAppArmor
Cơ chế kiểm soátDựa trên nhãn bảo mật (label/inode)Dựa trên đường dẫn tệp (path)
Độ chi tiếtRất cao — kiểm soát đến từng system callTrung bình — kiểm soát theo tệp và capability
Độ phức tạpCao — cần thời gian học và thực hànhThấp hơn — profile dễ đọc và viết
Distro mặc địnhRHEL, Fedora, CentOS, AlmaLinux, Rocky, openSUSE (mới)Ubuntu, Debian
An toàn với hard linkCó — dựa trên inode nên hard link không bypass đượcKhông — hard link có thể tạo đường dẫn mới
MLS (Multi-Level Security)Có — phù hợp môi trường quân sự/chính phủKhông hỗ trợ
Công cụ tạo policyaudit2allow, audit2why, semanageaa-genprof, aa-logprof, aa-complain
Tích hợp containerTốt — Docker, Podman, Kubernetes đều hỗ trợTốt — Kubernetes hỗ trợ native từ 1.30

Vậy chọn cái nào?

  • Dùng distro nào thì dùng MAC mặc định của nó — RHEL dùng SELinux, Ubuntu dùng AppArmor. Đơn giản vậy thôi.
  • Cần tuân thủ MLS hoặc tiêu chuẩn quân sự/chính phủ → chắc chắn SELinux
  • Cần triển khai nhanh, đội ngũ chưa quen MAC → AppArmor sẽ dễ tiếp cận hơn
  • Môi trường multi-tenant hoặc high-security → SELinux mạnh hơn
  • Và điều quan trọng nhất: MAC nào được bật và duy trì cũng tốt hơn gấp nhiều lần so với không có MAC nào

Gia Cố Máy Chủ Web Production: Checklist Thực Hành

Lý thuyết đã đủ rồi. Giờ mình chia sẻ hai script checklist mà bạn có thể chạy ngay trên máy chủ production để kiểm tra nhanh tình trạng MAC.

Checklist cho máy chủ RHEL/CentOS với SELinux

#!/bin/bash
# checklist-selinux.sh — Kiểm tra và gia cố SELinux cho web server

echo "=== KIỂM TRA SELINUX ==="

# 1. Xác nhận SELinux đang enforcing
SELINUX_MODE=$(getenforce)
if [ "$SELINUX_MODE" != "Enforcing" ]; then
    echo "[CẢNH BÁO] SELinux đang ở chế độ: $SELINUX_MODE"
    echo "Chạy: sudo setenforce 1"
else
    echo "[OK] SELinux đang Enforcing"
fi

# 2. Kiểm tra context của thư mục web
echo -e "\n=== CONTEXT THƯ MỤC WEB ==="
ls -Zd /var/www/html/
ls -Zd /data/webapp/ 2>/dev/null

# 3. Kiểm tra booleans liên quan đến web server
echo -e "\n=== BOOLEANS WEB SERVER ==="
for bool in httpd_can_network_connect httpd_can_sendmail httpd_enable_homedirs httpd_can_network_connect_db; do
    VALUE=$(getsebool $bool 2>/dev/null | awk '{print $NF}')
    echo "$bool = $VALUE"
done

# 4. Kiểm tra cổng được phép
echo -e "\n=== CỔNG HTTP ĐƯỢC PHÉP ==="
semanage port -l | grep http_port_t

# 5. Kiểm tra AVC denial trong 24h qua
echo -e "\n=== AVC DENIAL (24H QUA) ==="
DENIALS=$(ausearch -m AVC -ts yesterday 2>/dev/null | grep -c "type=AVC")
echo "Số lượng denial: $DENIALS"
if [ "$DENIALS" -gt 0 ]; then
    echo "Chạy: sudo ausearch -m AVC -ts yesterday | audit2why"
fi

Checklist cho máy chủ Ubuntu/Debian với AppArmor

#!/bin/bash
# checklist-apparmor.sh — Kiểm tra và gia cố AppArmor cho web server

echo "=== KIỂM TRA APPARMOR ==="

# 1. Xác nhận AppArmor đang hoạt động
if sudo aa-status > /dev/null 2>&1; then
    ENFORCE=$(sudo aa-status 2>/dev/null | grep "profiles are in enforce" | awk '{print $1}')
    COMPLAIN=$(sudo aa-status 2>/dev/null | grep "profiles are in complain" | awk '{print $1}')
    echo "[OK] AppArmor đang hoạt động"
    echo "  Profiles enforce: $ENFORCE"
    echo "  Profiles complain: $COMPLAIN"
else
    echo "[CẢNH BÁO] AppArmor không hoạt động!"
fi

# 2. Kiểm tra profile của các dịch vụ quan trọng
echo -e "\n=== PROFILES DỊCH VỤ QUAN TRỌNG ==="
for svc in nginx apache2 mysqld sshd; do
    STATUS=$(sudo aa-status 2>/dev/null | grep $svc)
    if [ -n "$STATUS" ]; then
        echo "[OK] $svc có profile: $STATUS"
    else
        echo "[THIẾU] $svc không có profile AppArmor"
    fi
done

# 3. Kiểm tra log denial
echo -e "\n=== APPARMOR DENIAL (GẦN ĐÂY) ==="
DENIALS=$(sudo dmesg | grep -c "apparmor=\"DENIED\"" 2>/dev/null)
echo "Số lượng denial trong kernel log: $DENIALS"

# 4. Kiểm tra profile chưa được enforce
echo -e "\n=== PROFILES CẦN CHUYỂN SANG ENFORCE ==="
sudo aa-status 2>/dev/null | grep -A 100 "profiles are in complain mode" | head -20

Tích Hợp MAC Vào Pipeline DevSecOps

Trong môi trường DevSecOps hiện đại, MAC không nên được cấu hình thủ công trên từng máy chủ (đó là công thức cho sự thiếu nhất quán). Hãy tích hợp vào quy trình CI/CD:

# Ví dụ: Kiểm tra SELinux trong Ansible playbook
# file: roles/selinux-hardening/tasks/main.yml

- name: Đảm bảo SELinux ở chế độ enforcing
  ansible.posix.selinux:
    policy: targeted
    state: enforcing

- name: Thiết lập booleans cho web server
  ansible.posix.seboolean:
    name: "{{ item.name }}"
    state: "{{ item.state }}"
    persistent: true
  loop:
    - { name: httpd_can_network_connect, state: true }
    - { name: httpd_can_network_connect_db, state: true }
    - { name: httpd_can_sendmail, state: false }
    - { name: httpd_enable_homedirs, state: false }

- name: Thiết lập context cho thư mục web tùy chỉnh
  community.general.sefcontext:
    target: "/data/webapp(/.*)?"
    setype: httpd_sys_content_t
    state: present
  notify: Restorecon webapp
# Ví dụ: Kiểm tra AppArmor trong CI/CD pipeline
# file: .github/workflows/security-check.yml (trích đoạn)

- name: Kiểm tra AppArmor profiles
  run: |
    # Đảm bảo tất cả profiles trong enforce mode
    COMPLAIN_COUNT=$(sudo aa-status | grep "profiles are in complain" | awk '{print $1}')
    if [ "$COMPLAIN_COUNT" -gt 0 ]; then
      echo "THẤT BẠI: $COMPLAIN_COUNT profiles đang ở chế độ complain"
      sudo aa-status | grep "(complain)"
      exit 1
    fi
    echo "THÀNH CÔNG: Tất cả profiles đang enforce"

Xử Lý Sự Cố Thường Gặp

Dù bạn cấu hình cẩn thận đến đâu, sẽ có lúc gặp vấn đề. Đây là những tình huống mình thấy phổ biến nhất và cách xử lý.

SELinux: Ứng dụng bị chặn sau khi cập nhật

Đây là tình huống cực kỳ phổ biến — bạn chạy dnf update, Nginx cập nhật xong rồi không khởi động lại được. Đừng hoảng:

# Bước 1: Kiểm tra denial
sudo ausearch -m AVC -c nginx -ts recent

# Bước 2: Phân tích nguyên nhân
sudo ausearch -m AVC -c nginx -ts recent | audit2why

# Bước 3: Nếu do sai context sau cập nhật
sudo restorecon -Rv /etc/nginx/
sudo restorecon -Rv /var/log/nginx/

# Bước 4: Nếu cần policy mới
sudo ausearch -m AVC -c nginx -ts recent | audit2allow -M nginx_fix
# Kiểm tra tệp .te trước khi cài!
cat nginx_fix.te
sudo semodule -i nginx_fix.pp

AppArmor: Profile quá chặt gây lỗi ứng dụng

Nếu ứng dụng bỗng dưng lỗi mà log không rõ ràng, rất có thể AppArmor đang chặn thầm. Đây là quy trình debug:

# Bước 1: Chuyển profile sang complain để debug
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

# Bước 2: Chạy lại ứng dụng và thực hiện thao tác bị lỗi

# Bước 3: Quét log và cập nhật profile
sudo aa-logprof
# Duyệt từng violation và chọn Allow/Deny

# Bước 4: Chuyển lại enforce
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

# Bước 5: Xác minh ứng dụng hoạt động bình thường
sudo systemctl restart nginx
curl -I http://localhost

Câu Hỏi Thường Gặp (FAQ)

SELinux và AppArmor có thể chạy cùng lúc không?

Không nên. Cả hai đều là Linux Security Module (LSM) và chạy đồng thời sẽ gây xung đột. Hãy chọn một trong hai và tập trung vào nó. Nếu muốn chuyển đổi (ví dụ từ AppArmor sang SELinux trên Ubuntu), bạn phải tắt hoàn toàn cái cũ trước khi kích hoạt cái mới.

Nên bắt đầu với Enforcing hay Permissive?

Hệ thống mới cài? Bật Enforcing ngay từ đầu. Hệ thống đang chạy mà chưa bao giờ bật MAC? Bắt đầu với Permissive/Complain trong 1-2 tuần để thu thập log, tạo policy phù hợp, rồi mới chuyển sang Enforcing. Đừng bỏ qua bước này — chuyển thẳng sang Enforcing trên hệ thống phức tạp có thể làm sập dịch vụ ngay lập tức.

MAC có ảnh hưởng đến hiệu năng không?

Overhead rất nhỏ — thường dưới 2-5% CPU trong các benchmark thực tế. Nói thật, nếu bạn đang lo lắng về 2-5% performance overhead trong khi không bật MAC, thì ưu tiên của bạn có lẽ cần được xem xét lại. Toàn bộ hạ tầng cloud lớn (AWS, Google, Azure) đều chạy MAC ở chế độ enforcing mà không ai phàn nàn về hiệu năng.

Làm sao kiểm tra MAC có đang bảo vệ container Docker không?

Với SELinux, Docker tự động gán security context. Kiểm tra bằng: docker inspect --format='{{.HostConfig.SecurityOpt}}' container_name. Với AppArmor, Docker sử dụng profile mặc định docker-default. Kiểm tra bằng: docker inspect --format='{{.AppArmorProfile}}' container_name. Bạn cũng có thể tạo custom profile cho từng container riêng nếu cần kiểm soát chặt hơn.

openSUSE chuyển sang SELinux — tôi đang dùng openSUSE cũ với AppArmor, có cần chuyển không?

Không bắt buộc. Các cài đặt hiện có vẫn giữ AppArmor và tiếp tục được hỗ trợ. Tuy nhiên, nếu bạn cài mới Tumbleweed (từ snapshot 20250211) hoặc Leap 16 trở đi, SELinux sẽ là mặc định. Nếu muốn chuyển đổi trên hệ thống hiện có, hãy lên kế hoạch cẩn thận: tắt AppArmor, cài SELinux, relabel toàn bộ filesystem, và test kỹ trong Permissive trước khi bật Enforcing. Không phải việc làm trong 5 phút đâu.

Về Tác Giả Editorial Team

Our team of expert writers and editors.