開源網(wǎng)絡(luò)抓包與分析框架學(xué)習(xí)-Packetbeat篇

go初學(xué)者卓箫,有興趣者,歡迎交流學(xué)習(xí)垄潮。

開源簡介

packbeat是一個(gè)開源的實(shí)時(shí)網(wǎng)絡(luò)抓包與分析框架烹卒,內(nèi)置了很多常見的協(xié)議捕獲及解析,如HTTP弯洗、MySQL旅急、Redis等。在實(shí)際使用中牡整,通常和Elasticsearch以及kibana聯(lián)合使用藐吮,用于數(shù)據(jù)搜索和分析以及數(shù)據(jù)展示。

  • 開發(fā)環(huán)境:Go語言
  • Git:源碼管理
  • IDE:推薦sublime或者liteide

開發(fā)之前

1.packbeat已經(jīng)被elastic整合在beats項(xiàng)目中逃贝,使用前登錄github,并打開
https://github.com/elasticsearch/beats.fork到自己的倉庫谣辞。
如:https://github.com/lindsay-show/packbeat

2.創(chuàng)建相應(yīng)目錄
<pre><code>
mkdir -p $GOPATH/src/github.com/elastic

cd $GOPATH/src/github.com/elastic</pre></code>
3.git clone

<pre><code>git clone https://github.com/elasitc/beats.git

cd beats</pre></code>

4.修改官方庫為upstream源,設(shè)置自己的倉庫為orgin源

<pre><code>git remote rename origin upstream

git remote add origin git@github.com:lindsay-show/packbeat.git</pre></code>

5.獲取最新代碼(剛fork沐扳,可忽略)泥从,并創(chuàng)建分支用于自定義功能開發(fā)

<pre><code>git pull upstream master

git checkout -b mypackbeat</pre></code>

6.切換到packbeat,并獲取依賴信息

<pre><code>cd packbeat

mkdir -p $GOPATH/src/golang.org/x/

cd $GOPATH/src/golang.org/x

git clone https://github.com/golang/tools.git

go get github.com/tools/godep</pre></code>

7.使用make編譯packbeat源碼沪摄,得到packbeat可執(zhí)行文件

注:

[1] git的相關(guān)介紹和命令可參考 Git教程

[2] go安裝及環(huán)境變量配置可參考 Golang官網(wǎng)

源碼框架

packbeat項(xiàng)目源碼結(jié)構(gòu)如下:


packetbeat源碼代碼結(jié)構(gòu).png

packetbeat整合在beats項(xiàng)目中躯嫉,其中還包括topbeat以及filebeat,現(xiàn)簡要介紹beats源碼框架內(nèi)容如下:

  • /libbeat:公共依賴庫
  • /filebeat:logstash升級(jí)版纱烘,處理日志類型數(shù)據(jù)
  • /packbeat:網(wǎng)絡(luò)抓包
  • /topbeat:監(jiān)控系統(tǒng)性能;
  • /vendor:依賴的第三方庫(如dns開源庫或者其他協(xié)議棧)
  • /tests:用于測(cè)試的pcamp抓包文件
  • /scripts:測(cè)試腳本

關(guān)于topbeat及filebeat的更多介紹參考elastic官網(wǎng)和敬。

packebeat源碼框架介紹如下:

  • /packetbeat/main.go:項(xiàng)目啟動(dòng)入口;
  • /packetbeat/config/:config.go凹炸,定義了所有配置相關(guān)的struct結(jié)構(gòu)體
  • /packetbeat/debian/:打包相關(guān)
  • /packetbeat/docs/:文檔
  • /packetbeat/etc/:配置文件示例
  • /packetbeat/procs/:獲取系統(tǒng)內(nèi)核運(yùn)作狀態(tài)與進(jìn)程信息的工具類
  • /packetbeat/protos/:自定義協(xié)議類,每個(gè)子目錄對(duì)應(yīng)一個(gè)應(yīng)用協(xié)議,包含配置相關(guān)的結(jié)構(gòu)體及具體實(shí)現(xiàn)
  • /packetbeat/sniffer/:三種不同抓包方式的實(shí)現(xiàn)昼弟,如pcap啤它、af_packet及pf_ring
  • /packetbeat/tests/:測(cè)試相關(guān)的文件,包含協(xié)議pcap文件及python測(cè)試腳本

