-
-
Save lowell80/10428118 to your computer and use it in GitHub Desktop.
Splunk deployment based on CIDR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 ) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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