Skip to content

Latest commit

 

History

History
405 lines (264 loc) · 17.1 KB

File metadata and controls

405 lines (264 loc) · 17.1 KB

SEChrome(SecChrome)方案说明

本文档用于对外交付,面向具备工程落地能力的开发者/运维人员,提供可直接执行的构建、配置、运行、排障与验收指引。


1. 背景与目标

浏览器(Chrome/Chromium)是高频攻击面。即使浏览器自身有沙箱,一旦出现漏洞被利用,攻击者仍可能尝试:

  • 读取宿主机敏感文件(SSH key、token、配置等)
  • 写入恶意文件(落地持久化)
  • 执行外部程序(横向移动、下载器)
  • 使用高风险系统能力(提权、逃逸、调试注入等)

SEChrome 的定位:在 Linux 上以“安全启动器(launcher)”的方式为 Chrome/Chromium 增加一层可配置的系统级访问控制,将浏览器进程权限收敛至最小(Least Privilege),降低漏洞被利用后的影响面。

1.1 目标

  • 为 Chrome/Chromium 提供额外的系统级约束层(Defense in Depth)
  • 通过可配置策略限制文件读写、程序执行与高风险系统调用
  • 提供可观测与排障能力,支持策略收敛与持续迭代

1.2 非目标

  • 不进行恶意内容检测/拦截(不解析网页内容,不做 AV/EDR 能力)
  • 不自动推断业务所需权限,策略需按场景配置与验证

1.3 与 Chrome 自带沙箱的关系(重要)

本方案以 SEChrome 的外部约束机制替代 Chrome 自带沙箱 的运行方式为前提。为避免两套沙箱机制在进程模型与系统调用行为上产生冲突,运行时应 禁用 Chrome 自带沙箱(使用 --no-sandbox)。

仓库中的 run_sec_chrome.sh 已默认传入 --no-sandbox,属于该方案的标准运行方式。启用 Chrome 沙箱可能导致启动失败、子进程行为异常或策略判定不一致等问题,建议避免同时开启。


2. 工作方式概述

SEChrome 通过 secure_chrome_launcher 启动并监管 Chrome/Chromium 进程:

  • 加载 config.yaml(Chrome 路径、启动参数、策略规则、审计日志)
  • fork 创建子进程并执行 Chrome
  • 父进程以选定的监管引擎(ptrace 或 seccomp-notify)对关键行为进行判定与处置(允许/拒绝)