注:以上介紹針對(duì)packetbeat-1.2.1,區(qū)別官網(wǎng)的開發(fā)幫助文檔(官網(wǎng)未更新)舱痘。

工作原理

介紹了beats及packetbeat源碼結(jié)構(gòu)变骡,簡要說明一下packetbeat的工作原理:

每一個(gè)協(xié)議都有一個(gè)或者多個(gè)固定的端口用于通信,開發(fā)者要做的事情就是定義協(xié)議端口芭逝,然后按照TCP以及UDP實(shí)現(xiàn)對(duì)應(yīng)的接口塌碌,Packetbeat會(huì)捕獲到指定端口的數(shù)據(jù)包,然后交給開發(fā)者定義的方法來解析旬盯,如TCP對(duì)應(yīng)的是Parse台妆,UDP是ParseUdp.解析出來的結(jié)構(gòu)化數(shù)據(jù)封裝成Json,插入到Elasticsearch中胖翰,后續(xù)便可使用Elasticsearch的搜索和數(shù)據(jù)統(tǒng)計(jì)能力進(jìn)行應(yīng)用層數(shù)據(jù)分析接剩。

使用方法

了解Packetbeat的工作原理后,接下來介紹如何使用packetbeat進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)包捕獲及分析萨咳。

在上述介紹中懊缺,我們知道packetbeat/protos目錄下支持自定義協(xié)議,目前Packebeat支持的協(xié)議如下:

  • ICMP (v4 and v6)
  • DNS
  • HTTP
  • Mysql
  • PostgreSQL
  • Redis
  • Thrift-RPC
  • MongoDB
  • Memcache

以HTTP為例培他,安裝packetbeat源碼后鹃两,配置文件packetbeat.yml中默認(rèn)已經(jīng)配置了上述支持的協(xié)議類型。使用步驟簡述如下:

  • 安裝Packetbeat源碼
  • 配置packetbeat.yml文件舀凛,默認(rèn)不用更改(默認(rèn)配置輸出到elasticsearch)
  • 加載packetbeat索引至elasticsearch中(使用第三方腳本)
  • 啟動(dòng)elasticsearch及kibana俊扳,查看http數(shù)據(jù)包捕獲及分析

如:啟動(dòng)packetbeat,打開幾個(gè)網(wǎng)頁猛遍,在終端極即可看到packetbeat已注冊(cè)的協(xié)議類型以及http請(qǐng)求數(shù)據(jù)和應(yīng)答數(shù)據(jù)包

<pre><code>
cd packetbeat-1.2.1

./packetbeat -N -e </pre></code>

注:

[1] Packetbeat詳細(xì)使用說明拣度,請(qǐng)參考Packetbeat官方幫助文檔,非常詳細(xì)螃壤。

[2] Elasticsearch及kibana的安裝和使用,請(qǐng)參考Elastic官方幫助文檔筋帖。

擴(kuò)展協(xié)議開發(fā)

在前面介紹到奸晴,目前packetbeat支持的協(xié)議類型主要是HTTP等常見協(xié)議類型,即時(shí)通信協(xié)議日麸,如sip寄啼、msrp以及xmpp等暫不支持逮光。如何對(duì)packetbeat進(jìn)行協(xié)議擴(kuò)展是我們研究該源碼的主要目的。

網(wǎng)絡(luò)傳輸兩大協(xié)議TCP和UDP墩划,應(yīng)用層協(xié)議都離不開這兩種協(xié)議涕刚,如源碼中的HTTP、MySQL走的是TCP傳輸協(xié)議乙帮,DNS走的是UDP協(xié)議杜漠,在Packetbeat里面,要實(shí)現(xiàn)自定義協(xié)議察净,只需實(shí)現(xiàn)這兩者對(duì)應(yīng)的接口驾茴。擴(kuò)展協(xié)議的框架代碼可分別參考基于TCP的http以及基于udp的dns協(xié)議實(shí)現(xiàn)代碼。

