網路流量視覺化 開源碼 Grafana MySQL 資料庫

擺脫商軟設限以開源替代 活用SNMP擷取網卡流入流出量

安裝Grafana彙整資料 繪製圖表快速判讀

2020-04-22
這裡介紹著名的開源碼圖表繪製平台Grafana,使用SNMP協定每10秒讀取一次主機內網路卡的流入和流出位元數值,並寫入MySQL資料庫,然後透過Grafana平台將資料庫內的資訊繪製成網路流量圖表,提供給IT人員當作管理參考。

 

為了能夠即時掌握網路狀態,網管人員通常會建立如MRTG(Multi Router Traffic Grapher)之類的軟體,搭配SNMP(Simple Network Management Protocol)通訊協定來即時取得主機上的網路卡流量資訊,並繪製成易懂的圖形提供給管理者參考網路流量的情形。但是,此類軟體通常都會有些限制,例如不能繪製5分鐘以下的網路流量圖。

為此,本文將說明如何利用SNMP協定及開源碼社群中最富盛名的圖表繪製平台Grafana來實作,使用SNMP協定來讀取主機上網路卡的流入及流出之位元數值,每10秒即讀取一次,將之寫入至MySQL資料庫。最後再透過Grafana平台,使用資料庫內的資訊來繪製成相關的網路流量圖表。可藉此擺脫相關限制,更有彈性地繪製相關的網路流量圖。

本文示範所使用的環境為CentOS 7,並且將使用net-snmp套件來實作SNMP服務。

‧Grafana官方網站:https://grafana.com/

認識SNMP

SNMP通訊協定主要的目的,在於能夠以統一的規範來管理網路上各式各樣的設備,例如主機、路由器等,它允許管理者利用一致的方法來管理設備上的裝置,如CPU、網路卡等,以下簡稱為裝置。

以系統架構來區分,SNMP可區分為代理者(Agent)、管理端(Manager)、管理資訊庫(Management Information Base,MIB)等三個元件。

代理者(Agent)

代理者通常為執行程式的型態,主要運作在被監控設備上以擷取裝置相關資料,例如網路卡的流量資訊,並等待管理端發出相關SNMP查詢指令,依據查詢指令的要求,將相關資訊回覆到管理端中。

除此之外,代理者還有另外一個重要的特性,即是可以設定相關的門檻條件,一旦發生符合的事件,就會以告警的型式主動通知管理端,例如可設定當CPU使用率超過100%便通知管理端。

管理端(Manager)

管理端主要是利用查詢指令來向代理者端查詢裝置的監控資訊,例如CPU使用率。而為了資料視覺化的原因,通常會將所查詢到的資訊,以工具(例如MRTG,在本文會以Grafana取代)繪製成圖表的方式來呈現。以SNMP第一版本(以下簡稱SNMP V1)為例,常用的指令如下所述:

GetRequest

由管理端發送給代理者端,用來讀取裝置上的相關數值,例如讀取網路卡所接收到的流量資訊。

GetNextRequest

由管理端發送給代理者端,由於SNMP通訊協定限制一次只能取得設備上一個裝置的資訊,因此管理端可利用此指令來取得下一個設備的資訊。

GetResponse

由管理端發送給代理者端,用來取得以GetRequest或GetNextRequest等查詢指令所讀取的數值。

SetRequest

由管理端發送給代理者端,用來設定代理者端某個裝置的設定值。

Trap

由代理者端發送給管理端,管理者可事先定義相關門檻條件,一旦設備發生符合門檻條件的事件,就主動回報至管理端。

管理資訊庫(MIB)

SNMP通訊協定的原始設計目的,就是要以相同的方式來管理各式各樣的設備,因此必須使用一致性的表示方法來描述設備。也因此,SNMP定義了物件識別碼(Object Identifier,以下簡稱OID)來描述各式各樣的網路設備,並利用樹狀結構的方式來說明相關設備的屬性,此類結構便稱為「管理資訊庫」。在管理資訊庫上的設備,皆可以定義成SNMP物件(Object)。

為了符合現實所需,管理資訊庫可以分為標準(Standard)和私人(Private)兩大類。

標準MIB適用於所有通用網路設備,而私人MIB則授權由設備廠商自行定義,以反映該設備的獨特的數值,例如描述某家廠商的獨特功能。

