使用Go进行可扩展的操作系统分析

服务器

浏览数:102

2020-6-22

http://https://blog.kolide.com/using-go-for-scalable-operating-system-analytics-cb170d85b1c5


在Kolide,我们所做的一部分工作是构建一个客户端 – 服务器系统,以便管理一个名为osquery的开源工具的大型孤立安装。 尽管过去我已经写了关于osquery的文章,但是在这篇文章中,我想集中讨论如何使用Go来解决我们为osquery社区和内部分布式系统构建软件所面临的许多挑战。

Osquery是一个操作系统分析工具,它允许你使用SQL查询来表达操作系统状态。 然后,您可以使用您希望用于监视主机的查询的声明式配置来提供osquery。 对于每个查询,您使用选项来定义如何记录这些查询的结果(即:每当结果集更改时记录日志,以设定的时间间隔记录数据集的快照等)。 然后运营商可以使用这些数据来创建和注释基础架构的当前不断发展的数据模型。 您还可以存储这些原始数据(JSON)并将其加载到HDFS或BigQuery等数据仓库中。 分析这些数据对于完成与安全性,操作,设备管理和合规性相关的目标是有用的。

所以在Kolide,我们在osquery和管理osquery基础架构方面有很多经验。 为了使您的机群中的osquery部署成功,您需要拥有出色的打包工具:osquery提供了许多功能,但是为了利用其功能,配置可能相当复杂。 从osquery版本2.10.1开始,有115个可配置的选项。 通过文件系统的配置最有效地提供了文件的目录结构。 您可以使用自定义扩展,这些扩展将作为平台特定的二进制可执行文件进行分发。 为了实现您的具体目标,您必须具有良好的工具来打包和分发osquery 。
管理osquery还需要勤奋的更新卫生:为了利用最可靠的软件,使您能够监控紧急威胁,您应该真正保持osqueryd的最新。 Osquery是一个快速移动的项目,整个社区都有很多伟大的工作。 使用能够根据“更新通道”(即:“beta”,“stable”)自动更新和管理osquery的osquery管理器使得这个过程更容易,特别是在客户端和包管理可能不可靠的环境中。

Osquery启动器


在Kolide,我们用来管理osquery实例的工具,autoupdating osquery和建立与指定服务器的远程通信被称为“Launcher”。 你可以在我们的网站和GitHub上阅读Launcher。 Launcher是用Go编写的,并包含许多细节,使得扩展osquery部署变得更容易。 对于Go开发者来说,我最喜欢的代码库中的一些特性/部分包括: 一个osquery运行时 ,暴露了一个程序化的Go界面,它利用了Dave Cheney( 博客 , 视频 )流行的功能选项API模式。 一旦@groob将我引入这种模式,我就爱上了它。 这绝对需要更多的时间和样板,但是由此产生的API的美感和附加的类型安全性使其成为这些API的必备品。
一个现代的,类型安全的gRPC服务器规范 。 由Google创建的CNCF项目gRPC是一个优秀的RPC框架,基本上是基于HTTP2 协议缓冲区 ,具有大量有趣的功能。 我们编写了很多启动器服务器,所以有一个定义良好的,版本化的服务器规范是有用的。
使用“更新框架”的安全的osquery自动更新系统 。 由Docker创建的一个CNCF项目TUF是一个规范,概述了一个强大而完整的同行评审更新机制。 规范阐明了一个客户/服务器模型。 Kolide使用公证工具托管TUF服务器。 公证人 ,由Docker创建的一个CNCF项目提供了一个TUF服务器,我们在Kolide编写了一个名为Updater的专用的TUF客户端(当然是在Go中)。
所有这些组件在Launcher存储库( cmd / launcher / launcher.go )主文件的Launcher项目中连接在一起。

Kolide舰队


Launcher旨在与满足提供的gRPC服务器规范的服务器进行通信。 包生成器可以很容易地分发启动器和Osquery,但一台服务器是必要的,以完成运输。 为此,有一个开源的osquery舰队经理Kolide Fleet 。 我们以前在这个博客上写过关于Fleet的内容,Fleet的一个很好的特性就是它支持现有的osquery TLS服务器API以及新的osquery gRPC服务器API。 这使得用户可以通过现有的osquery部署轻松进行转换。