在進(jìn)行擴(kuò)展協(xié)議開發(fā)之前氢卡,需要了解protos/register.go中tcp锈至、udp以及基礎(chǔ)協(xié)議的接口定義:

  • TcpPlugin:TCP協(xié)議插件的接口定義。其中Pares()用于解析Packet译秦,ReceivedFin()用于處理TCP斷開連接峡捡,GapInStream()處理空包丟包,ConnectionTimeout()處理超時(shí)時(shí)間
  • UdpPlugin:UDP協(xié)議插件的接口定義筑悴。其中ParseUdp()用于解析Packet
  • ProtocolPlugin:TCP和UDP以及其他擴(kuò)展協(xié)議均需要實(shí)現(xiàn)ProtocolPlugin的基礎(chǔ)接口们拙,主要是提供獲取端口方法

上述對(duì)應(yīng)的接口定義如下所示:
<pre><code>
type Plugin interface {

// Called to return the configured ports

GetPorts() []int

}

type TcpPlugin interface {

Plugin
// Called when TCP payload data is available for parsing.
Parse(pkt *Packet, tcptuple *common.TcpTuple,
    dir uint8, private ProtocolData) ProtocolData
// Called when the FIN flag is seen in the TCP stream.
ReceivedFin(tcptuple *common.TcpTuple, dir uint8,   private ProtocolData) ProtocolData

// Called when a packets are missing from the tcp
// stream.

GapInStream(tcptuple *common.TcpTuple, dir uint8, nbytes int,
    private ProtocolData) (priv ProtocolData, drop bool)
// ConnectionTimeout returns the per stream connection timeout.
// Return <=0 to set default tcp module transaction timeout.
ConnectionTimeout() time.Duration

}

type UdpPlugin interface {

Plugin

// ParseUdp is invoked when UDP payload data is available for parsing.

ParseUdp(pkt *Packet)

}
</pre></code>

接下來,需要了解config.go中ProtocolCommon的結(jié)構(gòu)體雷猪,擴(kuò)展協(xié)議需要繼承該基本結(jié)構(gòu).

協(xié)議的基本配置結(jié)構(gòu)體定義如下所示(該結(jié)構(gòu)體對(duì)應(yīng)packetbeat.yml的配置結(jié)構(gòu)睛竣,參考默認(rèn)的packetbeat.yml文件):
<pre><code>
type ProtocolCommon struct {

Ports              []int         `config:"ports"`

SendRequest        bool          `config:"send_request"`

SendResponse       bool          `config:"send_response"`

TransactionTimeout time.Duration `config:"transaction_timeout"`

}
</pre></code>

最后了解一下packetbeat中的關(guān)于packet結(jié)構(gòu)定義:
<pre><code>
type Packet struct {

Ts      time.Time

Tuple   common.IpPortTuple

Payload []byte

}
</pre></code>

  • Ts:收到數(shù)據(jù)包的時(shí)間戳
  • Tuple:來源ip+來源端口+目的ip+目的端口的元組
  • Payload:應(yīng)用層字節(jié)數(shù),不包括tcp及udp頭部信息求摇,這部分正是七層協(xié)議需要解析的部分

以上射沟,擴(kuò)展協(xié)議的基本思路介紹完畢。現(xiàn)以sip協(xié)議擴(kuò)展開發(fā)為例:(擴(kuò)展開發(fā)之前与境,參考前文開發(fā)之前所述)

<pre><code>
cd $GOPATH/src/github.com/elastic/beats/packetbeat/protos

mkdir sip&&cd sip

touch sip.go config.go sip_parse.go

</pre></code>

其中验夯,sip.go用于sip協(xié)議的具體實(shí)現(xiàn),包括實(shí)現(xiàn)基于TCP及UDP對(duì)應(yīng)的解析方法摔刁,config.go用于sip協(xié)議的配置結(jié)構(gòu)定義挥转,sip_parse.go用于sip消息解析結(jié)構(gòu)的定義。
config.go中定義如下:
<pre><code>
package sip

import (

"github.com/elastic/beats/packetbeat/config"

"github.com/elastic/beats/packetbeat/protos"

)

//ProtocolCommon struct

type sipConfig struct {

config.ProtocolCommon ``config:",inline"

}

