Skip to content

Instantly share code, notes, and snippets.

@lowell80
Forked from waffle2k/cidr2regex.py
Last active September 5, 2022 14:21
Embed
What would you like to do?
Splunk deployment based on CIDR
#!/usr/bin/env python
''' Splunk deployment based on CIDR
Splunk's deployment server does not support CIDR based matching out of the box,
but they do support PCRE regex matching. I found this script online and
modified it slightly to match Splunk's specific regex variation. (Basically,
Splunk uses standards PCRE but replace the meaning of "." and "*" to act more
like traditional glob strings.) The values returned by this script can be
used in the serverclass.conf for either whitelist.<n> or blacklist.<n> values.
See the Splunk docs for more details.
Example usage:
echo "10.0.1.0/22" | python cidr2regex.py
Example output:
^10.0.[0-3].\d+$
Original cidr2regex.py script:
https://gist.github.com/tom-knight/1b5e0dcf39062af8910e
Thanks to github users:
petermblair, 2xyo, mordyovits, tom-knight
Splunk docs:
http://docs.splunk.com/Documentation/Splunk/latest/Admin/Serverclassconf
'''
import sys
from math import log10
def cidr_to_regex(cidr):
ip, prefix = cidr.split('/')
base = 0
for val in map(int, ip.split('.')):
base = (base << 8) | val
shift = 32 - int(prefix)
start = base >> shift << shift
end = start | (1 << shift) - 1
def regex(lower, upper):
if lower == upper:
return str(lower)
exp = int(log10(upper - lower))
if (int(str(lower)[-1]) > int(str(upper)[-1]) and exp == 0):
# increasing exp due to base 10 wrap to next exp
exp += 1
delta = 10 ** exp
if lower == 0 and upper == 255:
return "\d+"
if delta == 1:
val = ""
for a, b in zip(str(lower), str(upper)):
if a == b:
val += str(a)
elif (a, b) == ("0", "9"):
val += '\d'
elif int(b) - int(a) == 1:
val += '[%s%s]' % (a, b)
else:
val += '[%s-%s]' % (a, b)
return val
def gen_classes():
def floor_(x):
return int(round(x / delta, 0) * delta)
xs = range(floor_(upper) - delta, floor_(lower), -delta)
for x in map(str, xs):
yield '%s%s' % (x[:-exp], r'\d' * exp)
yield regex(lower, floor_(lower) + (delta - 1))
yield regex(floor_(upper), upper)
return "(%s)" % '|'.join(gen_classes())
def get_parts():
for x in range(24, -1, -8):
yield regex(start >> x & 255, end >> x & 255)
# Not using the typical r'\.' regex because Splunk automatically
# replaces "." with "\." for the whitelist and blacklist entries.
return '^%s$' % '.'.join(get_parts())
for line in sys.stdin.readlines():
print cidr_to_regex( line )
print
@habeebk
Copy link

habeebk commented May 4, 2020

Unable to run the code, give the error "inconsistent use of tabs and spaces in indentation". I did few things to correct indentation, but still issues. Appreciate if you could have a look, it will be greatly useful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment