Netflow Activity dashboard showing MB’s in to dest_ip

Description:

Dashboard that helps me understand activity in my home lab looking at netflow data from my OPNsense firewall.  This dashboard starts with a simple timechart that gives me a trend of average mb_in across all of my devices. I have OPNsense configured to send netflow data v9 to a Splunk independent stream forward which then sends to my Splunk indexer.  

This dashboard utilizes the Network Topology – Custom Visualization and the Network Toolkit to be more interactive and perform WHOIS actions on source IP addresses.  You will need to have both of those apps installed for the dashboard to work as intended.  

You will also need to adjust the base search of this dashboard to match the index where the netflow data lives.  This dashboard uses post processing and you will need to edit the source XML provided. 

Here is a video that provides an overview of the dashboard and how to adjust the source XML:

Add-on’s required:

Network Topology – Custom Visualization: https://splunkbase.splunk.com/app/3762/

Network Toolkit: https://splunkbase.splunk.com/app/3491/

Dashboard:

<form theme="light" version="1.0">
  <label>Netflow Activity view -PostProcess</label>
  <search id="net_base1">
    <query>index=netflow_opnsense dest_ip=192.168.0.0/16 
| stats count by _time bytes_in src_ip src_port dest_ip dest_port tcp_flags tos nexthop_addr
| lookup hall_dhcp_leases.csv ip as src_ip OUTPUT hostname as src_host 
| lookup hall_dhcp_leases.csv ip as dest_ip OUTPUT hostname as dest_host </query>
    <earliest>$time1.earliest$</earliest>
    <latest>$time1.latest$</latest>
    <sampleRatio>1</sampleRatio>
  </search>
  <fieldset submitButton="true" autoRun="false">
    <input type="time" token="time1">
      <label></label>
      <default>
        <earliest>-24h@h</earliest>
        <latest>now</latest>
      </default>
    </input>
  </fieldset>
  <row>
    <panel>
      <chart>
        <search base="net_base1">
          <query>
| eval mb_in=((bytes_in/1024)/1024)
| timechart avg(mb_in) by dest_host useother=f usenull=f span=1m limit=30</query>
        </search>
        <option name="charting.axisLabelsX.majorLabelStyle.overflowMode">ellipsisNone</option>
        <option name="charting.axisLabelsX.majorLabelStyle.rotation">0</option>
        <option name="charting.axisTitleX.visibility">visible</option>
        <option name="charting.axisTitleY.visibility">visible</option>
        <option name="charting.axisTitleY2.visibility">visible</option>
        <option name="charting.axisX.abbreviation">none</option>
        <option name="charting.axisX.scale">linear</option>
        <option name="charting.axisY.abbreviation">none</option>
        <option name="charting.axisY.scale">linear</option>
        <option name="charting.axisY2.abbreviation">none</option>
        <option name="charting.axisY2.enabled">0</option>
        <option name="charting.axisY2.scale">inherit</option>
        <option name="charting.chart">line</option>
        <option name="charting.chart.bubbleMaximumSize">50</option>
        <option name="charting.chart.bubbleMinimumSize">10</option>
        <option name="charting.chart.bubbleSizeBy">area</option>
        <option name="charting.chart.nullValueMode">zero</option>
        <option name="charting.chart.showDataLabels">none</option>
        <option name="charting.chart.sliceCollapsingThreshold">0.01</option>
        <option name="charting.chart.stackMode">default</option>
        <option name="charting.chart.style">shiny</option>
        <option name="charting.drilldown">all</option>
        <option name="charting.layout.splitSeries">0</option>
        <option name="charting.layout.splitSeries.allowIndependentYRanges">0</option>
        <option name="charting.legend.labelStyle.overflowMode">ellipsisMiddle</option>
        <option name="charting.legend.mode">standard</option>
        <option name="charting.legend.placement">right</option>
        <option name="charting.lineWidth">2</option>
        <option name="refresh.display">progressbar</option>
        <option name="trellis.enabled">0</option>
        <option name="trellis.scales.shared">1</option>
        <option name="trellis.size">medium</option>
        <drilldown>
          <set token="hostname">$click.name2$</set>
        </drilldown>
      </chart>
    </panel>
  </row>
  <row>
    <panel>
      <title>Reviewing $hostname$</title>
      <input type="multiselect" token="field1" searchWhenChanged="true">
        <label>MB Usage selection:</label>
        <choice value="very_low">very_low</choice>
        <choice value="low">low</choice>
        <choice value="medium">medium</choice>
        <choice value="high">high</choice>
        <choice value="very_high">very_high</choice>
        <default>very_low,low,medium,high,very_high</default>
        <prefix>search usage IN(</prefix>
        <suffix>)</suffix>
        <delimiter> </delimiter>
      </input>
      <viz type="network_topology.network_topology">
        <search base="net_base1">
          <query>| search dest_host=$hostname$
