Splunk Search

How to best determine IP range membership?

hulahoop
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

hulahoop
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

Marklar
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.

hulahoop
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

Johnvey
Contributor

That's pretty sweet.

hulahoop
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

V_at_Splunk
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.

Did you miss .conf21 Virtual?

Good news! The event's keynotes and many of its breakout sessions are now available online, and still totally FREE!