---
id: linux-selinux
title: "SELinux: cài và đặt mode"
shortTitle: "SELinux"
track: linux
trackTitle: "Linux & Shell Scripting"
order: 3
level: important
status: published
estimatedMinutes: 30
prerequisites:
  - linux-filesystem-permissions
next: linux-process-management
reviewedAgainst: 2026-10-15
sources:
  - title: "KodeKloud Engineer — 100 Days of DevOps"
    url: https://engineer.kodekloud.com/practice
  - title: "Red Hat — Changing SELinux states and modes"
    url: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/using_selinux/changing-selinux-states-and-modes_using-selinux
  - title: "getenforce(8)"
    url: https://man7.org/linux/man-pages/man8/getenforce.8.html
  - title: "setenforce(8)"
    url: https://man7.org/linux/man-pages/man8/setenforce.8.html
---

# SELinux: cài và đặt mode

SELinux là lớp policy của kernel, tách khỏi permission `rwx`. `ls -l` đúng mà process vẫn bị từ chối thì thường là AVC. Ubuntu và nhiều image mặc định dùng AppArmor, không có SELinux. Lab 100 Days chạy trên họ RHEL.

## Để làm gì

Bạn đọc được mode hiện tại, phân biệt `enforcing`, `permissive` và `disabled`, và biết lệnh nào đổi tạm, lệnh nào ghi vào file rồi cần reboot.

## Gồm những gì

- Gói trên RHEL: `selinux-policy-targeted`, `libselinux-utils`, `policycoreutils`.
- `getenforce`, `sestatus`, `setenforce 0` / `1`.
- `/etc/selinux/config`: `SELINUX=` và `SELINUXTYPE=`.

Bài này không viết policy mới, không dùng `semanage` hay `restorecon`. Permission `rwx` nằm ở bài trước.

## Dùng khi nào

Máy RHEL hoặc AlmaLinux, process bị từ chối dù owner và mode file đã đúng. Đọc `getenforce` trước khi `chmod 777`.

Đừng tắt SELinux trên production để "cho app chạy". Debug thì `permissive`: policy vẫn log AVC, không chặn.

## Kiến thức cốt lõi

Khi SELinux bật, kernel chạy một trong hai mode. Tắt hẳn là trạng thái thứ ba, kernel không nạp policy.

| Giá trị | `getenforce` in | Kernel làm gì |
| --- | --- | --- |
| `enforcing` | `Enforcing` | Áp policy, từ chối thao tác sai |
| `permissive` | `Permissive` | Không từ chối, chỉ ghi AVC |
| `disabled` | `Disabled` | Không nạp policy, không ghi AVC |

`setenforce` chỉ đổi giữa Enforcing và Permissive trên máy đang bật SELinux. Argument là `Enforcing` hoặc `1`, `Permissive` hoặc `0`. Mode Disabled không bật lại được bằng `setenforce`. Docs Red Hat: sửa `/etc/selinux/config` rồi reboot.

File `/etc/selinux/config`:

- `SELINUX=` nhận `enforcing`, `permissive`, hoặc `disabled`.
- `SELINUXTYPE=` trên RHEL 9 nhận `targeted` hoặc `mls`. `targeted` là policy mặc định.

`sestatus` in mode đang chạy và mode ghi trong file. Hai cột lệch nhau khi vừa `setenforce` mà chưa sửa file, hoặc vừa sửa file mà chưa reboot.

File tạo lúc SELinux tắt không có label. Đưa máy từ `disabled` sang `enforcing` mà chưa relabel thì boot có thể hỏng. Docs Red Hat: về `permissive` trước, `fixfiles -F onboot`, reboot, đọc AVC, rồi mới `enforcing`. Tắt hẳn trên RHEL 9 dùng `selinux=0` trên kernel command line, không phải chỉ sửa một dòng config.

## Lệnh và code mẫu

Chỉ đọc trên máy hiện tại. Đừng `setenforce` và đừng sửa `/etc/selinux/config` trừ khi đó là VM lab.

```bash
command -v getenforce || printf 'May nay khong co SELinux.\n'
getenforce
sestatus
```

Cài gói trên VM họ RHEL, khi `rpm -q` báo thiếu:

```bash
sudo dnf install -y selinux-policy-targeted libselinux-utils policycoreutils
```

Đổi tạm trên VM lab đang Enforcing, không reboot:

```bash
sudo setenforce 0
getenforce
sudo setenforce 1
```

Ghi mode bền, chỉ trên VM lab. Sửa xong phải reboot. Giữ một session console trước khi reboot.

```text
SELINUX=enforcing
SELINUXTYPE=targeted
```

Sau reboot, `getenforce` phải in đúng giá trị vừa ghi.