基本上,合法的私人MIB就跟網址一樣,需要向有關單位申請,以確保每一個私人MIB都是世上獨一無二的。如圖1所示,此為MIB的範例。

圖1  MIB範例示意圖。

在樹狀結構上的每一個物件,都會分配一組唯一的OID,例如Internet,其OID的表示方法即為iso.org.dod.internet或以1.3.6.1數字表示。而後,SNMP便會利用此OID值來操縱該物件(代理者端的設備)。

由於網路設備不斷地推陳出新,最初版本的SNMP已漸漸不敷使用,也因此有新的版本出現。就現況而言,目前SNMP版本可分為SNMP V1、SNMP V2、SNMP V3,接著簡略說明這三個版本的差異性。

SNMP V1主要存在如下幾個問題,分別加以說明:

1. 無法一次取得大量的資料,因此使用上必須重複地下達相關命令,方可取得完整的資料。

2. 無嚴謹的身分認證機制,在安全性上有相當大的疑慮。

3. 採用Pooling(輪詢)的管理方式,如果所設定間隔時間過長,會有無法即時取得代理者相關資訊的情況,但如果設定間隔時間過短,大量的傳輸封包又會影響網路的使用效能。

基於SNMP V1上述的缺點,因此又提出SNMP V2的通訊協定,主要是針對存取效率的改良,如下所述:

1. 新增GetBulkRequest命令,讓管理端只要下達一次命令即可取得大量相關資料,而不必經由多次的存取來取得相關資料,藉此提升讀取的效率。

2. 新增InformRequest指令,增強管理端與管理端的溝通能力,讓彼此之間能夠互相交換訊息。擺脫了SNMP V1一個網路環境只能部署一個管理系統的魔咒,這對於大型網路環境的管理是相當有利的。

3. 運用DES與MD5等編碼技術對於傳送中的資料進行編碼,以增進網路傳輸時的安全。

相對於SNMP V1而言,SNMP V2主要是改良V1版本的傳輸效率,但對於提升安全功能,並未多所著墨,也因此有SNMP V3的出現。

V3版本主要著重在安全功能上,透過對相關資料的加解密運用,提供以下的安全特性:

1. 確保相關資料一定是從合法的資料源發出。

2. 對於傳輸的資料進行加密,以確保資料的機密性,即使被擷取也無法被還原成原來的資料。

3. 利用密碼原理,確保傳輸資料在傳輸過程中不會被篡改。

在簡單說明過SNMP的基本原理之後,接下來即可安裝SNMP套件。

安裝SNMP

利用「yum install net-snmp*」指令,即可將SNMP安裝起來。在安裝完成後,就會產生以下幾個常用的應用程式:

snmpd

此為SNMP的主要程式,使用者可以利用此項程式,搭配snmpd.conf(SNMP的主要組態檔)的設定,來讀取所在設備上的資料。

snmpstatus

用來取得主機上某個裝置或主機的相關資訊,其命令格式為:

snmpstatus -v [SNMP版本] -c [社群名]

如果執行「snmpstatus -v 2c -c public 主機名稱」,即表示以SNMP版本為2c的通訊協定來取得主機的資訊,輸出結果如圖2所示。

圖2  以SNMP版本為2c的通訊協定來取得主機資訊。

snmpwalk

可顯示某個MIB架構下所有裝置資訊,其命令格式為:

snmpstatus -v [SNMP版本] -c [社群名]   [主機名稱] [OID]

以下例子為顯示主機網路卡流入(Input)流量的資訊,輸出結果如圖3所示:

圖3  顯示主機網路卡流入流量的資訊。

snmpwalk -v 2c -c public localhost 1.3.6.1.2.1.2.2.1.10

snmpget

用來取得被監控設備的相關資訊,其命令格式為:

snmpstatus -v [SNMP版本] -c [社群名] [主機名稱] [被監控裝置的OID]

若執行以下的命令範例,便可以取得系統上第一張網卡的輸入流量:

snmpget -v 2c -c public localhost .3.6.1.2.1.2.2.1.10.1

snmptranslate

可將OID資訊轉換易於閱讀的文字型式,由於裝置在MIB架構上都是以數字型態的方式呈現,較不易於使用者的閱讀,因此利用此指令來轉換成可閱讀的文字型態。以下範例可用來轉換主機網路卡的OID資訊:

snmptranslate 1.3.6.1.2.1.2.2.1.10