| fillnull value=outside src_host dest_host 
| eval mb_in=((bytes_in/1024)/1024)
| stats sum(mb_in) as mb_in by src_ip src_host dest_ip dest_host
| eval usage=case(mb_in&lt;.1,"very_low",mb_in&lt;1,"low",mb_in&lt;5,"medium",mb_in&lt;20,"high",mb_in&gt;20,"very_high")
| $field1$
| table src_ip src_host dest_ip dest_host usage</query>
        </search>
        <option name="drilldown">none</option>
        <option name="network_topology.network_topology.drilldown">false</option>
        <option name="network_topology.network_topology.link1">very_low</option>
        <option name="network_topology.network_topology.link1Color">#00d1b1</option>
        <option name="network_topology.network_topology.link1Dashed">true</option>
        <option name="network_topology.network_topology.link1Label">Below 0.1 MB - very low</option>
        <option name="network_topology.network_topology.link2">low</option>
        <option name="network_topology.network_topology.link2Color">#53a051</option>
        <option name="network_topology.network_topology.link2Dashed">false</option>
        <option name="network_topology.network_topology.link2Label">Below 1 MB - low</option>
        <option name="network_topology.network_topology.link3">medium</option>
        <option name="network_topology.network_topology.link3Color">#f8be34</option>
        <option name="network_topology.network_topology.link3Dashed">true</option>
        <option name="network_topology.network_topology.link3Label">Below 5 MB - medium</option>
        <option name="network_topology.network_topology.link4">high</option>
        <option name="network_topology.network_topology.link4Color">#dc4e41</option>
        <option name="network_topology.network_topology.link4Dashed">false</option>
        <option name="network_topology.network_topology.link4Label">Below 20 MB - high</option>
        <option name="network_topology.network_topology.link5">very_high</option>
        <option name="network_topology.network_topology.link5Color">#ed7db1</option>
        <option name="network_topology.network_topology.link5Dashed">true</option>
        <option name="network_topology.network_topology.link5Label">Above 20 MB - very high</option>
        <option name="network_topology.network_topology.unfocusOpacity">0</option>
        <option name="refresh.display">progressbar</option>
      </viz>
    </panel>
  </row>
  <row>
    <panel>
      <input type="multiselect" token="field2" searchWhenChanged="true">
        <label>Field selection:</label>
        <default>src_host,dest_ip,dest_host</default>
        <delimiter> </delimiter>
        <choice value="src_host">src_host</choice>
        <choice value="src_port">src_port</choice>
        <choice value="dest_host">dest_host</choice>
        <choice value="dest_ip">dest_ip</choice>
        <choice value="dest_port">dest_port</choice>
        <choice value="tcp_flags">tcp_flags</choice>
        <choice value="tos">tos</choice>
        <choice value="nexthop_addr">nexthop_addr</choice>
      </input>
      <table>
        <search base="net_base1">
          <query>
| search dest_host=$hostname$
| eval mb_in=((bytes_in/1024)/1024)
| fillnull value=outside src_host dest_host
| stats sum(mb_in) as mb_in by src_ip $field2$
| eval usage=case(mb_in&lt;.1,"very_low",mb_in&lt;1,"low",mb_in&lt;5,"medium",mb_in&lt;20,"high",mb_in&gt;20,"very_high")
| $field1$
| sort -mb_in</query>
        </search>
        <option name="drilldown">cell</option>
        <option name="refresh.display">progressbar</option>
        <drilldown>
          <set token="ip">$click.value$</set>
        </drilldown>
      </table>
    </panel>
    <panel>
      <title>WHOIS: $ip$</title>
      <table>
        <search>
          <query>| whois $ip$</query>
          <earliest>$time1.earliest$</earliest>
          <latest>$time1.latest$</latest>
        </search>
        <option name="drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </table>
    </panel>
  </row>
</form>
Share This:

Leave A Comment?