golang读取silk网络流量文件的插件库silk的使用
Golang读取SiLK网络流量文件的插件库silk的使用
描述
这个包使得读取常见的silk文件变得容易,无需使用C Go。
什么是SiLK
SiLK是由卡内基梅隆大学CERT网络态势感知团队(CERT NetSA)开发和维护的一套网络流量收集和分析工具,用于促进大型网络的安全分析。SiLK工具套件支持高效地收集、存储和分析网络流数据,使网络安全分析师能够快速查询大型历史流量数据集。
支持的文件格式
记录大小 | 记录版本 | 压缩 | 支持 |
---|---|---|---|
88 | RWIPV6ROUTING VERSION 1 | None (0) | ✅ |
88 | RWIPV6ROUTING VERSION 1 | Zlib (1) | ✅ |
88 | RWIPV6ROUTING VERSION 1 | Lzo (2) | ✅ |
88 | RWIPV6ROUTING VERSION 1 | Snappy (3) | ✅ |
68 | RWIPV6 VERSION 1 | None (0) | ✅ |
68 | RWIPV6 VERSION 1 | Zlib (1) | ✅ |
68 | RWIPV6 VERSION 1 | Lzo (2) | ✅ |
68 | RWIPV6 VERSION 1 | Snappy (3) | ✅ |
56 | RWIPV6 VERSION 2 | None (0) | ✅ |
56 | RWIPV6 VERSION 2 | Zlib (1) | ✅ |
56 | RWIPV6 VERSION 2 | Lzo (2) | ✅ |
56 | RWIPV6 VERSION 2 | Snappy (3) | ✅ |
52 | RWGENERIC VERSION 5 | None (0) | ✅ |
52 | RWGENERIC VERSION 5 | Zlib (1) | ✅ |
52 | RWGENERIC VERSION 5 | Lzo (2) | ✅ |
52 | RWGENERIC VERSION 5 | Snappy (3) | ✅ |
示例
解析整个文件
package main
import (
"fmt"
"log"
"github.com/chrispassas/silk"
)
func main() {
var testFile = "testdata/FT_RWIPV6-v2-c0-L.dat"
var err error
var sf silk.File
if sf, err = silk.OpenFile(testFile); err != nil {
log.Fatalf("OpenFile() error:%s", err)
}
log.Printf("Compression:%d", sf.Header.Compression)
log.Printf("FileFlags:%d", sf.Header.FileFlags)
log.Printf("FileVersion:%d", sf.Header.FileVersion)
log.Printf("HeaderLength:%d", sf.Header.HeaderLength)
log.Printf("MagicNumber:%x", sf.Header.MagicNumber)
log.Printf("RecordFormat:%d", sf.Header.RecordFormat)
log.Printf("RecordSize:%d", sf.Header.RecordSize)
log.Printf("RecordVersion:%d", sf.Header.RecordVersion)
log.Printf("SilkVersion:%d", sf.Header.SilkVersion)
log.Printf("File record count:%d\n", len(sf.Flows))
fmt.Printf("start_time_ms,src_ip,dst_ip,src_port,dst_port\n")
for _, flow := range sf.Flows {
fmt.Printf("%d,%s,%s,%d,%d\n",
flow.StartTimeMS,
flow.SrcIP.String(),
flow.DstIP.String(),
flow.SrcPort,
flow.DstPort,
)
//Etc... for other silk.Flow values
}
}
基于通道的解析
package main
import (
"fmt"
"log"
"os"
"github.com/chrispassas/silk"
)
func main() {
var testFile = "testdata/FT_RWIPV6-v2-c0-L.dat"
var err error
flows := make([]silk.Flow, 0, 245340)
receiver := silk.NewChannelFlowReceiver(0)
reader, err := os.Open(testFile)
if err != nil {
log.Fatal(err)
}
defer reader.Close()
go func() {
if err = silk.Parse(reader, receiver); err != nil {
log.Fatal(err)
}
}()
for flow := range receiver.Read() {
/*
Pulling all data into an in memory array. That really isn't the point of the channel based
parser. You would want to stream it somewhere else to keep memory usage low. This is for example
purposes only.
*/
flows = append(flows, flow)
}
log.Printf("Compression:%d", receiver.Header.Compression)
log.Printf("FileFlags:%d", receiver.Header.FileFlags)
log.Printf("FileVersion:%d", receiver.Header.FileVersion)
log.Printf("HeaderLength:%d", receiver.Header.HeaderLength)
log.Printf("MagicNumber:%x", receiver.Header.MagicNumber)
log.Printf("RecordFormat:%d", receiver.Header.RecordFormat)
log.Printf("RecordSize:%d", receiver.Header.RecordSize)
log.Printf("RecordVersion:%d", receiver.Header.RecordVersion)
log.Printf("SilkVersion:%d", receiver.Header.SilkVersion)
log.Printf("File record count:%d\n", len(flows))
fmt.Printf("start_time_ms,src_ip,dst_ip,src_port,dst_port\n")
for _, flow := range flows {
fmt.Printf("%d,%s,%s,%d,%d\n",
flow.StartTimeMS,
flow.SrcIP.String(),
flow.DstIP.String(),
flow.SrcPort,
flow.DstPort,
)
//Etc... for other silk.Flow values
}
}
更多关于golang读取silk网络流量文件的插件库silk的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang读取silk网络流量文件的插件库silk的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Go语言读取silk网络流量文件的插件库
silk(Structured Internet流量记录)是一种用于网络流量分析的二进制格式,由CMU/SEI开发。在Go语言中,我们可以使用第三方库来读取和处理silk文件。
1. silk文件格式简介
silk文件通常包含网络流记录,每条记录包含源/目的IP、端口、协议、字节数、数据包数、时间戳等信息。文件扩展名通常是.rwf(原始流)或.rwf.gz(压缩流)。
2. Go语言中的silk处理库
目前Go语言中处理silk文件的主要库是go-silk
,这是一个纯Go实现的silk文件解析器。
安装
go get github.com/davidrenz/go-silk
3. 基本使用方法
3.1 打开silk文件
package main
import (
"fmt"
"log"
"github.com/davidrenz/go-silk/silk"
)
func main() {
// 打开silk文件
file, err := silk.Open("example.rwf")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// 获取文件头信息
header := file.Header()
fmt.Printf("文件类型: %s\n", header.FileType)
fmt.Printf("版本: %d\n", header.Version)
fmt.Printf("记录数: %d\n", header.Count)
}
3.2 读取流记录
func readRecords() {
file, err := silk.Open("example.rwf")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// 读取所有记录
for {
record, err := file.Next()
if err != nil {
if err == silk.EOF {
break
}
log.Fatal(err)
}
// 打印记录信息
fmt.Printf("源IP: %s, 目的IP: %s, 协议: %d, 字节数: %d\n",
record.SrcIP, record.DstIP, record.Proto, record.Bytes)
}
}
3.3 处理压缩的silk文件(.rwf.gz)
func readCompressed() {
file, err := silk.OpenGzip("example.rwf.gz")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// 读取记录...
}
4. 高级用法
4.1 过滤特定流量
func filterTraffic() {
file, _ := silk.Open("example.rwf")
defer file.Close()
for {
record, err := file.Next()
if err != nil {
break
}
// 只显示HTTP流量(端口80)
if record.DstPort == 80 || record.SrcPort == 80 {
fmt.Printf("HTTP流量: %s -> %s, 字节数: %d\n",
record.SrcIP, record.DstIP, record.Bytes)
}
}
}
4.2 统计流量
func trafficStats() {
file, _ := silk.Open("example.rwf")
defer file.Close()
var totalBytes, totalPackets uint64
ipStats := make(map[string]uint64)
for {
record, err := file.Next()
if err != nil {
break
}
totalBytes += uint64(record.Bytes)
totalPackets += uint64(record.Packets)
ipStats[record.SrcIP.String()] += uint64(record.Bytes)
}
fmt.Printf("总字节数: %d\n", totalBytes)
fmt.Printf("总数据包数: %d\n", totalPackets)
// 打印每个IP的流量
for ip, bytes := range ipStats {
fmt.Printf("%s: %d bytes\n", ip, bytes)
}
}
5. 性能考虑
当处理大型silk文件时,考虑以下优化:
- 使用缓冲读取
- 并行处理记录
- 选择性读取字段
func processLargeFile() {
file, _ := silk.Open("large.rwf")
defer file.Close()
// 使用缓冲通道并行处理
records := make(chan *silk.Record, 100)
done := make(chan bool)
// 启动多个工作goroutine
for i := 0; i < 4; i++ {
go func() {
for record := range records {
// 处理记录...
_ = record
}
done <- true
}()
}
// 读取记录并发送到通道
for {
record, err := file.Next()
if err != nil {
break
}
records <- record
}
close(records)
// 等待所有工作完成
for i := 0; i < 4; i++ {
<-done
}
}
6. 替代方案
如果go-silk
不能满足需求,还可以考虑:
- 使用C库
libfixbuf
并通过cgo调用 - 使用Python的
pyfixbuf
并通过系统调用 - 将silk文件转换为CSV/JSON再用Go处理
总结
Go语言的go-silk
库提供了简单易用的API来读取和分析silk网络流量文件。通过合理使用并发和缓冲技术,可以高效处理大型流量文件。对于更复杂的需求,可能需要考虑与其他语言工具链集成。
希望这些示例能帮助您开始使用Go处理silk网络流量数据!