cmake可见性和AppArmor示例

This commit is contained in:
NoDistanceY 2026-09-03 10:39:21 +08:00
commit 4b4b933e3d
19 changed files with 661 additions and 0 deletions

123
AppArmor/demo1/run.sh Executable file
View file

@ -0,0 +1,123 @@
#!/bin/bash
# 运行方法:
# step1: chmod +x run.sh demo_shell.sh
# step2: sudo sh run.sh
set -e
WORK_DIR=$(cd "$(dirname "$0")" && pwd)
cd "${WORK_DIR}"
if [ "$(id -u)" -ne 0 ];then
echo "please run with sudo: sudo sh run.sh"
exit 1
fi
ELF_BIN="${WORK_DIR}/demo_app"
SCRIPT_FILE="${WORK_DIR}/demo_shell.sh"
PROFILE_ELF_NAME="home.fnzhang.aa_demo.demo_app"
PROFILE_SCRIPT_NAME="home.fnzhang.aa_demo.demo_shell"
PROFILE_ELF="/etc/apparmor.d/${PROFILE_ELF_NAME}"
PROFILE_SCRIPT="/etc/apparmor.d/${PROFILE_SCRIPT_NAME}"
REPORT="${WORK_DIR}/report.txt"
> "${REPORT}"
log(){
echo "$1"
echo "$1" >> "${REPORT}"
}
echo "========================================"
echo "AppArmor Demo start, workdir: ${WORK_DIR}"
echo "========================================"
# ========== 【前置清理:解决上次残留冲突】 ==========
log ""
log "===== Precleanup: remove leftover profile ====="
# 卸载内核中可能残留的旧 profile-R 按 profile 名卸载)
apparmor_parser -R "${PROFILE_ELF}" 2>/dev/null || true
apparmor_parser -R "${PROFILE_SCRIPT}" 2>/dev/null || true
# 清掉 /etc/apparmor.d 下旧文件(含上次失败残留的错误 profile
rm -f "${PROFILE_ELF}" "${PROFILE_SCRIPT}"
# 注意:不使用 systemctl reload apparmor —— 它会重载全部 200+ 个 profile
# 触发内核 printk ratelimitkauditd callbacks suppressed
# 把随后 demo 真正的 DENIED 审计事件一并丢弃。
log "precleanup done"
# ========== Step1 compile C elf ==========
log ""
log "===== Step1 compile C elf ====="
gcc "${WORK_DIR}/demo_app.c" -o "${ELF_BIN}"
chmod +x "${ELF_BIN}"
log "compile done: ${ELF_BIN}"
# ========== Step2 validate profile syntax ==========
log ""
log "===== Step2 validate profile syntax ====="
apparmor_parser -Q "${WORK_DIR}/profile.elf" && log "profile.elf syntax OK"
apparmor_parser -Q "${WORK_DIR}/profile.script" && log "profile.script syntax OK"
# ========== Step3 install profile ==========
log ""
log "===== Step3 install profile ====="
cp "${WORK_DIR}/profile.elf" "${PROFILE_ELF}"
cp "${WORK_DIR}/profile.script" "${PROFILE_SCRIPT}"
apparmor_parser -r -W "${PROFILE_ELF}" || { rm -f "${PROFILE_ELF}"; log "ERROR: elf profile load failed"; exit 1; }
apparmor_parser -r -W "${PROFILE_SCRIPT}" || { rm -f "${PROFILE_SCRIPT}"; log "ERROR: script profile load failed"; exit 1; }
log "profile installed & enforce enabled"
# 等待内核 audit ratelimit 窗口恢复,避免 DENIED 事件被 printk ratelimit 吞掉
sleep 6
# ========== Step4 run elf demo_app ==========
log ""
log "===== Step4 run elf demo_app ====="
rm -f /tmp/demo_elf.log /tmp/demo_forbidden.log
"${ELF_BIN}" 2>&1 | tee -a "${REPORT}" || log "(demo_app returned non-zero / was killed - expected)"
log "-- verify /tmp/demo_elf.log exists (allowed write):"
ls -l /tmp/demo_elf.log 2>&1 | tee -a "${REPORT}"
# ========== Step5 run shell script ==========
log ""
log "===== Step5 run shell script ====="
rm -f /tmp/demo_sh.log /tmp/demo_forbidden.log
"${SCRIPT_FILE}" 2>&1 | tee -a "${REPORT}" || log "(demo_shell.sh returned non-zero / was killed - expected)"
log "-- verify /tmp/demo_sh.log exists (allowed write):"
ls -l /tmp/demo_sh.log 2>&1 | tee -a "${REPORT}"
# ========== Step6 aa-status snapshot ==========
log ""
log "===== Step6 aa-status snapshot ====="
aa-status --json 2>/dev/null | python3 -c "
import json,sys
d = json.load(sys.stdin)
for name, mode in sorted(d.get('profiles', {}).items()):
if 'demo_app' in name or 'demo_shell' in name:
print(f' {name}: {mode}')
" | tee -a "${REPORT}"
# ========== Step7 check deny evidences ==========
log ""
log "===== Step7 AppArmor DENIED logs ====="
# 等 ratelimit 窗口过去再收集sleep 6 已在 Step3 后做过,这里直接查)
dmesg 2>/dev/null | grep -iE 'apparmor=\"DENIED\"' | grep -iE 'demo_app|demo_shell' | tail -10 | tee -a "${REPORT}" \
|| journalctl -k -b --no-pager 2>/dev/null | grep -iE 'apparmor=\"DENIED\"' | grep -iE 'demo_app|demo_shell' | tail -10 | tee -a "${REPORT}"
if [ -z "$(dmesg 2>/dev/null | grep 'apparmor=\"DENIED\"' | grep -iE 'demo_app|demo_shell')" ]; then
log "(提示: 若此处为空, 可能被内核 printk ratelimit 抑制; 显式 deny 规则本身不产生日志)"
fi
# ========== Step8 clean resources ==========
log ""
log "===== Step8 clean resources ====="
apparmor_parser -R "${PROFILE_ELF}" 2>/dev/null || true
apparmor_parser -R "${PROFILE_SCRIPT}" 2>/dev/null || true
rm -f "${PROFILE_ELF}" "${PROFILE_SCRIPT}"
rm -f "${ELF_BIN}"
rm -f /tmp/demo_elf.log /tmp/demo_sh.log /tmp/demo_forbidden.log
log ""
log "========================================"
log "Demo finished, report file: ${REPORT}"