Tự hack để biết cách tự bảo vệ (Ft. AppArmor)
Kể từ năm 2025, số lượng người dùng Linux cá nhân tăng đáng kể, qua đó đặt ra nhu cầu đánh giá lại thiết kế bảo mật dành cho môi trường Desktop.
Thiết kế bảo mật trên Linux
Thiết kế bảo mật trên một OS nói chung và Linux nói riêng (về mặt kỹ thuật thì vẫn là chung vì mỗi distro lại có một số sai khác nhất định về cấu hình) là một vấn đề phức tạp. Đặc biệt là khi không hề có một tài liệu chính thống mà chỉ tồn tại ở dạng phân mảnh của các distro khác nhau (như Debian, Redhat, ...) và trong tài liệu của kernel. Dù vậy, tôi cho rằng các cơ chế bảo mật của Linux bao gồm các vấn đề cơ bản:
Kiểm soát việc sử dụng và chia sẻ tài nguyên.
Giảm thiểu rủi ro và tác động của cuộc tấn công.
Thiết kế việc sử dụng và chia sẻ tài nguyên
Một trong những chức năng cốt lõi của hệ điều hành là kiểm soát việc chia sẻ tài nguyên. Việc hệ điều hành quyết định đối tượng nào được phép sử dụng tài nguyên nào không chỉ là bài toán phân phối tài nguyên, mà còn là nền tảng của cơ chế kiểm soát truy cập. Trên Linux, tài nguyên được biểu diễn dưới dạng các đối tượng như file, shared memory segment, socket, v.v. Việc kiểm soát truy cập được thực hiện dựa trên tập hợp các credential gắn với tiến trình và thông tin ngữ cảnh của đối tượng. Mỗi đối tượng có chủ sở hữu được xác định thông qua UID (người dùng) và GID (nhóm người dùng).
Thực vậy, trong một hệ thống Linux sử dụng rất nhiều user nhằm tách biệt việc sử dụng tài nguyên. Một ví dụ điển hình là một máy chủ web, ta có một số user/group cơ bản sau:
User web, thường là
www-datahoặcnginxchỉ được kiểm soát dữ liệu của web server, ví dụ các file nằm trongDOCUMENT_ROOT. Đây là các daemon user được tạo ra bởi dịch vụ apache2 hoặc nginx.Database user (nếu database nằm trên
localhost) được phép quản lý dữ liệu của database.User của quản trị viên, người dùng thường, bao gồm user
rootcó uid là0, sở hữu home folder nằm tại/root/nhưng có quyền quản lý toàn bộ tài nguyên hệ thống. Các người dùng khác, theo cấu hình mặc định, có home folder nằm trong/home/và có uid bắt đầu từ1000trở đi.Các user daemon khác của hệ thống nhằm quản lý các tài nguyên khác.
Trong mô hình này, user quản lý web service không có quyền truy cập tài nguyên của các user khác. Việc web sử dụng database phải được thông qua một kết nối TCP nhờ sử dụng module của web service. Dịch vụ web cũng phải cung cấp thông tin xác thực thông qua kết nối TCP để database xác thực phiên truy cập. Trong khi đó, user thường (uid 1000) có thể đọc được dữ liệu nằm trong DOCUMENT_ROOT của web, nhưng không thể chỉnh sửa. Các cấu hình này có thể khác biệt với những distro khác nhau. Ví dụ: với một hệ thống vhost thì mỗi user thường là chủ sở hữu của một DOCUMENT_ROOT và quyền truy cập lúc này tương đương với một user daemon của nginx hay apache2 tạo ra. Cơ chế này là cơ chế phân quyền dựa trên danh tính, được gọi là Discretionary Access Control.
Tuy nhiên, model thiết kế này gặp phải 2 bài toán lớn trong thực tế sử dụng:
Phải làm thế nào nếu đối tượng cần sử dụng tài nguyên được sở hữu bởi một chủ sở hữu khác? Ví dụ như người dùng hiện tại muốn đổi mật khẩu, nhưng mật khẩu lại được lưu trong
/etc/shadowvốn được sở hữu bởirootvà file cũng không hề cho phép đọc ghi?Dữ liệu được sử dụng bởi các đối tượng trong hệ thống phải đảm bảo tính toàn vẹn. Trong mô hình mặc định, các đối tượng có cùng chủ sở hữu có thể truy cập tài nguyên của nhau thông qua cơ chế phân quyền dựa trên danh tính. Tuy nhiên, không phải đối tượng nào cũng đáng tin cậy. Vì vậy, hệ điều hành cần có cơ chế tách biệt tài nguyên nhằm giới hạn phạm vi truy cập của từng đối tượng. Qua đó, các vi phạm tính toàn vẹn dữ liệu cũng bị giới hạn phạm vi ảnh hưởng.
Cấp quyền qua suid để kiểm soát tài nguyên => nguy hiểm (mặc dù sudoer yêu cầu user nằm trong group sudo, và phải xác thực)
- least privilege -> cap , drop privilege (ví dụ bash drop suid)
Tách space
sandbox (tổng hợp nhiều cơ chế, gồm cả least privliege, drop privilege, dac)
namespace: cho phép đối tượng được "nhìn thấy" tài nguyên nào
Giảm thiểu rủi ro khi bị tấn công
Vấn đề rủi ro: process luôn có nguy cơ bị exploit ->
Giảm xác suất bị tấn công -> least surface
Làm cho exploit khó hoạt động (mitigate exploit)
Giới hạn khả năng hành động sau khi bị khai thác (filter syscall, các cơ chế sandboxing hay cơ chế của DAC đã nói ở trên)
quản trị vân vân (của selinux /apparmor, ...)
Vấn đề mismatch với end-user.






