SELinux: context, port và boolean
Thực hiện trên server của bạn, rồi kiểm tra từng tiêu chí.
Vì sao cần học
Khi gặp lỗi do SELinux, nhiều người chọn cách tắt nó, và bỏ đi một lớp bảo vệ quan trọng: dù kẻ tấn công chiếm được tiến trình web, SELinux vẫn chặn nó đọc file của dịch vụ khác. Cách làm đúng là đọc audit log, hiểu policy muốn gì và cấp đúng nhãn. RHCSA chấm bài trên máy SELinux enforcing.
Mục tiêu
- Giải thích SELinux type enforcement: tiến trình có domain, file và port có type.
- Đọc context bằng
ls -Z,ps -Z, và tìm lỗi bằngausearch. - Gán port bằng
semanage port, gán file context bền vững bằngsemanage fcontext+restorecon. - Tra và bật boolean bằng
getsebool/setsebool -P.
Điều kiện tiên quyết
- Bài Firewall với firewalld.
getenforcetrảEnforcing.
Mental model
Quyền Unix (owner, group, mode) được kiểm tra trước. Sau đó SELinux kiểm tra thêm: domain của tiến trình có được làm việc này với type của đối tượng không?
httpd (domain httpd_t) ──đọc──▶ /srv/kdc-www/index.html (type ?)
httpd (domain httpd_t) ──bind──▶ tcp/8088 (type ?)
- File trong
/var/www/htmlcó typehttpd_sys_content_t: httpd đọc được. - File mới trong
/srvnhận typevar_t: httpd không đọc được, dù quyền Unix cho phép. - Port 8088 chưa có type web: httpd không bind được. Port 80, 443, 8443 thuộc
http_port_t.
chcon đổi nhãn ngay nhưng mất khi relabel toàn hệ thống. semanage fcontext ghi quy tắc vào policy; restorecon áp quy tắc đó. Luôn dùng cách thứ hai.
Thực hành (Guided Lab)
1. Kiểm tra trạng thái
getenforce
sestatus
grep ^SELINUX= /etc/selinux/config
ps -eZ | grep -E 'sshd|systemd' | head -3
ls -Zd /var/www /srv
Giải thích lệnh và tham số
getenforce in mode SELinux hiện tại; sestatus in thông tin chi tiết. ps -eZ gộp xem mọi tiến trình (-e) và context SELinux (-Z); ls -Zd xem context (-Z) của chính thư mục (-d). grep ^SELINUX= lọc dòng cấu hình mode khi boot. setenforce 1 chuyển runtime sang Enforcing; không tự sửa /etc/selinux/config.
Nếu getenforce trả Permissive, chạy sudo setenforce 1 và sửa /etc/selinux/config thành SELINUX=enforcing.
2. Dựng site trên port và thư mục không mặc định
sudo dnf install -y httpd policycoreutils-python-utils
sudo install -d /srv/kdc-www
echo '<h1>KDC-SELINUX</h1>' | sudo tee /srv/kdc-www/index.html
sudo tee /etc/httpd/conf.d/kdc-www.conf <<'EOF'
Listen 8088
<VirtualHost *:8088>
DocumentRoot /srv/kdc-www
<Directory /srv/kdc-www>
Require all granted
</Directory>
</VirtualHost>
EOF
sudo apachectl configtest
sudo systemctl enable --now httpd
Giải thích lệnh và tham số
apachectl configtest kiểm tra cú pháp cấu hình Apache trước khi bật service. Các dòng Listen, VirtualHost, DocumentRoot là cấu hình trong file, không phải lệnh shell. Nếu service không chạy, đọc trạng thái/log để phân biệt lỗi cú pháp với SELinux từ chối bind port.
Lệnh cuối thất bại. Thu thập evidence:
systemctl status httpd --no-pager | tail -5
sudo ausearch -m AVC -ts recent | tail -5
Giải thích lệnh và tham số
ausearch tìm bản ghi audit: -m AVC chọn loại thông điệp SELinux Access Vector Cache, -ts recent chọn thời điểm bắt đầu gần đây. tail -5 giới hạn số dòng hiển thị, không thay phạm vi truy vấn của ausearch.
Audit log ghi denied { name_bind } cho httpd_t trên port 8088: SELinux chặn, không phải lỗi cấu hình Apache.
3. Gán type cho port
sudo semanage port -a -t http_port_t -p tcp 8088
sudo semanage port -l | grep ^http_port_t
sudo systemctl restart httpd
curl -s http://127.0.0.1:8088/ | head -3
Giải thích lệnh và tham số
semanage port quản lý mapping port ↔ SELinux type: -a thêm, -t http_port_t chọn type, -p tcp chọn giao thức, 8088 là port. -l liệt kê mapping. Nếu port đã có mapping phù hợp để chỉnh, -m là sửa thay cho -a thêm. Các thay đổi này lưu trong policy local, khác mở port trong firewall.
httpd đã chạy, nhưng trả trang lỗi 403 Forbidden. Đọc evidence lần nữa:
ls -Z /srv/kdc-www/index.html
sudo ausearch -m AVC -ts recent | tail -3
Giải thích lệnh và tham số
ls -Z in SELinux context của file. ausearch -m AVC -ts recent lọc audit theo loại AVC (-m) và thời điểm bắt đầu gần đây (-ts). tail -3 chỉ lấy ba dòng cuối.
4. Gán file context bền vững
sudo semanage fcontext -a -t httpd_sys_content_t '/srv/kdc-www(/.*)?'
sudo restorecon -Rv /srv/kdc-www
ls -Z /srv/kdc-www/index.html
curl -s http://127.0.0.1:8088/
Giải thích lệnh và tham số
semanage fcontext -a -t httpd_sys_content_t '<mẫu>' khai báo type mặc định cho đường dẫn khớp regex. Mẫu /srv/kdc-www(/.*)? gồm thư mục và mọi đường dẫn con; nháy đơn giữ mẫu nguyên vẹn. restorecon -Rv áp mapping lên file thật (-R đệ quy, -v in thay đổi). ls -Z xác nhận type thực tế sau khi áp dụng.
5. Boolean (tham khảo, không chấm)
Boolean bật/tắt các nhóm quyền có sẵn trong policy:
getsebool -a | grep httpd_can_network_connect
sudo setsebool -P httpd_can_network_connect on
sudo setsebool -P httpd_can_network_connect off
Giải thích lệnh và tham số
getsebool -a liệt kê mọi boolean SELinux; setsebool -P <tên> on/off đổi boolean và lưu bền vững nhờ -P. Đây là P hoa, khác -p tcp của semanage. Thử bật rồi tắt theo bài để không giữ quyền kết nối mạng rộng hơn cần thiết.
-P lưu bền vững. Boolean này cần khi Apache làm reverse proxy tới một backend (Module 04).
Tự kiểm tra (Verification)
getenforce
sudo semanage port -l | grep 8088
sudo semanage fcontext -l -C
ls -Z /srv/kdc-www/index.html
curl -s http://127.0.0.1:8088/
Giải thích lệnh và tham số
semanage fcontext -l -C liệt kê (-l) chỉ các tùy chỉnh local (-C). -d trong semanage port/fcontext ở phần dọn dẹp xóa mapping local; không có nghĩa xem thư mục như ls -d.
semanage fcontext -l -C chỉ liệt kê các quy tắc bạn thêm. Chọn server và bấm Kiểm tra kết quả.
Lỗi thường gặp
setenforce 0"để thử": lỗi biến mất nên bạn không học được gì, và máy mất lớp bảo vệ. Nếu cần chẩn đoán, đặt riêng một domain sang permissive (semanage permissive -a httpd_t) rồi bỏ đi ngay.mvfile từ thư mục home vào/srv/kdc-www: file giữ nhãn cũ.cpthì nhận nhãn của thư mục đích. Saumv, chạyrestorecon.- Dùng
chcon: đúng tới lần relabel tiếp theo. semanage port -abáo đã tồn tại: port thuộc type khác, dùng-mđể sửa.
Ghi chú production
- Nhiều sự cố "permission denied" trên RHEL là SELinux. Hãy kiểm tra audit log trước khi đổi quyền file.
setroubleshoot-servercài thêm lệnhsealert, giải thích AVC bằng ngôn ngữ dễ đọc và gợi ý lệnh sửa. Đọc kỹ trước khi làm theo.- Container trên RHEL cũng được SELinux bảo vệ; Module 05 sẽ gặp tùy chọn
:Zkhi mount volume.
Ghi chú Ubuntu
Ubuntu dùng AppArmor, không có SELinux; bài này chỉ làm được trên RHEL-family.
Dọn dẹp
sudo systemctl disable --now httpd
sudo rm -f /etc/httpd/conf.d/kdc-www.conf
sudo semanage port -d -t http_port_t -p tcp 8088
sudo semanage fcontext -d '/srv/kdc-www(/.*)?'
sudo rm -rf /srv/kdc-www
Giải thích lệnh và tham số
systemctl disable --now bỏ cấu hình tự chạy khi boot và dừng service ngay. daemon-reload yêu cầu systemd đọc lại unit file sau khi sửa/xóa. rm -f xóa file và không hỏi xác nhận; -r thêm xóa đệ quy thư mục cùng nội dung, nên -rf gộp hai tùy chọn này. semanage port -d xóa mapping port; -t http_port_t chọn type và -p tcp chọn giao thức. semanage fcontext -d xóa quy tắc đường dẫn local được chỉ định.