- 观测代理
- 网络安全
【免费下载链接】osquery
SQL powered operating system instrumentation, monitoring, and analytics.
导读
Augeas 是一套把系统配置文件解析为统一树形结构的 C 库,osquery 依赖它实现augeas(别名configurations)虚拟表,从而用 SQL 直接查询/etc/hosts等配置文件内容。本指南以仓库中的 libraries/cmake/source/augeas/README.md 为核心,完整讲解 osquery 如何在 Linux 与 macOS(含 Apple Silicon)上从源码构建 Augeas 静态库:从裁剪 libxml2 依赖、禁用命令行工具,到 autotools 配置、并行编译,再到把生成的 parser/lexer/config 文件回填进仓库的三方库目录。读完你不仅能在本地复现这一构建流程,还能理解生成物在 augeas 表的 C++ 实现 中如何被消费。
Augeas 在 osquery 中的角色:为什么需要一个"瘦身版"
Augeas 将配置文件暴露为一棵以/files为根的树,osquery 在 POSIX 平台上通过augeas表把这张树形数据映射为二维 SQL 结果。表结构定义在 specs/posix/augeas.table:
node:配置项在 Augeas 树中的路径(如/files/etc/hosts);value:配置项的值;label:配置项的标签(如hosts);path:对应的真实配置文件路径(附加列,如/etc/hosts)。
底层实现见 osquery/tables/system/posix/augeas.cpp:它调用aug_init(以AUG_NO_ERR_CLOSE | AUG_NO_LOAD | AUG_NO_STDINC | AUG_SAVE_NOOP模式初始化)、aug_load全量装载、aug_match匹配节点,并通过aug_ns_attr取回 value/label/file 元数据;lenses 目录由--augeas_lenses旗标指定(macOS 默认/private/var/osquery/lenses,其余平台默认/opt/osquery/share/osquery/lenses)。测试用例集中在 osquery/tables/system/tests/posix/augeas_tests.cpp,验证了按 path/node 精确匹配、LIKE 通配符展开等行为。
既然 Augeas 仅用于"读"配置树,osquery 不需要它的 XML 序列化能力,因此构建时砍掉了全部 libxml2 相关代码——这正是本 README 一切裁剪步骤的出发点。
为什么必须移除 libxml2 依赖
README 开篇即明确核心约束:Augeas 依赖 libxml2,但osquery 不会使用它。系统自带的 libxml2 足以满足构建期需求,而真正需要改动的是源码本身——在编辑 osquery 内的 Augeas CMakeLists 时,必须把augrun.c和xml.c从构建文件里剔除,因为这两者才是 libxml2 的消费者,且在 osquery 中完全用不到。在独立配置 Augeas 库时同样可以照此处理,从而让整个系统不再要求安装 libxml2。
仓库中的补丁文件 libraries/cmake/source/augeas/patches/src/remove-libxml2-dep.patch 给出了具体证据:它删除了src/augeas.h中的#include <libxml/tree.h>,并移除aug_to_xml声明——该函数正是把 Augeas 树转成 XML 树的唯一入口(xmlNode **xmldoc参数即 libxml2 类型)。补丁通过 libraries/cmake/source/modules/Findaugeas.cmake 中的PATCH "src"在源码拉取阶段自动应用。
而 libraries/cmake/source/augeas/CMakeLists.txt 则从另一侧呼应了 README:源文件列表只有ast.c、augeas.c、builtin.c、errcode.c、fa.c、get.c、hash.c、info.c、internal.c、jmt.c、lens.c、memory.c、pathx.c、put.c、ref.c、regexp.c、syntax.c、transform.c,既没有augrun.c也没有xml.c,并且 lexer/parser 直接复用generated/macos/x86_64/code/下预生成的产物(CMake 注释说明它们由最新版 flex/bison 生成,跨平台通用)。可见"移除 libxml2"不是口头约定,而是 patch 与构建清单双重落实的事实。
Linux 构建全流程
准备工具链环境
export TOOLCHAIN="/usr/local/osquery-toolchain" export PKG_CONFIG_SYSROOT_DIR=${TOOLCHAIN} export PKG_CONFIG_PATH= export PKG_CONFIG_LIBDIR=${TOOLCHAIN}/usr/lib/pkgconfig export PATH="${TOOLCHAIN}/usr/bin:${PATH}" export CFLAGS="--sysroot ${TOOLCHAIN}" export CXXFLAGS="${CFLAGS}" export CPPFLAGS="${CFLAGS}" export LDFLAGS="${CFLAGS}" export CC=clang这些变量让 pkg-config 只向 osquery 自带的工具链(/usr/local/osquery-toolchain)查找依赖,并用clang+--sysroot保证编译环境与最终打包环境一致。注意PKG_CONFIG_PATH被显式清空,避免宿主机/usr/lib/pkgconfig干扰。
裁剪构建目标
先用 sed 禁用测试、文档与示例:
sed -i '/SUBDIRS += tests man doc examples/d' Makefile.am sed -i '/SUBDIRS += gnulib\/tests/d' Makefile.am再禁用命令行工具(augtool、augparse、augmatch),同时剔除 readline 检查:
sed -i '/AUGEAS_CHECK_READLINE/d' configure.ac sed -i '/bin_PROGRAMS = augtool augparse augmatch/c\bin_PROGRAMS = ' src/Makefile.amosquery 只以静态库方式链接 Augeas,命令行工具与交互式 readline 支持都属于无用负担,去掉后还能减少 configure 阶段的依赖探测。
配置与编译
./autogen.sh \ --enable-static \ --enable-shared=no \ --without-selinux make -j $(nproc)--enable-static:生成静态库;--enable-shared=no:关闭共享库;--without-selinux:禁用 SELinux 相关代码(与 osquery 无关);make -j $(nproc):按 CPU 核数并行编译,缩短构建时间。
从生成物看,Linux 产物最终归档在generated/linux/{x86_64,aarch64}/下(见 generated/linux/x86_64/config/config.h,其中PACKAGE_STRING "augeas 1.12.0"确认本仓库锁定的是 Augeas 1.12.0)。
收集生成物
构建完成后需要把以下文件复制回 osquery 的三方库目录:
Augeas 侧生成物:
config.hdatadir.hparser.cparser.hlexer.c
gnulib 侧生成物:
config.h(注意:使用 Augeas 生成的那个,而非 gnulib 自带的)lib目录下所有包含GENERATED AUTOMATICALLY标记的文件
这些文件对应仓库中的目录结构:generated/ 存放 Augeas 的code/(parser、lexer)与config/(config.h、datadir.h),gnulib/generated/ 存放 gnulib 的config/与lib/头文件(如stdint.h、stdio.h、stdlib.h、string.h、alloca.h、fcntl.h、unistd.h等,Linux 侧还包含fnmatch.h、getopt*.h等)。gnulib 提供的可移植性头文件正是 Augeas 在异构平台上编译所需的垫片层。
macOS 构建全流程
通用准备
macOS 上必须从 Homebrew 安装 GNU 版本的bison与flex(系统自带的 BSD 版本过于陈旧,无法生成正确的 parser/lexer):
brew install bison flex裁剪步骤与 Linux 完全一致,只是把sed换成 GNU sed(gsed):
gsed -i '/SUBDIRS += tests man doc examples/d' Makefile.am gsed -i '/SUBDIRS += gnulib\/tests/d' Makefile.am gsed -i '/AUGEAS_CHECK_READLINE/d' configure.ac gsed -i '/bin_PROGRAMS = augtool augparse augmatch/c\bin_PROGRAMS = ' src/Makefile.amx86_64 构建
export PATH="/usr/local/opt/bison/bin:/usr/local/opt/flex/bin:${PATH}" export CFLAGS="-isysroot /Applications/Xcode_13.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -mmacosx-version-min=10.14 -Wunguarded-availability-new" export LDFLAGS="${CFLAGS}" export CC=clang要点解析:
- 把 brew 的 bison/flex 前置到
PATH,确保 autotools 使用 GNU 版本; -isysroot指向 Xcode 13.0 自带的 macOS 11.3 SDK;-mmacosx-version-min=10.14设定最低部署目标(与 osquery 对旧版 macOS 的支持基线一致);-Wunguarded-availability-new提前暴露可用性告警。
随后执行与 Linux 相同的./autogen.sh --enable-static --enable-shared=no --without-selinux与make -j $(nproc),并收集相同的 5 个 Augeas 文件与 gnulib 文件(config.h仍用 Augeas 那份,gnulib 侧收集lib下所有AUTOGENERATED标记的文件)。
macOS ARM(M1 / M2 等)构建
构建步骤同上,区别在于环境变量与交叉目标:
export CFLAGS="-isysroot /Applications/Xcode_13.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -mmacosx-version-min=10.15 -Wunguarded-availability-new -target arm64-apple-macos10.15" export LDFLAGS="${CFLAGS}" export CC=clang并额外向autogen.sh传递--host=arm64-apple-macos10.15,让 configure 按 ARM64 目标生成构建系统。最低部署版本在 ARM 上提高为 10.15,因为这是 Apple Silicon 可运行的最低 macOS 版本。
仓库中对应的归档可见 generated/macos/aarch64/ 与 gnulib/generated/macos/aarch64/ 等目录,分别保存code/、config/与lib/产物。另外需要留意,CMakeLists 中 lexer/parser 统一复用generated/macos/x86_64/code/的版本(因为它们由最新的 flex/bison 生成),ARM 目录下同样保留了独立生成的parser.c、parser.h、lexer.c以备参考。
生成物如何汇入 osquery 的 CMake 构建
README 描述的"复制生成物"动作,最终在构建系统里以importSourceSubmodule的形式固化。查看 libraries/cmake/source/modules/Findaugeas.cmake 可知:
- 先以
SHALLOW_SUBMODULES "src"浅拉取augeas/gnulib子模块; - 再以
NO_RECURSIVE+SHALLOW_SUBMODULES "src"拉取augeas本体,并应用PATCH "src"(即 remove-libxml2-dep.patch)。
随后 libraries/cmake/source/augeas/CMakeLists.txt 在augeasMain()中组装thirdparty_augeas静态库目标:
- 源文件取自子模块
src/下的 18 个.c文件,加上generated/macos/x86_64/code/下的lexer.c与parser.c; - 按平台选择
generated/{linux,macos,windows}/${TARGET_PROCESSOR}/config作为 include 路径,使config.h、datadir.h生效; - 定义
HAVE_CONFIG_H编译宏,链接thirdparty_c_settings、thirdparty_gnulib_headers并公开依赖thirdparty_gnulib_library; - 通过全局属性
AUGEAS_LENSES_FOLDER_PATH记录 lenses 目录(${library_root}/lenses),供运行时装载配置解析模板使用。
一个值得注意的细节:CMake 构建直接使用generated/macos/x86_64/的 lexer/parser,也就是说日常开发无需在每台机器上重跑 autogen——这正是本 README 所描述的"一次性生成、多平台复用"策略的落地:只有 Augeas 版本升级或 flex/bison 版本变化时,才需要按本指南重新走一遍完整流程并更新生成物。
构建注意事项与常见坑
- libxml2 一定要从源头上移除:既要在
CMakeLists.txt里剔除augrun.c、xml.c,也要保证 patch 中的aug_to_xml声明被删掉,否则链接期会报 libxml2 符号缺失。若你单独编译 Augeas 库(不经过 osquery),同样先按 remove-libxml2-dep.patch 裁剪再走 autogen。 - gnulib 的
config.h不能混用:README 反复强调"use the augeas one",因为 Augeas 的config.h定义了PACKAGE_STRING、HAVE_*等与 Augeas 编译直接相关的宏(见 generated/linux/x86_64/config/config.h),而 gnulib 的头文件层依赖这些宏保持一致。 - macOS 必须用 brew 的 bison/flex:系统自带版本过旧,生成的 parser 会报语法错误;同时记得
export PATH把 brew 版本前置。 - ARM 与 x86_64 的 SDK/部署目标不同:ARM 分支要求
-target arm64-apple-macos10.15且最低版本 10.15,不要照抄 x86_64 的 10.14 参数。 - 生成物目录按平台/架构归档:Linux 与 macOS、x86_64 与 aarch64 各有独立目录(generated/ 与 gnulib/generated/),升级版本时需要四套产物同步更新,避免交叉污染。
从构建到查询:验证 Augeas 集成
构建完成后,你可以用 osquery 的augeas表直接验证集成是否正常。官方 spec 提供的示例为:
select * from augeas where path = '/etc/hosts';测试文件 augeas_tests.cpp 给出了更细的断言矩阵,可直接当作行为规范:
- 按路径精确匹配:
select * from augeas where path = '/etc/hosts' and label = 'hosts' limit 1,期望node = '/files/etc/hosts'、path = '/etc/hosts'; - 按目录匹配:
path = '/etc'返回/files/etc目录节点; - 按节点匹配:
node = '/files/etc/hosts'; - 元数据节点:
node = '/augeas/load'返回 Augeas 自身的加载信息; - 通配符语义:LIKE 中
%被转换为 Augeas 的*(单层),%%被转换为//*(递归),例如node LIKE '/augeas/load/%'与node LIKE '/augeas/load/%%'的结果规模差异显著——这印证了 augeas.cpp 中patternsFromOsquery的%/%%→*///*转换逻辑。
测试运行时通过FLAGS_augeas_lenses指向测试配置目录下的augeas/lenses,模拟真实部署时--augeas_lenses的行为。这些测试既是对构建产物可用性的最终检验,也是理解 Augeas 树结构与 SQL 约束映射关系的最佳教材。
小结
本文以 libraries/cmake/source/augeas/README.md 为纲,还原了 osquery 构建 Augeas 1.12.0 静态库的完整链路:Linux 与 macOS 共用的裁剪手法(去 libxml2、去命令行工具、去测试文档)、autogen 配置参数、并行编译与产物收集清单,以及 Apple Silicon 下的交叉编译差异。对照仓库中的 patch、CMakeLists 与生成物目录可以看到,这一流程并非一次性手工操作,而是通过Findaugeas.cmake的子模块拉取与打补丁机制固化进构建系统的可复现步骤。理解了它,你就同时掌握了 Augeas 的构建定制方法论与 osquery 三方库"源码构建—产物归档—CMake 消费"的完整范式。
- 观测代理
- 网络安全
【免费下载链接】osquery
SQL powered operating system instrumentation, monitoring, and analytics.
相关推荐
osquery 内置 libmagic 第三方库构建指南:跨平台静态编译与 magic 表集成
osquery 内置 libmagic 第三方库构建指南:跨平台静态编译与 magic 表集成 导读 libmagic 是经典 file 命令背后的文件类型识别
观测代理网络安全osquery 中 zlib 第三方库的构建集成指南:跨平台静态编译与宏定义对齐实践
osquery 中 zlib 第三方库的构建集成指南:跨平台静态编译与宏定义对齐实践 导读 本文基于 libraries/cmake/source/zlib/R
观测代理网络安全终极指南:如何使用Sentry Native SDK实现C/C++应用崩溃监控
终极指南:如何使用Sentry Native SDK实现C/C++应用崩溃监控 想要为你的C/C++应用程序添加专业的错误监控和崩溃报告功能吗?Sentry N
观测代理网络安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考