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

1 回复

更多关于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文件时,考虑以下优化:

  1. 使用缓冲读取
  2. 并行处理记录
  3. 选择性读取字段
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不能满足需求,还可以考虑:

  1. 使用C库libfixbuf并通过cgo调用
  2. 使用Python的pyfixbuf并通过系统调用
  3. 将silk文件转换为CSV/JSON再用Go处理

总结

Go语言的go-silk库提供了简单易用的API来读取和分析silk网络流量文件。通过合理使用并发和缓冲技术,可以高效处理大型流量文件。对于更复杂的需求,可能需要考虑与其他语言工具链集成。

希望这些示例能帮助您开始使用Go处理silk网络流量数据!

回到顶部