Splunk Search

How to best determine IP range membership?

Splunk Employee
Splunk Employee

Use Case: Find Juniper firewall events where the source/destination IP (Src_Zone/Dst_Zone) does or does not belong in the private zone.

The private zone includes IP ranges defined by RFC1918 plus others:

  • 169.254.0.0 to 169.254.255.255 (RFC1918)
  • 10.0.0.0 to 10.255.255.255 (RFC1918)
  • 192.168.0.0 to 192.168.255.255 (RFC1918)
  • 172.16.0.0 to 172.31.255.255 (LinkLocal)

Proposed Splunk search macro for Src_Zone membership in the private zone:

Src_Zone=169.254.*.* OR Src_Zone=10.*.*.* OR Src_Zone=192.168.*.* OR Src_Zone=172.16.*.* OR Src_Zone=172.17.*.* OR Src_Zone=172.18.*.* OR Src_Zone=172.19.*.* OR Src_Zone=172.20.*.* OR Src_Zone=172.21.*.* OR Src_Zone=172.22.*.* OR Src_Zone=172.23.*.* OR Src_Zone=172.24.*.* OR Src_Zone=172.25.*.* OR Src_Zone=172.26.*.* OR Src_Zone=172.27.*.* OR Src_Zone=172.28.*.* OR Src_Zone=172.29.*.* OR Src_Zone=172.30.*.* OR Src_Zone=172.31.*.*

This approach is super unwieldy even as a macro, and is likely not efficient. There must be a better way to express membership in the last IP range defined by the private zone 172.16.0.0-172.31.255.255 without having to expand it. I tried incorporating the regex command (... | regex Src_Zone="172\.(1[6-9]|2\d|3[0-1])\.) but can't figure out how to use it in a boolean OR context.

This gets even hairier when trying to express membership where

Src_Zone!=<in the private zone> AND Dst_Zone=<in the private zone>.

Any suggestions on how to not brute force this?

Tags (2)
1 Solution

Splunk Employee
Splunk Employee

Many thanks, V!

For the scenario above, this is how your answer was applied:

... | where cidrmatch("10.0.0.0/8",Src_Addr) OR cidrmatch("172.16.0.0/12",Src_Addr) OR cidrmatch("192.168.0.0/16",Src_Addr) OR cidrmatch("169.254.0.0/16",Src_Addr)

Who knew the Splunk search language is so powerful. 😉 This is much simpler!

For the curious, here is further supporting information:

It is especially helpful to know the where and eval commands support booleans. For example, to solve the more difficult case of

Src_Zone!=<in the private zone> AND Dst_Zone=<in the private zone>

simply apply the NOT and AND boolean operators:

... | where NOT ( cidrmatch("10.0.0.0/8",Src_Addr) OR cidrmatch("172.16.0.0/12",Src_Addr) OR cidrmatch("192.168.0.0/16",Src_Addr) OR cidrmatch("169.254.0.0/16",Src_Addr) ) AND
( cidrmatch("10.0.0.0/8",Dst_Addr) OR cidrmatch("172.16.0.0/12",Dst_Addr) OR cidrmatch("192.168.0.0/16",Dst_Addr) OR cidrmatch("169.254.0.0/16",Dst_Addr) )

View solution in original post

Splunk Employee
Splunk Employee

We also allow the CIDR syntax in a search field comparison, so you could enter something simple like this in the search bar:

Src_Zone=172.16.0.0/16

This works for '=' and '!=', and you can still use the search boolean operators.

Splunk Employee
Splunk Employee

It is very sweet. Thank you, Marklar! So my IP range searches now are even shorter. I've even defined macros so my searches are super short, too:

For outbound traffic:

( Src_Addr=10.0.0.0/8 OR Src_Addr=172.16.0.0/12 OR Src_Addr=192.168.0.0/16 OR Src_Addr=169.254.0.0/16 ) AND ( Dst_Addr!=10.0.0.0/8 AND Dst_Addr!=172.16.0.0/12 AND Dst_Addr!=192.168.0.0/16 AND Dst_Addr!=169.254.0.0/16 AND Dst_Addr!=65.194.243.* AND Dst_Addr!=216.52.215.* )

0 Karma

Contributor

That's pretty sweet.

Splunk Employee
Splunk Employee

Many thanks, V!

For the scenario above, this is how your answer was applied:

... | where cidrmatch("10.0.0.0/8",Src_Addr) OR cidrmatch("172.16.0.0/12",Src_Addr) OR cidrmatch("192.168.0.0/16",Src_Addr) OR cidrmatch("169.254.0.0/16",Src_Addr)

Who knew the Splunk search language is so powerful. 😉 This is much simpler!

For the curious, here is further supporting information:

It is especially helpful to know the where and eval commands support booleans. For example, to solve the more difficult case of

Src_Zone!=<in the private zone> AND Dst_Zone=<in the private zone>

simply apply the NOT and AND boolean operators:

... | where NOT ( cidrmatch("10.0.0.0/8",Src_Addr) OR cidrmatch("172.16.0.0/12",Src_Addr) OR cidrmatch("192.168.0.0/16",Src_Addr) OR cidrmatch("169.254.0.0/16",Src_Addr) ) AND
( cidrmatch("10.0.0.0/8",Dst_Addr) OR cidrmatch("172.16.0.0/12",Dst_Addr) OR cidrmatch("192.168.0.0/16",Dst_Addr) OR cidrmatch("169.254.0.0/16",Dst_Addr) )

View solution in original post

Splunk Employee
Splunk Employee

Take a look at cidrmatch, in http://www.splunk.com/base/Documentation/4.0.8/SearchReference/CommonEvalFunctions. You can use it with WHERE, that should simplify things.

State of Splunk Careers

Access the Splunk Careers Report to see real data that shows how Splunk mastery increases your value and job satisfaction.

Find out what your skills are worth!