var (
defaultConfig = sipConfig{

    ProtocolCommon: config.ProtocolCommon{

        TransactionTimeout: protos.DefaultTransactionExpiration,
    },
}

)
</pre></code>
sip下的config.go定義完畢后共屈,在packetbeat.yml中增加sip對(duì)應(yīng)的配置绑谣,如下所示:
<pre><code>
protocols:
sip:
ports: [5060,5260]
# send_request and send_response control whether or not the stringified SIP
# request and response message are added to the result.
# Nearly all data about the request/response is available in the sip.*
# fields, but this can be useful if you need visibility specifically
# into the request or the response.
# Default: false
# send_request: true
# send_response: true
</pre></code>

在sip.go中實(shí)現(xiàn)udp協(xié)議插件接口方法Parseudp,并注冊(cè)協(xié)議拗引,使用registor.go中的register方法借宵,如下:
<pre><code>
func init() {

protos.Register("sip", New)

}

func New(
testMode bool,

results publish.Transactions,

cfg *common.Config,

) (protos.Plugin, error) {

p := &Sip{}
config := defaultConfig
if !testMode {
    if err := cfg.Unpack(&config); err != nil {
        return nil, err
    }
}
if err := p.init(results, &config); err != nil {
    return nil, err
}
return p, nil

}
</pre></code>
最后一步,在packetbeat的main.go主程序中加載sip協(xié)議矾削,如下所示:
<pre><code>
package main

import (

"os"
"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/packetbeat/beater"
// import support protocol modules
_ "github.com/elastic/beats/packetbeat/protos/amqp"
_ "github.com/elastic/beats/packetbeat/protos/dns"
_ "github.com/elastic/beats/packetbeat/protos/http"
_ "github.com/elastic/beats/packetbeat/protos/memcache"
_ "github.com/elastic/beats/packetbeat/protos/mongodb"
_ "github.com/elastic/beats/packetbeat/protos/mysql"
_ "github.com/elastic/beats/packetbeat/protos/nfs"
_ "github.com/elastic/beats/packetbeat/protos/pgsql"
_ "github.com/elastic/beats/packetbeat/protos/redis"
_ "github.com/elastic/beats/packetbeat/protos/sip"
_ "github.com/elastic/beats/packetbeat/protos/thrift"

)
</pre></code>

使用makefile壤玫,編譯packeteat豁护,執(zhí)行./packetbeat -N -e后,在終端上會(huì)顯示sip協(xié)議已注冊(cè)成功欲间。

至此楚里,packetbeat的協(xié)議擴(kuò)展介紹完畢了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末猎贴,一起剝皮案震驚了整個(gè)濱河市班缎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嘱能,老刑警劉巖吝梅,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異惹骂,居然都是意外死亡苏携,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門对粪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來右冻,“玉大人,你說我怎么就攤上這事著拭∩磁ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵儡遮,是天一觀的道長乳蛾。 經(jīng)常有香客問我,道長鄙币,這世上最難降的妖魔是什么肃叶? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮十嘿,結(jié)果婚禮上因惭,老公的妹妹穿的比我還像新娘。我一直安慰自己绩衷,他們只是感情好蹦魔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咳燕,像睡著了一般勿决。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上招盲,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天剥险,我揣著相機(jī)與錄音,去河邊找鬼宪肖。 笑死表制,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的控乾。 我是一名探鬼主播么介,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蜕衡!你這毒婦竟也來了壤短?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤慨仿,失蹤者是張志新(化名)和其女友劉穎久脯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镰吆,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帘撰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了万皿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摧找。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖牢硅,靈堂內(nèi)的尸體忽然破棺而出蹬耘,到底是詐尸還是另有隱情,我是刑警寧澤减余,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布综苔,位于F島的核電站,受9級(jí)特大地震影響位岔,放射性物質(zhì)發(fā)生泄漏如筛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一赃承、第九天 我趴在偏房一處隱蔽的房頂上張望妙黍。 院中可真熱鬧,春花似錦瞧剖、人聲如沸拭嫁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽做粤。三九已至,卻和暖如春捉撮,著一層夾襖步出監(jiān)牢的瞬間怕品,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工巾遭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肉康,地道東北人闯估。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像吼和,于是被迫代替她去往敵國和親涨薪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容