## Thực hành

1. Chạy `command -v getenforce`. Không có lệnh thì dừng. Máy đang dùng AppArmor, không phải lab SELinux.
2. Chạy `getenforce` và `sestatus`. Ghi Current mode và Mode from config file.
3. Trên VM lab RHEL, `rpm -q selinux-policy-targeted libselinux-utils policycoreutils`. Thiếu thì cài khối `dnf` ở trên.
4. Đừng `setenforce` trên máy đang chạy dịch vụ. VM lab thì `setenforce 0`, đọc `getenforce`, rồi `setenforce 1`.

## Kết quả mong đợi

- Không có `getenforce`: bài dừng ở bước 1, không cài SELinux đè AppArmor.
- Có SELinux: `getenforce` in một trong ba từ `Enforcing`, `Permissive`, `Disabled`.
- `sestatus` có Current mode và Mode from config file.

## Checklist

- [ ] Đọc `getenforce` trước khi kết luận permission `rwx` đã đủ.
- [ ] Debug bằng `permissive`, không bằng `disabled`.
- [ ] `setenforce` không đổi máy đang `Disabled`.
- [ ] Sửa `/etc/selinux/config` rồi reboot, rồi mới tin mode mới.

## Thẻ ôn

### linux-selinux-mode
kind: distinguish
cue: `enforcing` chặn. `permissive` chỉ ghi AVC. `disabled` không nạp policy. `setenforce 0` không tắt SELinux.

Q: App bị từ chối dù `ls -l` đã đúng. Có người bảo `setenforce 0` để tắt SELinux cho app chạy. `setenforce 0` đổi sang mode nào, và mode nào mới thôi nạp policy?

A: `setenforce 0` đưa máy sang Permissive. Policy vẫn chạy, kernel ghi AVC, không từ chối. `Disabled` mới là không nạp policy và không ghi AVC. Từ Disabled không bật lại bằng `setenforce`. Debug thì Permissive, đọc AVC, rồi về Enforcing. Đừng `disabled` trên máy đang phục vụ.

### linux-selinux-persist
kind: command
cue: `setenforce` mất sau reboot. Mode bền nằm ở `SELINUX=` trong `/etc/selinux/config`, rồi reboot. `sestatus` in cả mode đang chạy và mode trong file.

Q: `getenforce` in `Permissive` sau `setenforce 0`. Sáng hôm sau máy Enforcing lại. Mode bền ghi ở đâu, và hai cột của `sestatus` khác nhau chỗ nào?

A: Mode bền là `SELINUX=` trong `/etc/selinux/config`. Sửa xong phải reboot. `setenforce` chỉ đổi process đang chạy. `sestatus` in Current mode là mode kernel đang dùng, và Mode from config file là dòng trong file. Hai cột lệch nghĩa là vừa đổi tạm, hoặc vừa sửa file chưa reboot. Từ `disabled` sang `enforcing` còn cần relabel; docs Red Hat bắt qua `permissive` trước.

## Lỗi thường gặp

**`setenforce 0` rồi tưởng SELinux đã tắt.** Máy đang Permissive, AVC vẫn ghi. Tắt hẳn là `disabled` hoặc `selinux=0`, và mất log để debug.

**Sửa `/etc/selinux/config` rồi không reboot.** `getenforce` vẫn in mode cũ. `sestatus` cho thấy file đã khác mode đang chạy.

**Đưa máy từ `disabled` thẳng sang `enforcing` rồi reboot.** File tạo lúc tắt không có label. Boot có thể fail. Docs Red Hat: `permissive` trước, `fixfiles -F onboot`, rồi mới `enforcing`.

**Cài SELinux lên Ubuntu đang chạy AppArmor.** Lab này dành cho họ RHEL. Không có `getenforce` thì dừng.

## Nguồn

1. [KodeKloud Engineer — 100 Days of DevOps](https://engineer.kodekloud.com/practice) — đề cương ngày cài và cấu hình SELinux. Trang practice cần đăng nhập. Bài này viết lại lệnh, không chép lab.
2. [Changing SELinux states and modes](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/using_selinux/changing-selinux-states-and-modes_using-selinux) — Red Hat RHEL 9, ba giá trị `SELINUX=`, gói cần có, relabel khi bật lại.
3. [getenforce(8)](https://man7.org/linux/man-pages/man8/getenforce.8.html) — in `Enforcing`, `Permissive`, hoặc `Disabled`.
4. [setenforce(8)](https://man7.org/linux/man-pages/man8/setenforce.8.html) — `1`/`Enforcing`, `0`/`Permissive`. Không bật máy đang Disabled.

## Tiếp theo

[Process và systemd](./02-process-management.md)