模式


启动器和软件包生成器和Fleet都遵循类似的模式,我们喜欢在Kolide的所有Go项目中遵循:
最小的程序文件应该总是在cmd / program /中。
无论何时需要将惯用程序接口映射到远程传输(如gRPC或HTTP),都可以使用Go-Kit。
使用新的Go Dep工具来管理依赖关系。
使用Dave Cheney的错误包来包装错误。
如果您的CLI不是非常复杂的话,可以使用OKLog中的Peter Bourgon建立的命令解析模式,而不是命令解析库。
不要使用init,也不要使用包级变量。 Peter Bourgon相当有说服力地写了这个 。 彼得说:

魔法不好; 全球状态是魔术→没有包水平变量; 没有func init。  

在您的API中传播一个context.Context 。 使用此上下文来传递请求UUID之类的东西,这在请求分布式跟踪时很有用。
为每个项目提供一个Dockerfile以促进Cloud Native测试和部署策略。

Kolide套件和风格指南

我们已经写了关于这些模式和更多的在我们的Go风格指南 ,在我们保留许多围绕我们的项目经常使用的Go库和助手的库中: kolide / kit 。 我们有许多实用程序和帮助程序,使得编写现代TLS服务器变得更加简单,在Go-Kit Logger之上还有更多帮手。 我们认为这些图书馆可以是一般的有用的,我们计划在未来的博客更多。

一致的开发人员使用GNU Make的经验

除了Fleet,Launcher,Updater和Kit之外,我们在这个领域还有一些内部的项目。 明显没有走出monorepo的道路,在所有这些项目中保持一定的紧密关系确实增加了开发者的经验。
每当Kolide的开发人员创建一个新的Go回购,他们将添加一个类似的Makefile
每个Kolide项目使用的基本Makefile结构需要以下命令:

make deps
make test
make build
./build/template --help
./build/template version
  #安装依赖关系管理器并调用它 
  #现在所有的kolide项目都使用dep,但是我们以前总是使用glide 
  #把这个隐藏在`make deps`之后,这个过渡是透明的 
 做出决定 
  #运行完整的测试套件 
  #这是(希望)只是一个轻包装上去测试 
  #有时我们也在这里添加短毛绒和静态分析仪 
 做测试 
  #为您的平台构建二进制文件 
  #你也可以运行`make xp`来交叉编译一个mac和linux二进制文件 
 使建立 
  ##现在你可以运行程序,获得帮助和版本信息 
  ./build/template --help 
  ./build/template版本 

这里包含了一个实现上述功能的Makefile文件。 注意kolide/kit的version包的使用方法,用于将基于git的版本工具轻松添加到程序中。

此外,请考虑使用kolide / kit版本包和OKLog命令解析模式的该程序的最小主文件 。对于这个例子,这些文件应该在Makefile和cmd/template/template.go ,但显然路径和template字符串需要替换为您的使用。

开发基础设施:Docker Compose和Minikube

我们的许多Go(和非Go)项目都需要某种基础设施来实现有效的本地开发。 例如,Kolide Fleet需要MySQL和Redis 。 MailHog对测试SMTP功能也很有用。 为了解决这个本地开发的需求,我们通常使用Docker Compose 。 例如,查看Fleet的docker-compose.yml 。 今后,我想开始将所有这些定义为Kubernetes部署或ReplicaSet,并通过Minikube管理本地开发基础架构。 由于我们在科里德生产Kubernetes,所以这种与当地环境的平衡将是进一步缩小开发和生产之间差距的有趣途径。

结论

在Kolide,我们创建和管理客户端 – 服务器软件,使操作系统分析变得简单,现代和可扩展。 这个领域非常适合Go擅长的领域。 我们喜欢写最好的Go,我们可以不断尝试改进。 如果你认为你可以帮助我们写出好的Go, 我们正在招聘 !

作者:xuanzilie