執行以上的命令之後,將會回覆如下的資訊:

IF-MIB::ifInOctets

設定SNMP組態檔

在簡單解釋幾個SNMP常用的程式之後,接下來設定SNMP的組態檔(/etc/snmpd.conf),這裡以V2C版本為例,基本上,要先設定使用者名稱與社群名稱,以及可允許查詢的來源範圍,其設定語法如下:

com2sec [USERNAME] [NETWORK_ SOURCE] [COMM_STRING]

其中,[USERNAME]為設定使用者名稱,[NETWORK_SOURCE]為設定可允許查詢SNMP資訊的來源資訊,可利用CIDR格式來設定,而[COMM_STRING]是設定社群(Community)名稱。如下例即表示允許localhost的主機可查詢社群名稱為public的裝置資訊:

com2sec notConfigUser localhost public

在設定完成使用者的組態後,即可繼續設定群組資訊,將使用者歸屬到某個群組,其設定格式如下所示:

group [GROUPNAME] [SNMP_VERSION]  [USERNAME]

其中,[GROUPNAME]為所設定的群組名稱,而[SNMP_VERSION]是使用的SNMP版本,[USERNAME]則為使用者名稱。若執行設定,表示將名稱為notConfigUser的使用者加入名稱為notConfigGroup的群組,並使用SNMP V2c的通訊協定溝通:

group notConfigGroup v2c notConfigUser

設定過使用者與群組資訊後,接著設定所能查看的SNMP裝置範圍,其設定格式如下:

view [檢視名稱] [include或exclude]  [OID]

由於在本文中,主要是監控網路卡的流量資訊,因此可設定成:

#1.3.6.1.2.1.2.2.1.16為流出(OUT) 的累計網路流量 view all included 1.3.6.1.2.1 .2.2.1.16 #1.3.6.1.2.1.2.2.1.10為網卡流入(IN) 的累計網路流量 view all included 1.3.6.1.2.1 .2.2.1.10

關於以上的設定,可以依照實際的需求來做修改。

最後的一個步驟,則是設定此群組適當的權限,使用其預設值即可,內容如下:

access notConfigGroup "" any noauth prefix all all all

在設定完成後,執行「service snmpd start」命令來啟動SNMP服務。

啟動完成後,利用「snmpwalk -v 2c -c public localhost 1.3.6.1.2.1.2.2.1.16」來確認是否正常地取得網路卡流量的資訊,藉以確認SNMP服務是否已經正常啟動。

在確認SNMP服務運作正常後,即可撰寫一個簡單的程式來擷取主機上的網路卡流量值,並寫入至MySQL資料庫,以供後續運用。

在本文中,所使用的資料庫名稱是「snmpdb」,可使用下列SQL指令來建立:

create database snmpdb;   #新建資料庫,名稱為snmpdb

接著,以如下的SQL指令來建立資料庫表格:

#新建資料庫表格,名稱為snmptable CREATE TABLE IF NOT EXISTS `snmpt able` (  `packtime` datetime NOT NULL,  #取得網路流量的時間  `in1` double DEFAULT '0',    #取得第一張網卡流入的累計流量  `out1` double DEFAULT '0',  #取得第一張網卡流出的累計流量   ) ENGINE=MyISAM DEFAULT CHARSET =utf8

