vbatts/tar-split

GitHub: vbatts/tar-split

tar-split 是一个将 tar 归档拆分为元数据与文件负载以实现校验和可复现重组的工具和 Go 库。

Stars: 110 | Forks: 31

# tar-split ![Build Status](https://static.pigsec.cn/wp-content/uploads/repos/cas/4b/4bb9aa1d2a70de578e070eae9354dc497906b1f72f0facf7c1e57754c5cfca1f.svg) ![Lint](https://static.pigsec.cn/wp-content/uploads/repos/cas/73/73ccbf4580efb36d6c888b7f4803d5e82c229071ca2fd1a481dac1a7a20547dc.svg) [![Go Report Card](https://goreportcard.com/badge/github.com/vbatts/tar-split)](https://goreportcard.com/report/github.com/vbatts/tar-split) 完美地拆分 tar 归档文件,并存储所需的原始终端和偏移量,以便重新组装出可验证的原始归档文件。 ## 文档 `tar-split` 提供的库的代码 API: * [github.com/vbatts/tar-split/tar/asm](https://pkg.go.dev/github.com/vbatts/tar-split/tar/asm) * [github.com/vbatts/tar-split/tar/storage](https://pkg.go.dev/github.com/vbatts/tar-split/tar/storage) * [github.com/vbatts/tar-split/archive/tar](https://pkg.go.dev/github.com/vbatts/tar-split/archive/tar) ## 安装 可以通过以下方式安装命令行工具: ``` go get github.com/vbatts/tar-split/cmd/tar-split ``` ## 用法 有关 cli 的用法,请参阅其 [README.md](cmd/tar-split/README.md)。 有关库的信息,请参阅[文档](#docs) ## 演示 ### 基本的拆分和组装 这演示了 `tar-split` 命令,以及如何从 `tar-data.json.gz` 组装出一个 tar 归档文件 ![basic cmd demo thumbnail](https://i.ytimg.com/vi/vh5wyjIOBtc/2.jpg?time=1445027151805) [基础命令演示的 YouTube 视频](https://youtu.be/vh5wyjIOBtc) ### Docker 层保留 这演示了 docker-1.8 的 tar-split 集成。为镜像层内容提供一致的 tar 归档文件。 ![docker tar-split demo](https://i.ytimg.com/vi_webp/vh5wyjIOBtc/default.webp) [docker 层校验和的 YouTube 视频](https://youtu.be/tV_Dia8E8xw) ## 注意事项 最终这应该能够检测到无法执行此操作的 TAR 文件。 例如,存储的具有“空洞”的稀疏文件将被读取为一个连续的文件,尽管归档内容可能以稀疏格式记录。 因此,当将文件负载添加到重新组装的 tar 中时,为了实现完全相同的输出,文件负载需要被精确地重新稀疏化。 这不是我打算立即修复的问题,而是宁愿提供一个警告,说明无法进行精确的重新组装。 (查看更多 http://www.gnu.org/software/tar/manual/html_node/Sparse-Formats.html) ## 约定 不要破坏我们的分支中 stdlib `archive/tar` 的 API(理想情况下是找到一个可以合并到上游的解决方案)。 ## Std 版本 golang stdlib `archive/tar` 的版本来自 go1.11 它进行了最小程度的扩展,以暴露 TAR 的原始字节,而不仅仅是序列化的头部和文件流。 ## 设计 请参阅[设计](concept/DESIGN.md)。 ## 存储的元数据 由于存储了头部和填充的原始字节,您可能会想知道对文件大小有什么影响。 每个文件的头部至少有 512 字节(有时更多),末尾至少有 1024 个 null 字节,以及各种填充。 这使得在使用简单的存储实现时,存储的元数据呈恒定的线性增长。 首先,我们将获取一个归档文件来进行操作。为了可重复性,我们将使用您刚刚克隆的内容制作一个归档: ``` git archive --format=tar -o tar-split.tar HEAD . ``` ``` $ go get github.com/vbatts/tar-split/cmd/tar-split $ tar-split checksize ./tar-split.tar inspecting "tar-split.tar" (size 210k) -- number of files: 50 -- size of metadata uncompressed: 53k -- size of gzip compressed metadata: 3k ``` 因此,假设您已经自己完成了归档文件的解压,并且为了从相对路径重用文件负载,那么额外的存储开销仅为 3kb。 但是让我们看一个包含许多文件的较大归档。 ``` $ ls -sh ./d.tar 1.4G ./d.tar $ tar-split checksize ~/d.tar inspecting "/home/vbatts/d.tar" (size 1420749k) -- number of files: 38718 -- size of metadata uncompressed: 43261k -- size of gzip compressed metadata: 2251k ``` 在这里,一个包含 38,718 个文件的归档,其压缩后的占用空间约为 2mb。 滚动归档末尾的 null 字节,我们将假设一个“字节/文件”的比率来评估存储开销。 | 未压缩 | 已压缩 | | :----------: | :--------: | | 每个文件约 1kb | 每个文件 0.06kb | ## 下一步计划? * 更多 storage Packer 和 Unpacker 的实现 * 更多 FileGetter 和 FilePutter 的实现 * 如果能有一个实现了 `io.Seeker` 的 assembler stream 会很有趣 ## 许可证 请参阅 [LICENSE](LICENSE)
标签:EVTX分析, Golang, 可重复构建, 安全编程, 归档处理, 日志审计, 请求拦截