3. 核心能力

  • 双引擎监管(可选其一)
    • seccomp-notify:较低性能开销,适合长期运行与生产化场景(依赖内核能力/权限条件)
    • ptrace:通用性强、可观测性较好,适合策略收敛与调试(通常性能开销更高)
  • 访问控制策略
    • 文件访问(rules.file:允许读取/打开的文件与目录(以白名单为主)
    • 程序执行(rules.exec:允许执行的程序路径(以白名单为主)
    • 写入控制(rules.write:允许写入的目录路径(以白名单为主)
    • 系统调用控制(rules.syscalls:按需增加 deny/allow 规则(默认允许,作为加固项)
  • 审计与排障
    • 可选审计日志输出,用于定位策略阻断点与支持策略迭代

4. 适用场景

  • Headless 自动化/抓取/渲染服务:降低被网页利用后的宿主风险
  • 企业桌面/受控浏览器环境:在系统层额外收紧能力
  • 容器/CI 中运行 Chrome:通过策略约束减少“容器内被打穿后”的扩散

5. 架构与运行流程(高层)

5.1 组件说明

  • Launchersecure_chrome_launcher,负责加载配置、启动 Chrome、执行策略判定与审计输出
  • 配置config.yaml,定义 Chrome 启动参数、监管引擎、审计输出与策略规则
  • 策略规则
    • 路径类策略:rules.file / rules.exec / rules.write
    • 系统调用策略:rules.syscalls

5.2 运行流程

  1. Launcher 加载 config.yaml
  2. 选择监管引擎(ptrace 或 seccomp-notify)
  3. 启动 Chrome/Chromium
  4. 运行期间对受控行为进行判定与处置(允许/拒绝),必要时写入审计日志

6. 构建与运行

6.1 依赖与构建

SEChrome/ 目录:

  1. 安装依赖(如果你使用项目脚本):
./install_dependencies.sh
  1. 构建:
mkdir -p build && cd build && cmake .. && make

产物:SEChrome/build/secure_chrome_launcher

6.2 配置文件准备

复制示例配置:

cp config.example.yaml config.yaml

编辑 config.yaml(至少设置 chrome_binary,并选择一种引擎)。

6.2.1 Docker Quickstart

项目提供了一份可复现的 Docker Quickstart 文档(包含 Dockerfile、容器配置与运行示例):

  • docs/QUICKSTART.md

容器默认配置的安全原则:

  • 不建议放开 /home(会显著扩大可读/可写面)
  • Quickstart 镜像会将 HOME/XDG_CONFIG_HOME 指向 /tmp 下的目录,并将 Chromium 的 profile/cache 指向 /tmp,以便将写入面收敛到 /tmp

6.3 运行方式

你可以直接运行二进制,也可以使用仓库根目录提供的脚本。

方式 A:直接运行(推荐用于理解参数)

SEChrome/ 目录下:

./build/secure_chrome_launcher --config=./config.yaml -- --headless https://example.com
  • --config=...:指定配置文件路径(不传默认使用当前目录的 config.yaml
  • --:分隔符,后面的参数会原样传给 Chrome

方式 B:用仓库脚本运行(推荐用于固定环境)

仓库根目录的 run_sec_chrome.sh 会固定使用本机路径的 launcher 与配置文件,并透传参数:

./run_sec_chrome.sh -- --headless https://example.com

说明:该脚本包含环境相关的绝对路径配置,跨机器/CI 使用前需要调整。

6.4 容器部署(Docker为例)

本节给出在容器中运行 SEChrome 的推荐配置。容器场景下最常见的问题是:容器运行时(Docker/K8s)自身的安全配置会限制 seccomp-notify / ptrace 所需的系统能力,导致启动失败或无法进入监管循环。

6.4.1 优先建议

  • 若容器环境无法授予额外权限,优先使用 ptrace 模式完成策略收敛与功能验证。
  • 若需要在容器中启用 seccomp-notify 模式,通常需要为容器授予额外能力并放开容器运行时的 seccomp 限制(否则 seccomp()/相关 flag 可能被 Docker 默认 seccomp profile 拦截)。

6.4.2 seccomp-notify 容器权限要求(实践口径)

在 Docker 中启用 seccomp-notify(用户态通知监听 FD)通常需要:

  • CAP_SYS_ADMIN:常见内核/发行版组合下,用于安装带 listener 的 seccomp filter(用户态通知)所需权限
  • 容器 seccomp 配置放开:Docker 默认 seccomp profile 可能拦截 seccomp() 或相关能力
    • 最简单方式:--security-opt seccomp=unconfined
    • 生产建议:使用自定义 seccomp profile(仅放开必要 syscall/flag)

说明:

  • 若无法满足上述条件,建议改用 ptrace 模式(ptrace_enabled: true)。
  • 仍需按本方案要求禁用 Chrome 自带沙箱(--no-sandbox),避免与 SEChrome 冲突。

6.4.3 config.yaml(容器场景)建议

启用 seccomp-notify:

  • security.ptrace_enabled: false
  • security.seccomp_notify: true
  • security.open_syscall_monitored: true

权限不足或需要更强可观测性时,启用 ptrace:

  • security.ptrace_enabled: true
  • security.seccomp_notify: false

6.4.4 Docker 启动示例

示例 A:seccomp-notify 模式(需要额外权限)

docker run --rm -it \
  --cap-add=SYS_ADMIN \
  --security-opt seccomp=unconfined \
  --shm-size=1g \
  -v "$(pwd)/SEChrome:/work/SEChrome" \
  -w /work/SEChrome \
  <your-image> \
  ./build/secure_chrome_launcher --config=./config.yaml --no-sandbox -- --headless https://example.com

示例 B:ptrace 模式(更通用)

docker run --rm -it \
  --security-opt seccomp=unconfined \
  --shm-size=1g \
  -v "$(pwd)/SEChrome:/work/SEChrome" \
  -w /work/SEChrome \
  <your-image> \
  ./build/secure_chrome_launcher --config=./config.yaml --no-sandbox -- --headless https://example.com

说明:--shm-size 用于规避 headless/多进程 Chrome 在容器默认 /dev/shm 较小时的稳定性问题,可按业务压测结果调整。

7. 配置参考(config.yaml

config.yaml 关注 4 类内容:Chrome 路径/参数、监管引擎选择、日志、访问规则。

7.0 配置必改项(部署前检查清单)

以下字段在不同机器/容器/发行版之间通常需要按环境调整;直接复用示例配置可能导致启动失败或权限配置不符合预期:

  • Chrome 可执行文件路径
    • 修改 chrome_binary 为实际 Chrome/Chromium 路径(例如 /opt/google/chrome/chrome
    • 同时在 rules.exec 中确保包含对应路径的允许项(示例中若写了其它路径但你的环境不存在,会导致启动失败)
  • Chrome 组件可执行文件白名单
    • rules.exec 至少需要包含 Chrome 主程序、chrome-sandboxchrome_crashpad_handler(路径以你的安装位置为准)
    • 不建议为降低配置成本而放开通用系统工具(见 7.4 常见配置不当)
  • 启动参数(按使用场景收敛)
    • 默认参数写在 chrome_argv
    • 运行命令中 -- 后的参数会透传给 Chrome(脚本/命令行额外参数会叠加在 chrome_argv 之后)
    • 本方案要求禁用 Chrome 自带沙箱:应确保运行链路中包含 --no-sandbox(仓库脚本 run_sec_chrome.sh 已默认添加)
  • 数据目录/写目录(建议明确指定并收敛)
    • 对自动化/服务化场景,建议显式指定 profile/缓存目录(例如通过 Chrome 参数指定到某个工作目录)
    • 然后仅在 rules.write 放行该工作目录(以及必要的 /tmp/dev/shm 等)
  • 审计日志(上线前收敛策略必需)
    • 策略收敛阶段建议打开 logging.audit_enabled: true 并指定 audit_path
    • 稳定后再关闭或将日志输出到受控位置

7.1 Chrome 路径与默认参数

  • chrome_binary:Chrome/Chromium 可执行文件路径
    • 例如:/opt/google/chrome/chrome
  • chrome_argv:启动 Chrome 时默认附带的参数数组
    • 例如 --headless--disable-gpu

说明:运行时传入的参数会在默认参数基础上追加(以 launcher 的参数拼接逻辑为准)。

7.2 安全引擎(security

  • ptrace_enabled(true/false)
    • true:使用 ptrace 引擎(更适合调试/可观测、一般更慢)
    • false:可以使用 seccomp-notify(若开启)
  • seccomp_notify(true/false)
    • true:启用 seccomp-notify 引擎(更偏生产、开销更小)
    • false:不启用 seccomp-notify(通常与 ptrace 二选一)
  • open_syscall_monitored(true/false)
    • 用于让“文件访问规则”能生效的关键开关(监控 open/openat
  • fs_mutation_syscalls_monitored(true/false)
    • 启用后,会对文件系统变更类系统调用进行额外控制(如 rename*link*unlink*symlink*mkdir*rmdirchmod*chown*utimensat*xattr* 等)
    • 用于覆盖“非 open 写入路径”的绕过方式(例如通过 rename/link/unlink 等修改文件系统状态)

7.3 审计日志(logging

  • audit_enabled:是否输出“允许/阻断”审计信息
  • audit_path:审计日志文件路径(默认示例:open_read_log.txt

排障阶段建议开启;策略稳定后可关闭或定向到受控位置。

7.4 常见配置不当(高风险放开清单)

以下配置模式在实践中风险较高,建议纳入配置审计检查项:

7.4.1 写入目录放开风险(rules.write

原则:写入面越大,攻击面越大。一旦浏览器进程被利用获得任意代码执行能力,写权限会直接转化为落地与持久化能力。

  • 不要放开/usr/bin/sbin/lib*/opt(尤其是 Chrome 安装目录)、/etc/var/lib(通常承载系统/服务状态)
  • 谨慎放开/var/tmp/var/cache,建议仅放开确切子目录,避免对整棵目录树使用 prefix
  • 推荐做法:仅允许写入
    • 业务工作目录(例如 /data/app/chrome-profile/<job-id>
    • 必要的临时目录(/tmp/dev/shm)与用户运行时目录(/run/user/<uid>

7.4.2 可执行文件放开风险(rules.exec

原则:rules.exec 是浏览器进程跳转到宿主系统工具链的关键开关。放开通用工具会显著降低攻击链门槛。

  • 避免允许/bin/sh/bin/bash/usr/bin/env/usr/bin/python*/usr/bin/node*/usr/bin/perl 等解释器与 shell
  • 避免允许curl/wget/nc/ssh/scp/rsync 等“下载/外联/横向移动”工具
  • 避免允许:大量通用 /usr/bin/* 工具(如 catlsreadlinkdirname 等),除非你能明确证明 Chrome 在你的场景中必须依赖它们
  • 推荐做法:仅允许 Chrome 自身必须的可执行组件,例如安装目录内的 Chrome 主程序及其配套二进制

7.4.3 文件读取范围过宽风险(rules.file

原则:读权限过大等价于“被利用后可读取更多宿主机秘密”。

  • 避免直接放开allow,prefix,/allow,prefix,/etc 这类全量/大范围读取
  • 避免放开敏感目录/root、用户家目录下的 ~/.ssh~/.config~/.kube~/.aws~/.npmrc 等(除非确有业务需要)
  • 推荐做法:对 /etc 采用最小必要文件与受控子目录策略,例如证书与字体目录,并通过审计日志按需补齐

8. 策略规则说明

SEChrome 有两类规则:

8.1 路径类规则(rules.file / rules.exec / rules.write

这三类规则采用白名单为主的控制方式:未显式允许的访问将被拒绝。

8.1.1 规则格式

每条规则是一个字符串:

[action],[type],[path]

  • actionallowdeny(可省略,省略默认 allow
  • type:匹配方式
    • exact:路径精确匹配
    • prefix:目录前缀匹配(相当于允许该目录树)
    • suffix:按后缀匹配(例如 .so
    • prefix_suffix:目录前缀 + 后缀组合(例如 /lib/*.so
  • path:路径或模式(具体语义由 type 决定)

8.1.2 三类规则的含义

  • rules.file:允许 Chrome 打开/读取(以及需要时的读写打开)哪些路径
  • rules.exec:允许 Chrome exec 哪些可执行文件
    • 必须至少包含 Chrome 主程序、chrome-sandboxchrome_crashpad_handler
  • rules.write:允许写入哪些目录(profile、缓存、tmp、共享内存等通常需要)

8.2 系统调用规则(rules.syscalls

系统调用规则是黑名单(默认允许):不写就代表允许;你写 deny,xxx 才会阻断。

8.2.1 规则格式

allow|deny,syscall_name

典型用途:

  • 你想进一步加固:添加 deny,socket(彻底禁网)等
  • 你需要兼容某环境:用 allow,xxx 覆盖默认阻断项(如果项目内置默认阻断)

说明:与文件打开/执行强相关的系统调用(如 open/openat/execve)通常由路径类规则完成控制,建议避免在 syscall 列表中重复配置。


9. 引擎选择建议

9.1 推荐策略

  • 先 ptrace,后 seccomp-notify
    • ptrace 更适合完成策略收敛:更容易发现缺失权限与路径访问项
    • 规则稳定后切到 seccomp-notify 获取更好的性能与更接近生产的形态

9.2 建议落地流程

  1. ptrace_enabled: trueaudit_enabled: true 运行目标用例
  2. 遇到异常(启动失败/页面打不开/组件报错)就看审计日志里“被拒绝的路径/动作”
  3. 最小化地补齐 rules.file/exec/write
  4. 用例稳定后将 ptrace_enabled: falseseccomp_notify: true(若环境支持)
  5. 在 seccomp-notify 下复测并微调规则
  6. 策略固化:输出“基线配置 + 场景差异配置”(见第 10 章)

10. 排障

10.1 Chrome 启动即退出 / 返回码 127

  • 优先检查chrome_binary 路径是否正确、rules.exec 是否允许该路径
  • 常见原因:Chrome 被禁止执行自身或辅助二进制(crashpad/sandbox)

10.2 页面加载失败 / 资源缺失 / 字体异常

  • 优先检查rules.file 是否放行了系统库、字体缓存、证书、/etc/usr/lib* 等必要路径(按你的发行版不同而不同)

10.3 无法写入 profile / 崩溃提示无法创建目录

  • 优先检查rules.write 是否允许 profile 目录、/tmp/dev/shm
  • 建议:为自动化任务显式指定 profile 目录并仅放行该目录(更利于收敛)

10.4 定位缺失权限

  • 开启 logging.audit_enabled: true
  • 临时切换到 ptrace_enabled: true(更适合排障)
  • 逐条补齐规则,直到用例跑通

11. 术语

  • launcher:外层启动器(本项目的 secure_chrome_launcher
  • 监管:launcher 运行期间对受控行为进行判定与处置(允许/拒绝)
  • 白名单:仅允许列表内项(rules.file/rules.exec/rules.write
  • 黑名单:默认允许,仅拒绝列表内项(rules.syscalls