Splunk Search

Perform a cidrmatch against a network CIDR retrieved from an inputlookup

seaofdreams1978
Engager

Hi All,

We run searches against logs that return, as part of the dataset, IP addresses.

We basically want to know what network and VLAN a given address belongs to so I created a CSV file that contains the following:

network          vlan   name

10.1.1.0/24   12      Server Network

10.1.2.0/24   13      Printer Network

So I'd like to pull in the CSV data and perform a cidrmatch against it using each IP address the search comes across.

If there is no match I want the fields to just return "No Data" so we can then go and update the CSV with anything missing.

As a test I've done the following:

| inputlookup Network_VLAN_Names.csv | fields network vlan name| where NOT isnull(network)
| dest_ip="10.1.1.21"
| foreach network [eval subnet=if(cidrmatch('<<FIELD>>', dest_ip), <<FIELD>>, "No Match")]

| search subnet!="No Match"

| table _time dest_ip vlan name

| sort _time asc


The first issue is that if there is no match, the row isn't returned all (I just want particular fields in a row of returned data to reflect the VLAN and friendly name of the network (if available in the CSV), not for the row to not be available.

Also when I've tried using:

<base search>

| append [ inputlookup Network_VLAN_Names.csv | fields network vlan name| where NOT isnull(network) ]
| foreach network [eval subnet=if(cidrmatch('<<FIELD>>', dest_ip), <<FIELD>>, "No Match")]

| search subnet!="No Match"

| table _time dest_ip vlan name

| sort _time asc


I get nothing back...

There's probably a simple solution to this but I'm not seeing it!

Any help would be much appreciated.

Labels (1)
0 Karma
1 Solution

Richfez
SplunkTrust
SplunkTrust

So, a couple of things.

First, and primarily, I'd switch the csv file /inputlookup into a regular cidr based lookup.

Settings/Lookups/Lookup Definitions (the file's already there so you don't have to add it in "lookup table files").

Add a new lookup definition, name it "networks" or similar, pick your file.

THEN click advanced options.  On "Match type" type in "CIDR(network)" to tell it to cidrmatch on the csv file's field "network."

Then here's a run anywhere search that creates three ip addresses (each in their own event), then uses the lookup we just created to match it to a network.

| makeresults
| eval ip = "192.168.1.12,10.11.12.13,192.168.2.99"
| makemv delim="," ip
| mvexpand ip
| lookup networks network as ip output name
| fillnull value="No Match" name

I do it this way because if you were, say, matching against firewall data, you could replace the first four lines (makeresults through mvexpand) with whatever search you had that displayed an IP address, then modify the lookup slightly and it should work on data of pretty much unbounded size, and quickly. 

In your case, if dest_ip is the field to use, you'd use something like

index=firewall sourcetype=cisco:asa blah blah 
| lookup networks network as dest_ip output name
| fillnull value="No Match" name
| table dest_ip name

 

And obviously, that last line can be changed to `| stats count by name` or any number of other things.

 

For reference, my networks.csv looks like this:

network,name
192.168.1.0/24,home
192.168.2.0/24,guest

 and the transforms.conf entry looks like

[networks]
batch_index_query = 0
case_sensitive_match = 1
filename = networks.csv
match_type = CIDR(network)

 

View solution in original post

seaofdreams1978
Engager

Perfect, worked like a charm and very fast!

Really appreciate the assistance and the fast response!

0 Karma

Richfez
SplunkTrust
SplunkTrust

So, a couple of things.

First, and primarily, I'd switch the csv file /inputlookup into a regular cidr based lookup.

Settings/Lookups/Lookup Definitions (the file's already there so you don't have to add it in "lookup table files").

Add a new lookup definition, name it "networks" or similar, pick your file.

THEN click advanced options.  On "Match type" type in "CIDR(network)" to tell it to cidrmatch on the csv file's field "network."

Then here's a run anywhere search that creates three ip addresses (each in their own event), then uses the lookup we just created to match it to a network.

| makeresults
| eval ip = "192.168.1.12,10.11.12.13,192.168.2.99"
| makemv delim="," ip
| mvexpand ip
| lookup networks network as ip output name
| fillnull value="No Match" name

I do it this way because if you were, say, matching against firewall data, you could replace the first four lines (makeresults through mvexpand) with whatever search you had that displayed an IP address, then modify the lookup slightly and it should work on data of pretty much unbounded size, and quickly. 

In your case, if dest_ip is the field to use, you'd use something like

index=firewall sourcetype=cisco:asa blah blah 
| lookup networks network as dest_ip output name
| fillnull value="No Match" name
| table dest_ip name

 

And obviously, that last line can be changed to `| stats count by name` or any number of other things.

 

For reference, my networks.csv looks like this:

network,name
192.168.1.0/24,home
192.168.2.0/24,guest

 and the transforms.conf entry looks like

[networks]
batch_index_query = 0
case_sensitive_match = 1
filename = networks.csv
match_type = CIDR(network)

 

youngsuh
Contributor

Additional idea on this thought is based on baseline of probing network.  You can use this information to assign a risk base alert.  Just a thought... 

0 Karma
Get Updates on the Splunk Community!

Enterprise Security Content Update (ESCU) | New Releases

In December, the Splunk Threat Research Team had 1 release of new security content via the Enterprise Security ...

Why am I not seeing the finding in Splunk Enterprise Security Analyst Queue?

(This is the first of a series of 2 blogs). Splunk Enterprise Security is a fantastic tool that offers robust ...

Index This | What are the 12 Days of Splunk-mas?

December 2024 Edition Hayyy Splunk Education Enthusiasts and the Eternally Curious!  We’re back with another ...