File size: 6,207 Bytes
7c89ed7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | # This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# Copyright (c) 2014 Mozilla Corporation
import netaddr
def isIPv4(ip):
try:
return netaddr.valid_ipv4(ip)
except:
return False
def isIPv6(ip):
try:
return netaddr.valid_ipv6(ip)
except:
return False
def addError(message, error):
'''add an error note to a message'''
if 'errors' not in message:
message['errors'] = list()
if isinstance(message['errors'], list):
message['errors'].append(error)
class message(object):
def __init__(self):
'''register our criteria for being passed a message
as a list of lower case strings or values to match with an event's dictionary of keys or values
set the priority if you have a preference for order of plugins to run.
0 goes first, 100 is assumed/default if not sent
'''
# ask for anything that could house an IP address
self.registration = ['sourceipaddress', 'destinationipaddress', 'src', 'dst', 'srcip', 'dstip', 'http_x_forwarded_for']
self.priority = 15
def onMessage(self, message, metadata):
'''
Examine possible ip addresses for the following:
ipv6 in an ipv4 field
ipv4 in another field
'-' or other invalid ip in the ip field
Also sets ipv4 in two fields:
ipaddress (decimal mapping IP)
ipv4address (string mapping)
While the IP field-type serves for IPv4 or IPv6,
it is not quite mature yet as kibana lacks filtering
to differentiate between IPv4 and IPv6, so always
having a string version is the most flexible option.
'''
if 'details' in message:
# forwarded header can be spoofed, so try it first,
# but override later if we've a better field.
if 'http_x_forwarded_for' in message['details']:
# should be a comma delimited list of ips with the original client listed first
ipText = message['details']['http_x_forwarded_for'].split(',')[0]
if isIPv4(ipText) and 'sourceipaddress' not in message['details']:
message['details']['sourceipaddress'] = ipText
if isIPv4(ipText) and 'sourceipv4address' not in message['details']:
message['details']['sourceipv4address'] = ipText
if isIPv6(ipText) and 'sourceipv6address' not in message['details']:
message['details']['sourceipv6address'] = ipText
if 'sourceipaddress' in message['details']:
ipText = message['details']['sourceipaddress']
if isIPv6(ipText):
message['details']['sourceipv6address'] = ipText
message['details']['sourceipaddress'] = '0.0.0.0'
addError(message, 'plugin: {0} error: {1}'.format('ipFixUp.py', 'sourceipaddress is ipv6, moved'))
elif isIPv4(ipText):
message['details']['sourceipv4address'] = ipText
else:
# Smells like a hostname, let's save it as source field
message['details']['source'] = message['details']['sourceipaddress']
message['details']['sourceipaddress'] = None
if 'destinationipaddress' in message['details']:
ipText = message['details']['destinationipaddress']
if isIPv6(ipText):
message['details']['destinationipv6address'] = ipText
message['details']['destinationipaddress'] = '0.0.0.0'
addError(message, 'plugin: {0} error: {1}'.format('ipFixUp.py', 'destinationipaddress is ipv6, moved'))
elif isIPv4(ipText):
message['details']['destinationipv4address'] = ipText
else:
# Smells like a hostname, let's save it as destination field
message['details']['destination'] = message['details']['destinationipaddress']
message['details']['destinationipaddress'] = None
if 'src' in message['details']:
ipText = message['details']['src']
if isIPv4(ipText):
message['details']['sourceipaddress'] = ipText
message['details']['sourceipv4address'] = ipText
if isIPv6(ipText):
message['details']['sourceipv6address'] = ipText
if 'srcip' in message['details']:
ipText = message['details']['srcip']
if isIPv4(ipText):
message['details']['sourceipaddress'] = ipText
message['details']['sourceipv4address'] = ipText
if isIPv6(ipText):
message['details']['sourceipv6address'] = ipText
if 'dst' in message['details']:
ipText = message['details']['dst']
if isIPv4(ipText):
message['details']['destinationipaddress'] = ipText
message['details']['destinationipv4address'] = ipText
if isIPv6(ipText):
message['details']['destinationipv6address'] = ipText
if 'dstip' in message['details']:
ipText = message['details']['dstip']
if isIPv4(ipText):
message['details']['destinationipaddress'] = ipText
message['details']['destinationipv4address'] = ipText
if isIPv6(ipText):
message['details']['destinationipv6address'] = ipText
if 'cluster_client_ip' in message['details']:
ipText = message['details']['cluster_client_ip']
if isIPv4(ipText):
message['details']['sourceipaddress'] = ipText
if isIPv6(ipText):
message['details']['sourceipv6address'] = ipText
return (message, metadata)
|