然後,以下列自行撰寫之程式(以Perl為例)來取得網卡流量並計算出MBS(百萬位元組/秒),再寫入至資料庫中:

  #!/usr/bin/perl use DBI; $mdb="snmpdb"; $mhost='[資料庫所在主機]'; $muser='資料庫使用者帳號'; $mpassword='資料庫使用者密碼'; $mdbh = DBI->connect("DBI:mysql :database=$mdb;host=$mhost",$mu ser, $mpassword, {RaiseError => 1}); $subcnt=0; while($subcnt<10000) #取樣次數 {     $in=0;     $ret=`snmpwalk -v 2c -c       public localhost 1.3.6.1.2       .1.2.2.1.10`; #取得網卡       的輸入流量     $ret=~s/ //g;     @a_tmp=split(/\n/,$ret);     if($a_tmp[0]=~/(.+)(Counter       32:)(\d+)/)     {     $in=$3;  #取得網卡的輸入流量數值     }     $out=0;     $ret=`snmpwalk -v 2c -c     public localhost 1.3.6.1.2     .1.2.2.1.16`;       #取得網卡的輸出流量     $ret=~s/ //g;  #去除空白字元     @a_tmp=split(/\n/,$ret);     if($a_tmp[0]=~/(.+)(Counter     32:)(\d+)/)     {     $out=$3;  #取得網卡的輸出流量數值     }     sleep(10);  #暫停10秒後再重取一次     $in_after=0;     $out_after=0;     $ret=`snmpwalk -v 2c -c publi localhost 1.3.6.1.2.1.2.2.1.10`;     $ret=~s/ //g;     @a_tmp=split(/\n/,$ret);     if($a_tmp[0]=~/(.+)(Counter       32:)(\d+)/)     {         $in_after=$3;     }     $ret=`snmpwalk -v 2c -c     public localhost1.3.6.1.2.1     .2.2.1.16`; #out     $ret=~s/ //g;     @a_tmp=split(/\n/,$ret);     if($a_tmp[0]=~/(.+)(Counter     32:)(\d+)/)     {          $out_after=$3;     }     #MBS的公式為(round((($in_aft     er - $in)/10)/(1024*1024),     2));     $sql="insert into snmptable  set  packtime=now(),in1=round(". ((($in_after - $in)/10)/(1024* 1024)).",2),out1=round(".((($out_ after - $out)/10)/(1024*1024)). ",2)";     #寫入至資料庫     $msth=$mdbh->prepare($sql);     $msth->execute;     $subcnt++;

之後,執行此程式,就會每隔10秒重新取得網路卡的流入與流出之流量資訊,並在計算MBS後,寫入至資料庫中的snmptable表格。

最後,安裝Grafana,並設定其顯示的資料來源為snmptable表格,然後將儲存在該表格的資訊以圖形化的方式顯示出來。

安裝Grafana

安裝Grafana套件很簡單,僅須下載套件檔即可安裝:

wget https://dl.grafana.com/oss/ release/grafana-6.6.1-1.x86_64.rpm #取得最新版本的Grafana(本文所使用的版 本為6.6.1)

接著,再執行下列指令進行安裝作業:

yum install grafana-6.6.1-1.x86_64. rpm

安裝完成後,執行「service grafana-server start」命令來啟動Grafana伺服器。啟動成功之後,就會在通訊埠3000上運作網站服務。然後,使用者就可以利用瀏覽器連結「http://[Grafana伺服器IP]:3000」開始使用。

初次使用時,可以利用預設的帳號(admin)和密碼(admin)進行登入,如圖4所示。

圖4  利用預設的帳號和密碼登入Grafana。

在登入後,建議立即更換密碼。由於本文只是利用Grafana平台來顯示資料庫的資料,因此將只針對此部分做說明。首先,設定資料來源(Data Source),如圖5所示,選擇「MySQL」類型。

圖5  設定資料來源,請選擇「MySQL」類型。

接下來,設定此資料庫來源的相關資訊,主要是設定資料庫名稱、資料庫使用者權限及資料庫使用者密碼等資訊,然後設定此資料來源為預設(Default),如圖6所示。

圖6  設定資料庫來源的相關資訊。

設定好資料來源之後,即可新增一個儀表板(Dashboard)。新增時,會要求設定一個SQL查詢語法來顯示資料,如圖7所示,表示會依欄位packtime的時間值排序,來顯示snmptable表格內欄位in1的值。在設定完資料來源所使用的SQL查詢指令之後,最後選擇所要顯示的圖形種類,例如曲線圖或表格式圖形。點選圖7中的Graph圖示來設定所要呈現,為了更清楚地呈現資料內容,這裡選擇以表格式的圖形來呈現,如圖8所示。

圖7  設定SQL查詢語法來顯示資料。
圖8  選擇表格式圖形的呈現方式。

選擇完畢,儲存此儀表板的設定,隨後使用者就能夠利用此儀表板來即時查看snmptable內的資料,如圖9所示。

圖9  即時查看snmptable內的相關資料。

至此,就可以得到一個每10秒採樣一次的網路流量圖。

<本文作者:吳惠麟,多年資安經驗,喜好利用開源碼建構相關解決方案,著有「資訊安全原理與實驗」等書。>

 


追蹤我們Featrue us

本站使用cookie及相關技術分析來改善使用者體驗。瞭解更多

我知道了!