Một service chỉ cần mở port 80 không nhất thiết phải chạy với toàn bộ quyền root. Linux capabilities chia đặc quyền superuser thành các đơn vị nhỏ hơn, cho phép tiến trình nhận đúng khả năng cần thiết—chẳng hạn bind port đặc quyền—mà vẫn chạy dưới tài khoản không phải root.
Capabilities giảm blast radius nhưng không biến code thành an toàn. Cấp nhầm một quyền mạnh, để bounding set quá rộng hoặc gắn capability lên interpreter có thể tạo đường leo thang quyền mới. Vì vậy cần hiểu các capability set và kiểm thử toàn bộ vòng đời triển khai.
1. Capabilities giải quyết vấn đề gì?
Unix truyền thống phân biệt root và non-root: UID 0 vượt qua nhiều phép kiểm tra mà user thường không vượt được. Từ Linux 2.2, kernel tách các đặc quyền này thành capability độc lập và kiểm tra capability của thread cho từng thao tác. Tài liệu chuẩn nằm tại capabilities(7).
| Capability ví dụ | Cho phép | Lưu ý |
|---|---|---|
CAP_NET_BIND_SERVICE | Bind port Internet đặc quyền | Phù hợp cho web service non-root |
CAP_NET_RAW | Dùng RAW/PACKET socket | Mạnh hơn nhu cầu TCP/UDP thông thường |
CAP_CHOWN | Thay owner file | Có thể phá ranh giới ownership |
CAP_DAC_OVERRIDE | Bỏ qua nhiều kiểm tra quyền file | Blast radius rất lớn |
CAP_SYS_ADMIN | Nhiều thao tác quản trị khác nhau | Rất rộng; không phải “root-lite” an toàn |
2. Năm capability set cần biết
- Permitted: tập quyền mà thread có thể đưa vào effective.
- Effective: quyền kernel thực sự dùng khi kiểm tra thao tác hiện tại.
- Inheritable: tham gia quy tắc truyền quyền qua
execve(). - Bounding: trần giới hạn các capability có thể nhận qua việc chạy executable mới.
- Ambient: quyền được giữ qua
execve()của chương trình không privileged; mỗi quyền ambient phải đồng thời nằm trong permitted và inheritable.
Child tạo bằng fork() thừa hưởng bản sao các set của parent. execve() tính lại các set dựa trên state tiến trình, file capability, bounding set và secure bits. Đây là lý do “process đang có quyền gì” và “binary có capability gì” là hai câu hỏi khác nhau.
Bounding set không phải danh sách quyền đang hoạt động; nó là trần. Thu hẹp trần ngăn tiến trình và chương trình con giành lại quyền ngoài phạm vi dự kiến.
3. Ví dụ: cho binary non-root mở port 80
Giả sử binary riêng nằm tại /usr/local/bin/webapp. Gắn file capability:
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/webapp
getcap /usr/local/bin/webappKết quả dự kiến:
/usr/local/bin/webapp cap_net_bind_service=epp đưa capability vào permitted khi chạy file; cờ effective làm các quyền permitted mới có hiệu lực. Chạy ứng dụng bằng user chuyên dụng và xác nhận nó bind được port 80 mà UID vẫn không phải 0.
Rollback:
sudo setcap -r /usr/local/bin/webapp
getcap /usr/local/bin/webappsetcap(8) cũng hỗ trợ -v để xác minh capability đã gắn.
4. File capability có những bẫy nào?
File capabilities được lưu trong extended attribute security.capability. Điều này ảnh hưởng trực tiếp tới deployment:
- Thay binary bằng file mới thường làm capability biến mất; pipeline phải gắn lại và verify.
- Một số cách copy, archive, filesystem hoặc backup không giữ xattr.
- Gắn capability lên binary dùng chung khiến mọi user được phép execute file đều đi qua cùng cơ chế cấp quyền.
- Không gắn capability mạnh lên shell, runtime hay interpreter đa dụng; chúng có thể chạy nội dung tùy ý với quyền đó.
- Hash/signature của artifact và capability metadata cần được kiểm toán độc lập.
- Mount option, namespace và policy LSM có thể làm kết quả khác dự kiến.
Với service do systemd quản lý, khai báo quyền trong unit thường dễ audit và không phụ thuộc xattr của artifact.
5. Cấp capability bằng systemd
[Unit]
Description=Web application
After=network.target
[Service]
User=webapp
Group=webapp
ExecStart=/usr/local/bin/webapp --listen=:80
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
Restart=on-failure
[Install]
WantedBy=multi-user.targetsystemd.exec(5) mô tả AmbientCapabilities= là cách cấp capability cho tiến trình non-root, còn CapabilityBoundingSet= loại mọi capability không được liệt kê khỏi bounding set và các set liên quan. NoNewPrivileges=yes ngăn tiến trình/con của nó nhận thêm quyền qua execve() từ setuid, setgid hoặc file capabilities.
Sau khi sửa unit:
sudo systemctl daemon-reload
sudo systemctl restart webapp.service
sudo systemctl status webapp.service
sudo journalctl -u webapp.service -n 100 --no-pager
6. File capability hay systemd?
| Tiêu chí | File capability | systemd capability |
|---|---|---|
| Phạm vi | Gắn với executable | Gắn với service unit |
| Artifact bị thay | Có thể mất xattr | Unit vẫn còn policy |
| Chạy thủ công | Vẫn có capability | Không có nếu chạy ngoài unit |
| Audit cấu hình | Dùng getcap | Review unit/drop-in |
| Phù hợp | Tool chuyên dụng cần quyền ở mọi nơi | Daemon được quản lý tập trung |
Không áp dụng cả hai theo thói quen. Hai cơ chế chồng nhau làm khó xác định nguồn quyền và có thể tạo hành vi khác giữa chạy thủ công với chạy dưới systemd.
7. Cách xem capability đang có
# File capability
getcap /usr/local/bin/webapp
sudo getcap -r /usr/local 2>/dev/null
# Process capability
getpcaps PID
grep '^Cap' /proc/PID/status
# Service configuration
systemctl show webapp.service \
-p User -p AmbientCapabilities -p CapabilityBoundingSet \
-p NoNewPrivileges/proc/PID/status hiển thị CapInh, CapPrm, CapEff, CapBnd và CapAmb dưới dạng bitmask hexadecimal. Có thể dùng công cụ libcap phù hợp để decode thay vì đọc bit bằng mắt.
systemd-analyze security webapp.service hữu ích để tìm hardening gap, nhưng điểm tổng hợp không thay thế threat model hay kiểm thử chức năng.
8. Quy trình tìm quyền tối thiểu
- Chạy service bằng user riêng, không cấp capability, để quan sát lỗi thực.
- Xác định syscall/tài nguyên bị từ chối qua log, audit hoặc trace có kiểm soát.
- Đối chiếu đúng capability trong
capabilities(7); tránh chọn quyền rộng chỉ vì hết lỗi. - Cấp một capability qua một cơ chế duy nhất.
- Thu hẹp bounding set và bật
NoNewPrivilegeskhi tương thích. - Chạy test chức năng, negative test và restart/upgrade test.
- Ghi lý do của từng capability trong source quản lý cấu hình.
Nếu ứng dụng chỉ cần port 80, một lựa chọn khác là để reverse proxy đã harden lắng nghe cổng public rồi forward tới service ở port cao. Giải pháp này có thể loại bỏ capability khỏi application hoàn toàn.
9. Capabilities không thay thế các lớp bảo vệ khác
- DAC/ACL vẫn kiểm soát quyền file khi capability không bypass chúng.
- SELinux/AppArmor có thể tiếp tục chặn thao tác dù process có capability.
- systemd sandboxing giới hạn filesystem, device, namespace và syscall.
- Seccomp giảm syscall khả dụng.
- Container/user namespace thay đổi phạm vi mà capability có hiệu lực; “root trong container” không đồng nghĩa root trên host, nhưng cấu hình sai vẫn nguy hiểm.
- Network policy/firewall vẫn cần thiết cho service có capability mạng.
10. Những capability cần đặc biệt thận trọng
CAP_SYS_ADMIN bao phủ một tập thao tác rất rộng và thường được gọi là capability “gom đủ thứ”. Nếu một phần mềm yêu cầu nó, hãy xác minh chính xác thao tác nào cần quyền, xem kernel/version có capability hẹp hơn và cân nhắc tách helper nhỏ.
CAP_DAC_OVERRIDE, CAP_SYS_PTRACE, CAP_NET_ADMIN, CAP_SYS_MODULE, CAP_SETUID, CAP_SETGID và CAP_SETPCAP cũng có thể mở rộng đáng kể tác động sau compromise. Tên capability không phản ánh đầy đủ mọi syscall được phép; luôn đọc man page của kernel đang vận hành.
11. Upgrade, backup và rollback
- Trong deployment, verify
getcapsau bước copy/rename cuối cùng. - Kiểm tra backup/restore có giữ xattr; diễn tập restore trên filesystem đích.
- Khi package manager thay binary, chạy lại kiểm tra policy thay vì giả định capability còn nguyên.
- Giữ unit/drop-in trong version control và dùng
systemd-deltađể phát hiện override. - Rollback gồm cả binary lẫn capability metadata.
- Cảnh báo khi xuất hiện file capability mới ngoài allowlist.
12. Checklist production
- Service chạy bằng user/group riêng, không phải root.
- Chỉ capability đã có lý do rõ ràng mới được cấp.
- Bounding set là allowlist nhỏ nhất.
NoNewPrivileges=yesđược bật và test nếu phù hợp.- Không gắn capability lên shell/interpreter đa dụng.
- File capability được verify sau deploy và restore.
- Effective/ambient capability của process khớp thiết kế.
- SELinux/AppArmor, firewall và systemd sandbox vẫn được duy trì.
- Negative test chứng minh thao tác ngoài phạm vi bị từ chối.
- Có lệnh rollback đã kiểm thử.
Kết luận
Linux capabilities biến mô hình “root hoặc không root” thành các quyền nhỏ hơn, nhưng least privilege chỉ đạt được khi cả capability đang active lẫn khả năng giành thêm quyền đều bị giới hạn. Với daemon systemd, cặp AmbientCapabilities= và CapabilityBoundingSet= thường dễ quản trị hơn file xattr; với binary chuyên dụng, setcap có thể phù hợp nếu deployment giữ và kiểm tra metadata. Dù chọn cách nào, hãy cấp một quyền có lý do, đo hành vi thực và xem mọi capability là một phần của attack surface.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.