Cơ Chế Bảo Mật Trong Container: Namespace, Cgroups, Seccomp, AppArmor và SELinux
Trong vài năm gần đây, container (như Docker, Kubernetes) đã trở thành một phần không thể thiếu trong quy trình phát triển và triển khai phần mềm hiện đại. Tuy nhiên, nhiều người chỉ dừng lại ở việc sử dụng container mà chưa thật sự hiểu rõ cách thức hoạt động và cơ chế bảo mật bên trong chúng.
Vậy container bảo vệ ứng dụng và hệ thống như thế nào? Bài viết này sẽ giúp bạn hiểu được 4 trụ cột bảo mật quan trọng của container: namespace, cgroups, seccomp, và AppArmor/SELinux — cùng các ví dụ thực tế khi triển khai bằng Docker.
1. Bối Cảnh: Tại Sao Container Xuất Hiện?
Trước Khi Có Máy Ảo
Trước đây, ứng dụng được triển khai bằng cách cài đặt mỗi ứng dụng trên một máy chủ riêng biệt vì các lý do:
- Bảo mật: Tránh ảnh hưởng chéo giữa các ứng dụng khi có sự cố(bị tấn công, máy chủ sập kéo theo tất cả ứng dụng khác sập theo).
- Quản lý tài nguyên: Tránh chiếm dụng lẫn nhau.
- Xung đột thư viện: Các ứng dụng khác nhau cần các phiên bản khác nhau của cùng một thư viện. Nếu cài trên cùng một máy chủ có thể gây xung đột
Nhược điểm là:
- Chi phí cao: khi có ứng dụng mới cần phải mua thêm một máy chủ mới
- Lãng phí tài nguyên nếu ứng dụng không sử dụng hết công suất máy chủ
Máy Ảo (Virtual Machine)
Máy ảo giải quyết một phần vấn đề trên bằng cách cho phép nhiều hệ điều hành chạy song song trên cùng một máy chủ thông qua hypervisor như VMWare, Hyper-V, XenServer...
- Ưu điểm
- Tăng hiệu suất sử dụng phần cứng, cách ly tốt - Nhược điểm
- Mỗi máy ảo cần hệ điều hành riêng → tốn RAM, CPU
- Khởi động chậm: máy ảo phải khởi động hệ điều hành như một máy tính thật sự
- Chi phí: mỗi một hệ điều hành trong máy ảo cần giấy phép (license) để sử dụng
Container
Container xuất hiện như một giải pháp nhẹ hơn, sử dụng chung kernel của máy chủ và chỉ đóng gói các thư viện, mã nguồn cần thiết.
- Ưu điểm
- Nhẹ, nhanh: không giả lập hệ điều hành và kernel vì dùng chung kernel với máy chủ
- Khởi động nhanh
- Cài được nhiều ứng dụng trên một máy chủ vì mỗi container nhẹ hơn một máy ảo nhiều
- Dễ triển khai ở nhiều môi trường
- Không tốn chi phí giấy phép - Nhược điểm
- Không cách ly hoàn toàn như máy ảo
- Dùng chung kernel với máy chủ → dễ bị khai thác nếu không bảo vệ đúng cách
2. Cơ Chế Bảo Mật Chính Trong Container
Namespace – Cách Ly Tài Nguyên Hệ Thống
Namespace là cơ chế của Linux để tách biệt không gian tài nguyên giữa các tiến trình. Mỗi loại namespace sẽ cách ly một khía cạnh khác nhau:
Namespace | Cách Ly | Ví dụ |
---|---|---|
pid | Tiến trình | PID trong container bắt đầu từ 1, không thấy được tiến trình bên ngoài |
net | Mạng | Container có IP riêng, bảng định tuyến riêng |
mnt | Hệ thống tập tin | File system riêng biệt cho mỗi container |
uts | Hostname/domain | Container có hostname riêng |
ipc | Giao tiếp tiến trình | Tách biệt vùng nhớ chia sẻ (shared memory) |
user | UID/GID | Root trong container khác root trên máy chủ |
Máy chủ tạo và quản lý namespace cho các container.
Nếu không có namespace, một tiến trình ở container này có thể thấy và tương tác với tiến trình ở container khác.
Ví dụ với Docker:
docker run -it --name test-container --hostname mycontainer ubuntu bash
Cgroups – Giới Hạn và Theo Dõi Tài Nguyên
Cgroup (Control Group) giúp giới hạn tài nguyên mà container sử dụng.
Khi chạy container, các tiến trình của container sẽ được đặt bên trong một cgroup.
Cgroup cung cấp các khả năng sau:
- Giới hạn tài nguyên của tiến trình
- Thiết lập ưu tiên tài nguyên khi có nhiều tiến trình sử dụng
- Theo dõi: giới hạn tài nguyên được theo dõi và báo cáo ở cấp độ cgroup
- Điều khiển: thay đổi trạng thái (đóng băng, dừng và tái khởi động) của mọi tiến trình trong một cgroup
Ví dụ giới hạn tài nguyên trong Docker:
docker run -it --cpus=".5" --memory="256m" ubuntu
Seccomp – Chặn Gọi Hệ Thống Nguy Hiểm
Seccomp (Secure Computing Mode) là một tính năng của kernel cho phép chặn các syscall nguy hiểm — vốn là cửa ngõ để ứng dụng giao tiếp với hệ điều hành.
Một số ví dụ về syscall:
- Clone cho phép sao chép namespace
- iopl cho phép thay đổi cấp độ quyền hạn I/O của kernel
Nếu kẻ xấu tấn công ứng dụng, chúng có thể lợi dụng syscall để tương tác với máy chủ.
Seccomp ngăn chặn các syscall nguy hiểm, giảm thiểu đáng kể cơ hội bị tấn công.
Seccomp trong docker mặc định ngăn chặn 44 syscall trong tổng số hơn 300 syscall.
Ví dụ Docker với seccomp profile:
Tạo profile cho phép 4 quyền read, write, exit, sigreturn:
{
"defaultAction": "SCMP_ACT_ERRNO",
"archMap": [
{
"architecture": "SCMP_ARCH_X86_64",
"subArchitectures": [
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
]
}
],
"syscalls": [
{
"names": [
"read",
"write",
"exit",
"sigreturn"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
docker run --security-opt seccomp=/path/to/custom-seccomp.json ubuntu
AppArmor & SELinux – Quản Lý Truy Cập Hệ Thống
Cả AppArmor và SELinux đều là Mandatory Access Control (MAC) — cơ chế bảo vệ cấp kernel nhằm kiểm soát quyền truy cập của ứng dụng lên file, thư mục và tài nguyên hệ thống.
Điểm khác nhau giữa chúng nằm ở cách thức thực hiện và độ phức tạp trong thiết lập quản lý.
Đặc điểm | AppArmor | SELinux |
---|---|---|
Dựa trên | Đường dẫn | Nhãn (label) |
Tính dễ sử dụng | Dễ cho người mới | Phức tạp hơn, chuyên sâu |
Phân phối chính | Ubuntu, Debian | CentOS, Fedora, RHEL |
Hiệu suất | Nhẹ, nhanh | Tối ưu cho môi trường lớn |
Ví dụ dùng AppArmor với Docker:
docker run --security-opt apparmor=docker-default nginx
3. So Sánh Mức Độ Cách Ly Giữa Container Và Máy Ảo
Container có tốc độ và hiệu quả tài nguyên cao hơn máy ảo, nhưng mức độ cách ly thấp hơn vì:
- Máy ảo có kernel riêng, không thể truy cập kernel của máy chủ.
- Container dùng chung kernel với máy chủ, nếu container bị tấn công thì có thể truy cập kernel, từ đó ảnh hưởng hệ thống.
Để thực hiện tấn công lên máy chủ từ máy ảo, kẻ tấn công cần vượt qua 3 rào cản sau:
- Kernel máy ảo: tấn công và vượt qua kernel trong máy ảo
- Hypervisor: từ kernel của máy ảo tấn công/vượt qua hypervisor
- Hệ thống máy chủ: từ hypervisor tấn công lên máy chủ
Xét đến container, do sử dụng chung kernel với máy chủ nên bước thứ 2 đã được bỏ qua hoàn toàn.
Dữ liệu thống kê thực tế cho thấy container gặp nhiều sự cố bảo mật hơn máy ảo:
- Máy ảo: ~50 sự cố bảo mật (từ 2007 đến nay)
- Container: 50–60 sự cố chỉ trong khoảng 2016–nay
4. Biện Pháp Cải Thiện Bảo Mật Container
Để nâng mức độ bảo mật của container cho giống máy ảo, chúng ta có thể sử dụng các biện pháp sau:
- gVisor: lớp kernel user-space giúp ngăn container truy cập kernel thật
- Kata Containers: container chạy bên trong một máy ảo nhẹ
- Rootless containers: container chạy với user không phải root
- AppArmor/SELinux read-only: cấu hình container không thể ghi vào vùng dữ liệu nhạy cảm
✅ Tổng Kết
Container là công cụ mạnh mẽ giúp đơn giản hóa việc đóng gói và triển khai ứng dụng, nhưng đi kèm đó là thách thức về bảo mật. Việc hiểu rõ các cơ chế như namespace, cgroups, seccomp, AppArmor và SELinux sẽ giúp chúng ta:
- Nâng cao khả năng phòng thủ cho hệ thống
- Hạn chế tối đa thiệt hại nếu container bị khai thác
- Tự tin hơn khi đưa container vào các môi trường production quan trọng