如何使用 AppArmor 限制其他进程的权限?
美国、香港服务器
如何使用 AppArmor 限制其他进程的权限?
12-19 来源:
使用 AppArmor 限制任意进程的权限,核心遵循 “定义配置文件→加载规则→验证生效” 的通用流程,核心原则是「最小权限」—— 仅开放进程必需的资源访问(文件、网络、系统调用等),拒绝所有未显式允许的操作。以下是适配 Ubuntu 24.04 的通用步骤,以 Nginx、Python 脚本、自定义程序为例说明:
一、核心前置知识
AppArmor 规则模式
enforce(强制模式):拦截违规行为并记录日志(生产环境推荐);
complain(投诉模式):仅记录违规日志,不拦截(调试阶段)。
配置文件路径
系统默认配置:/etc/apparmor.d/(命名规则:可执行文件路径,如 /usr/sbin/nginx 对应 usr.sbin.nginx);
临时规则(测试用):/etc/apparmor.d/tunables/(不推荐长期使用)。
关键工具
apparmor_parser:编译 / 加载配置文件(检查语法);
aa-status:查看已加载的规则;
aa-complain/aa-enforce:切换规则模式;
grep apparmor /var/log/syslog:查看拦截日志(Ubuntu 24.04 日志默认存于 syslog)。
二、通用配置流程(以 Nginx 为例)
步骤 1:确认进程基础信息
先定位进程可执行文件路径、核心依赖目录(必选,避免权限不足导致进程崩溃):
bash
运行
# 1. 查找进程可执行文件路径
which nginx # 输出:/usr/sbin/nginx
# 2. 查找进程核心目录(日志、配置、网站根目录)
grep -E "pid|error_log|root" /etc/nginx/nginx.conf
# 示例输出:
# pid /var/run/nginx.pid;
# error_log /var/log/nginx/error.log;
# root /var/www/html;
步骤 2:创建 / 编辑 AppArmor 配置文件
配置文件格式为:/etc/apparmor.d/[可执行文件路径(替换/为.)],例如 Nginx 对应 usr.sbin.nginx:
bash
运行
sudo nano /etc/apparmor.d/usr.sbin.nginx
写入通用规则模板(注释说明各段用途,可按需修改):
apparmor
# 关联进程可执行文件(必须与实际路径一致)
/usr/sbin/nginx {
# ========== 基础系统资源(只读/执行) ==========
# 系统库(Nginx 依赖的 libc、openssl 等)
/lib/** r,
/usr/lib/** r,
/lib64/** r,
/usr/lib64/** r,
# 进程自身可执行文件(读/执行)
/usr/sbin/nginx mr,
/usr/share/nginx/** r,
# ========== 配置文件(只读) ==========
/etc/nginx/** r,
/etc/nginx/nginx.conf r,
/etc/nginx/sites-available/** r,
/etc/nginx/sites-enabled/** r,
# ========== 业务目录(按需开放) ==========
# 网站根目录(读,若需上传则加 w)
/var/www/html/** r,
# 临时文件(读写)
/tmp/ rw,
/var/run/nginx.pid rw,
# 日志目录(读写)
/var/log/nginx/ rw,
/var/log/nginx/** rwk, # k=锁定文件(日志写入必需)
# ========== 网络权限(按需限制) ==========
network tcp, # 允许 TCP 网络(Nginx 必需)
# 仅允许本地监听(禁止外网主动连接):network tcp addr=127.0.0.1,
# 禁止 UDP(Nginx 无需则添加):deny network udp,
# ========== 系统调用/权限(最小化) ==========
capability net_bind_service, # 允许绑定 80/443 端口(必需)
capability dac_override, # 基础文件权限覆盖(按需)
deny capability sys_admin, # 拒绝管理员级系统调用
# ========== 显式拒绝敏感目录(防越权) ==========
deny /etc/shadow r, # 拒绝读取密码文件
deny /root/** rw, # 拒绝访问 root 目录
deny /home/** rw, # 拒绝访问用户目录(若无需则保留)
# ========== 默认规则(兜底) ==========
deny /** w, # 禁止写入所有未显式允许的目录
deny /bin/bash r, # 禁止进程调用 shell(防提权)
}
步骤 3:编译并加载配置文件
编译规则(检查语法错误)→ 加载规则 → 重启进程使规则生效:
bash
运行
# 1. 编译配置文件(-v 显示详细信息,-W 警告提示)
sudo apparmor_parser -vW /etc/apparmor.d/usr.sbin.nginx
# 2. 重新加载 AppArmor 服务
sudo systemctl reload apparmor
# 3. 重启进程(使规则生效)
sudo systemctl restart nginx
# 4. 检查进程状态(确保未因权限不足崩溃)
sudo systemctl status nginx
步骤 4:验证规则生效
方法 1:查看已加载的规则
bash
运行
aa-status | grep nginx
# 输出示例:/usr/sbin/nginx (enforce) → 强制模式生效
方法 2:测试越权访问(验证拦截效果)
故意让 Nginx 尝试访问未授权目录(如 /root/test.html),查看拦截日志:
修改 Nginx 配置,指向敏感目录:
bash
运行
sudo nano /etc/nginx/sites-enabled/default
# 临时修改 root /root/; 保存后重启 Nginx
sudo systemctl restart nginx # 会启动失败
查看 AppArmor 拦截日志:
bash
运行
sudo grep -i apparmor /var/log/syslog | grep nginx
# 输出示例:
# apparmor="DENIED" operation="open" profile="/usr/sbin/nginx" name="/root/" pid=1234 comm="nginx" requested_mask="r" denied_mask="r"
出现 DENIED 日志说明规则生效,恢复 Nginx 配置后重启即可。
三、不同类型进程的适配示例
示例 1:限制 Python 脚本(自定义程序)
假设脚本路径为 /opt/my_script.py,核心依赖 /opt/data/ 目录,禁止网络访问:
创建配置文件 /etc/apparmor.d/opt.my_script.py:
apparmor
/opt/my_script.py {
# 基础依赖(Python 解释器+库)
/usr/bin/python3.12 mr,
/usr/lib/python3.12/** r,
# 脚本自身+数据目录
/opt/my_script.py r,
/opt/data/** rwk,
# 临时文件
/tmp/ rw,
# 禁止网络+敏感目录
deny network all,
deny /etc/shadow r,
# 兜底规则
deny /** w,
}
加载规则并运行脚本:
bash
运行
sudo apparmor_parser -v /etc/apparmor.d/opt.my_script.py
sudo aa-enforce /etc/apparmor.d/opt.my_script.py
python3 /opt/my_script.py # 运行脚本,测试越权行为
示例 2:限制自定义二进制程序(如 /usr/local/bin/myapp)
核心规则仅开放程序自身、日志目录,禁止所有网络和敏感目录访问:
apparmor
/usr/local/bin/myapp {
# 程序自身+系统库
/usr/local/bin/myapp mr,
/lib/** r,
# 日志目录
/var/log/myapp/** rwk,
# 禁止网络+提权
deny network all,
deny capability setuid,
# 兜底拒绝
deny /** w,
}
四、调试与排错(关键!避免进程崩溃)
1. 先启用 complain 模式调试
新配置建议先在 complain 模式运行,收集进程所需权限,再优化规则:
bash
运行
# 切换为投诉模式
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
# 运行进程并触发正常业务操作(如 Nginx 访问网页、写入日志)
# 查看日志,提取被拒绝的合法权限
sudo grep -i apparmor /var/log/syslog | grep nginx
根据日志中 requested_mask(请求的权限),补充到配置文件中(例如日志显示 denied_mask="w" 对应 /var/www/html/,则添加 /var/www/html/** rw)。
2. 常见进程崩溃原因及解决
问题现象 原因 解决方法
进程启动失败 遗漏核心目录 / 权限 查看 syslog,补充缺失的路径(如 /var/run/ 读写)
日志无法写入 未添加 k(锁定)权限 将 /var/log/xxx/** rw 改为 rwk
网络连接失败 未开放 network 权限 添加 network tcp(按需)
脚本无法调用依赖库 未开放 Python / 系统库路径 添加 /usr/lib/python3.12/** r
五、生产环境最佳实践
最小权限原则:
仅开放进程 “必需” 的资源(如 Nginx 无需 /home 访问则显式拒绝);
禁止进程调用 shell(deny /bin/bash r),防止攻击者通过进程提权。
规则固化:
修改配置后,执行 apparmor_parser -r /etc/apparmor.d/[配置文件] 重新加载;
备份配置文件(cp /etc/apparmor.d/xxx /backup/),避免系统更新覆盖。
日志监控:
定期检查 syslog 中的 AppArmor 日志,发现异常访问(如进程尝试读取 /etc/shadow);
可结合 rsyslog 将 AppArmor 日志单独存储(便于审计)。
避免冲突:
Ubuntu 24.04 默认启用 AppArmor,无需同时启用 SELinux(两者冲突);
容器化进程(Docker)需注意:Docker 自身有 AppArmor 模板,可复用并自定义。
六、快速禁用 / 删除规则(如需)
bash
运行
# 1. 临时禁用(切换为 complain 模式)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
# 2. 永久删除规则
sudo rm /etc/apparmor.d/usr.sbin.nginx
sudo systemctl reload apparmor
# 3. 验证已删除
aa-status | grep nginx # 无输出则删除成功
三二互联专业提供香港VPS,美国VPS主机,香港云服务器租用等业务香港美国到大陆CN2 GIA速度最快