本文档用于对外交付,面向具备工程落地能力的开发者/运维人员,提供可直接执行的构建、配置、运行、排障与验收指引。
浏览器(Chrome/Chromium)是高频攻击面。即使浏览器自身有沙箱,一旦出现漏洞被利用,攻击者仍可能尝试:
- 读取宿主机敏感文件(SSH key、token、配置等)
- 写入恶意文件(落地持久化)
- 执行外部程序(横向移动、下载器)
- 使用高风险系统能力(提权、逃逸、调试注入等)
SEChrome 的定位:在 Linux 上以“安全启动器(launcher)”的方式为 Chrome/Chromium 增加一层可配置的系统级访问控制,将浏览器进程权限收敛至最小(Least Privilege),降低漏洞被利用后的影响面。
- 为 Chrome/Chromium 提供额外的系统级约束层(Defense in Depth)
- 通过可配置策略限制文件读写、程序执行与高风险系统调用
- 提供可观测与排障能力,支持策略收敛与持续迭代
- 不进行恶意内容检测/拦截(不解析网页内容,不做 AV/EDR 能力)
- 不自动推断业务所需权限,策略需按场景配置与验证
本方案以 SEChrome 的外部约束机制替代 Chrome 自带沙箱 的运行方式为前提。为避免两套沙箱机制在进程模型与系统调用行为上产生冲突,运行时应 禁用 Chrome 自带沙箱(使用 --no-sandbox)。
仓库中的 run_sec_chrome.sh 已默认传入 --no-sandbox,属于该方案的标准运行方式。启用 Chrome 沙箱可能导致启动失败、子进程行为异常或策略判定不一致等问题,建议避免同时开启。
SEChrome 通过 secure_chrome_launcher 启动并监管 Chrome/Chromium 进程:
- 加载
config.yaml(Chrome 路径、启动参数、策略规则、审计日志) fork创建子进程并执行 Chrome- 父进程以选定的监管引擎(ptrace 或 seccomp-notify)对关键行为进行判定与处置(允许/拒绝)
- 双引擎监管(可选其一)
- seccomp-notify:较低性能开销,适合长期运行与生产化场景(依赖内核能力/权限条件)
- ptrace:通用性强、可观测性较好,适合策略收敛与调试(通常性能开销更高)
- 访问控制策略
- 文件访问(
rules.file):允许读取/打开的文件与目录(以白名单为主) - 程序执行(
rules.exec):允许执行的程序路径(以白名单为主) - 写入控制(
rules.write):允许写入的目录路径(以白名单为主) - 系统调用控制(
rules.syscalls):按需增加 deny/allow 规则(默认允许,作为加固项)
- 文件访问(
- 审计与排障
- 可选审计日志输出,用于定位策略阻断点与支持策略迭代
- Headless 自动化/抓取/渲染服务:降低被网页利用后的宿主风险
- 企业桌面/受控浏览器环境:在系统层额外收紧能力
- 容器/CI 中运行 Chrome:通过策略约束减少“容器内被打穿后”的扩散
- Launcher:
secure_chrome_launcher,负责加载配置、启动 Chrome、执行策略判定与审计输出 - 配置:
config.yaml,定义 Chrome 启动参数、监管引擎、审计输出与策略规则 - 策略规则
- 路径类策略:
rules.file/rules.exec/rules.write - 系统调用策略:
rules.syscalls
- 路径类策略:
- Launcher 加载
config.yaml - 选择监管引擎(ptrace 或 seccomp-notify)
- 启动 Chrome/Chromium
- 运行期间对受控行为进行判定与处置(允许/拒绝),必要时写入审计日志
在 SEChrome/ 目录:
- 安装依赖(如果你使用项目脚本):
./install_dependencies.sh- 构建:
mkdir -p build && cd build && cmake .. && make产物:SEChrome/build/secure_chrome_launcher
复制示例配置:
cp config.example.yaml config.yaml编辑 config.yaml(至少设置 chrome_binary,并选择一种引擎)。
项目提供了一份可复现的 Docker Quickstart 文档(包含 Dockerfile、容器配置与运行示例):
docs/QUICKSTART.md
容器默认配置的安全原则:
- 不建议放开
/home(会显著扩大可读/可写面) - Quickstart 镜像会将
HOME/XDG_CONFIG_HOME指向/tmp下的目录,并将 Chromium 的 profile/cache 指向/tmp,以便将写入面收敛到/tmp
你可以直接运行二进制,也可以使用仓库根目录提供的脚本。
在 SEChrome/ 目录下:
./build/secure_chrome_launcher --config=./config.yaml -- --headless https://example.com--config=...:指定配置文件路径(不传默认使用当前目录的config.yaml)--:分隔符,后面的参数会原样传给 Chrome
仓库根目录的 run_sec_chrome.sh 会固定使用本机路径的 launcher 与配置文件,并透传参数:
./run_sec_chrome.sh -- --headless https://example.com说明:该脚本包含环境相关的绝对路径配置,跨机器/CI 使用前需要调整。
本节给出在容器中运行 SEChrome 的推荐配置。容器场景下最常见的问题是:容器运行时(Docker/K8s)自身的安全配置会限制 seccomp-notify / ptrace 所需的系统能力,导致启动失败或无法进入监管循环。
- 若容器环境无法授予额外权限,优先使用 ptrace 模式完成策略收敛与功能验证。
- 若需要在容器中启用 seccomp-notify 模式,通常需要为容器授予额外能力并放开容器运行时的 seccomp 限制(否则
seccomp()/相关 flag 可能被 Docker 默认 seccomp profile 拦截)。
在 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 冲突。
启用 seccomp-notify:
security.ptrace_enabled: falsesecurity.seccomp_notify: truesecurity.open_syscall_monitored: true
权限不足或需要更强可观测性时,启用 ptrace:
security.ptrace_enabled: truesecurity.seccomp_notify: false
示例 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 较小时的稳定性问题,可按业务压测结果调整。
config.yaml 关注 4 类内容:Chrome 路径/参数、监管引擎选择、日志、访问规则。
以下字段在不同机器/容器/发行版之间通常需要按环境调整;直接复用示例配置可能导致启动失败或权限配置不符合预期:
- Chrome 可执行文件路径
- 修改
chrome_binary为实际 Chrome/Chromium 路径(例如/opt/google/chrome/chrome) - 同时在
rules.exec中确保包含对应路径的允许项(示例中若写了其它路径但你的环境不存在,会导致启动失败)
- 修改
- Chrome 组件可执行文件白名单
rules.exec至少需要包含 Chrome 主程序、chrome-sandbox、chrome_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 - 稳定后再关闭或将日志输出到受控位置
- 策略收敛阶段建议打开
chrome_binary:Chrome/Chromium 可执行文件路径- 例如:
/opt/google/chrome/chrome
- 例如:
chrome_argv:启动 Chrome 时默认附带的参数数组- 例如
--headless、--disable-gpu等
- 例如
说明:运行时传入的参数会在默认参数基础上追加(以 launcher 的参数拼接逻辑为准)。
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*、rmdir、chmod*、chown*、utimensat、*xattr*等) - 用于覆盖“非 open 写入路径”的绕过方式(例如通过 rename/link/unlink 等修改文件系统状态)
- 启用后,会对文件系统变更类系统调用进行额外控制(如
audit_enabled:是否输出“允许/阻断”审计信息audit_path:审计日志文件路径(默认示例:open_read_log.txt)
排障阶段建议开启;策略稳定后可关闭或定向到受控位置。
以下配置模式在实践中风险较高,建议纳入配置审计检查项:
原则:写入面越大,攻击面越大。一旦浏览器进程被利用获得任意代码执行能力,写权限会直接转化为落地与持久化能力。
- 不要放开:
/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>)
- 业务工作目录(例如
原则: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/*工具(如cat、ls、readlink、dirname等),除非你能明确证明 Chrome 在你的场景中必须依赖它们 - 推荐做法:仅允许 Chrome 自身必须的可执行组件,例如安装目录内的 Chrome 主程序及其配套二进制
原则:读权限过大等价于“被利用后可读取更多宿主机秘密”。
- 避免直接放开:
allow,prefix,/或allow,prefix,/etc这类全量/大范围读取 - 避免放开敏感目录:
/root、用户家目录下的~/.ssh、~/.config、~/.kube、~/.aws、~/.npmrc等(除非确有业务需要) - 推荐做法:对
/etc采用最小必要文件与受控子目录策略,例如证书与字体目录,并通过审计日志按需补齐
SEChrome 有两类规则:
这三类规则采用白名单为主的控制方式:未显式允许的访问将被拒绝。
每条规则是一个字符串:
[action],[type],[path]
- action:
allow或deny(可省略,省略默认allow) - type:匹配方式
exact:路径精确匹配prefix:目录前缀匹配(相当于允许该目录树)suffix:按后缀匹配(例如.so)prefix_suffix:目录前缀 + 后缀组合(例如/lib/*.so)
- path:路径或模式(具体语义由 type 决定)
rules.file:允许 Chrome 打开/读取(以及需要时的读写打开)哪些路径rules.exec:允许 Chromeexec哪些可执行文件- 必须至少包含 Chrome 主程序、
chrome-sandbox、chrome_crashpad_handler等
- 必须至少包含 Chrome 主程序、
rules.write:允许写入哪些目录(profile、缓存、tmp、共享内存等通常需要)
系统调用规则是黑名单(默认允许):不写就代表允许;你写 deny,xxx 才会阻断。
allow|deny,syscall_name
典型用途:
- 你想进一步加固:添加
deny,socket(彻底禁网)等 - 你需要兼容某环境:用
allow,xxx覆盖默认阻断项(如果项目内置默认阻断)
说明:与文件打开/执行强相关的系统调用(如 open/openat/execve)通常由路径类规则完成控制,建议避免在 syscall 列表中重复配置。
- 先 ptrace,后 seccomp-notify
- ptrace 更适合完成策略收敛:更容易发现缺失权限与路径访问项
- 规则稳定后切到 seccomp-notify 获取更好的性能与更接近生产的形态
ptrace_enabled: true,audit_enabled: true运行目标用例- 遇到异常(启动失败/页面打不开/组件报错)就看审计日志里“被拒绝的路径/动作”
- 最小化地补齐
rules.file/exec/write - 用例稳定后将
ptrace_enabled: false、seccomp_notify: true(若环境支持) - 在 seccomp-notify 下复测并微调规则
- 策略固化:输出“基线配置 + 场景差异配置”(见第 10 章)
- 优先检查:
chrome_binary路径是否正确、rules.exec是否允许该路径 - 常见原因:Chrome 被禁止执行自身或辅助二进制(crashpad/sandbox)
- 优先检查:
rules.file是否放行了系统库、字体缓存、证书、/etc、/usr、/lib*等必要路径(按你的发行版不同而不同)
- 优先检查:
rules.write是否允许 profile 目录、/tmp、/dev/shm等 - 建议:为自动化任务显式指定 profile 目录并仅放行该目录(更利于收敛)
- 开启
logging.audit_enabled: true - 临时切换到
ptrace_enabled: true(更适合排障) - 逐条补齐规则,直到用例跑通
- launcher:外层启动器(本项目的
secure_chrome_launcher) - 监管:launcher 运行期间对受控行为进行判定与处置(允许/拒绝)
- 白名单:仅允许列表内项(
rules.file/rules.exec/rules.write) - 黑名单:默认允许,仅拒绝列表内项(
rules.syscalls)