下圖是家裡的流量圖,零晨到二點半那段是在看 Google IO 直播產生的流量,挺有趣的...:),不過 In/Out 相反了,後面有談到解決方法。

小烏龜就是申請中華電信網路服務時所配發的 vdsl modem,我拿到的型號是 ZyXEL P874,有簡易的 Web 介面可以透過瀏覽器設定,即時在遠端也可以透過 telnet 來作業。

$ telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
ZyXEL VDSL Router
Login: cht
Password: <google>

   Main Menu

 1. VDSL Link State
 2. LAN/WLAN
 3. WAN
 4. DNS Server
 5. Route Setup
 6. NAT
 7. Firewall
 8. Quality Of Service
 9. Management
10. Passwords
11. Reset to Default
12. Reboot
13. Exit
 > 9
 
   SNMP Agent Menu

 1. Configure
 2. Show
 3. Exit
/Management/SNMP Agent > 2

        SNMP Agent Information

State                : enable
Read only community  : chtnvdsl
Read write community : xdsl
System name          : CHT
System location      : unknown
System contact       : unknown
Trap IP address      : 0.0.0.0

Hit <enter> to continue

預設 SNMP 是開啟的,可以看到 Read only cummunity 的值是 chtnvdsl (咦!怎麼有點眼熟...XD),接著用 snmpwalk 來看一下總共有哪些 OID。

$ snmpwalk -c chtnvdsl 192.168.1.1
IF-MIB::ifNumber.0 = INTEGER: 14
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifIndex.4 = INTEGER: 4
IF-MIB::ifIndex.5 = INTEGER: 5
IF-MIB::ifIndex.6 = INTEGER: 6
IF-MIB::ifIndex.7 = INTEGER: 7
IF-MIB::ifIndex.8 = INTEGER: 8
IF-MIB::ifIndex.9 = INTEGER: 9
IF-MIB::ifIndex.10 = INTEGER: 10
IF-MIB::ifIndex.11 = INTEGER: 11
IF-MIB::ifIndex.12 = INTEGER: 12
IF-MIB::ifIndex.13 = INTEGER: 13
IF-MIB::ifIndex.14 = INTEGER: 14
IF-MIB::ifDescr.1 = STRING: eth0
IF-MIB::ifDescr.2 = STRING: eth1
IF-MIB::ifDescr.3 = STRING: eth2
IF-MIB::ifDescr.4 = STRING: eth3
IF-MIB::ifDescr.5 = STRING: wl0
IF-MIB::ifDescr.6 = STRING: wl0.1
IF-MIB::ifDescr.7 = STRING: wl0.2
IF-MIB::ifDescr.8 = STRING: wl0.3
IF-MIB::ifDescr.9 = STRING: ptm0
IF-MIB::ifDescr.10 = STRING: ptm0_1
IF-MIB::ifDescr.11 = STRING: ptm0_2
IF-MIB::ifDescr.12 = STRING: ptm0_4
IF-MIB::ifDescr.13 = STRING: ppp0_3
IF-MIB::ifDescr.14 = STRING: dsl0
... skip

確認完後就用 cfgmaker 產生設定檔樣版。

$ cfgmaker --output=mrtg.cfg chtnvdsl@192.168.1.1

接著修改設定,沒有 ifSpeed 的值和 ifOperStatus 為 down 時設定會是註解起來的,然後介面 ppp0_3 的 In/Out 是相反的,參考 MRTG Reference - Reversing 1,把 Target 的值多個負號 (-) 就可以了

範例

Target[ezci]: -1:public@ezci-ether.domain

接著用 mrtg 透過 RRDTool 來生流量圖,這個指令要定時跑才能定時更新流量圖,所以要把這個指令加入 cron 每五分鐘值行一次,Mac 可以透過 launchd 來排程。

$ env LANG=C mrtg /etc/mrtg.cfg

indexmaker 產生 HTML 並擺在 Web 存取的到的地方,這邊只要執行一次,要注意輸出的目錄權限能不能寫入。

$ indexmaker --output=/path/to/htdocs/mrtg/index.html --title=Home mrtg.cfg

這樣就完成了,等個 24 小時應該就有些數據可以看了。

在做之前其實有 survey 了其他的方案,比較過後最後還是覺得用 MRTG 簡單畫就好了,相依性少一點,如果要偵測異常流量的話只要定個 threshold,然後簡單寫個 shell script 排程跑寄信通知就好了。