import re
import datetime
import time
from bernhard import Client
def parse_modsec_log(log_file_path):
parsed_logs = []
current_log = {}
current_section = None
with open(log_file_path, 'r') as file:
for line in file:
line = line.strip()
if line.startswith('---'):
current_section = line[14:15]
if current_section == 'Z':
# End of log entry, add current_log to parsed_logs
parsed_logs.append(current_log)
# Reset current_log for the next log entry
current_log = {}
else:
if current_section == 'A':
time_match = re.search(r'\[(\d+/\w+/\d+:\d+:\d+:\d+)', line)
if time_match:
# Convert timestamp to Unix epoch format
timestamp_str = time_match.group(1)
timestamp_obj = datetime.datetime.strptime(timestamp_str, '%d/%b/%Y:%H:%M:%S')
current_log['timestamp'] = int(timestamp_obj.timestamp())
# Extract client IP
client_ip_match = re.search(r'(\d+\.\d+\.\d+\.\d+)', line)
if client_ip_match:
current_log['client_ip'] = client_ip_match.group(1)
elif current_section == 'B':
match_host = re.match(r'Host: (.+)', line)
match_user_agent = re.match(r'User-Agent: (.+)', line)
if match_host:
current_log['host'] = match_host.group(1)
elif match_user_agent:
current_log['user_agent'] = match_user_agent.group(1)
elif current_section == 'D':
current_log['html_response'] = line
elif current_section == 'E':
current_log['http_response'] = line
elif current_section == 'F':
response_headers = line.split(': ')
if len(response_headers) == 2:
current_log[response_headers[0].lower()] = response_headers[1]
elif current_section == 'H':
modsec_warning_match = re.search(r'ModSecurity: Warning.*?\[msg "([^"]+)"\].*?\[tag "([^"]+)"\]', line)
if modsec_warning_match:
current_log['action'] = 'Warning'
current_log['msg'] = modsec_warning_match.group(1)
current_log['tag'] = modsec_warning_match.group(2)
file_match = re.search(r'\[file "([^"]+)"\]', line)
if file_match:
current_log['file'] = file_match.group(1)
data_match = re.search(r'\[data "([^"]+)"\]', line)
if data_match:
current_log['data'] = data_match.group(1)
unique_id_match = re.search(r'\[unique_id "([^"]+)"\]', line)
if unique_id_match:
current_log['unique_id'] = unique_id_match.group(1)
return parsed_logsdef send_to_riemann(event):
# Initialize Riemann client
client = Client()
# Send event to Riemann server
client.send(event)
log_file_path = "/var/log/modsec_audit.log"
parsed_logs = parse_modsec_log(log_file_path)
for log in parsed_logs:
event = {
'time': log.get('timestamp'),
'service': 'modsecurity',
'metric': 0,
'attributes': { 'host': log.get('host'),
'user_agent': log.get('user_agent'),
'file': log.get('file'),
'data': log.get('data'),
'unique_id': log.get('unique_id'),
'client_ip': log.get('client_ip')
}
}
send_to_riemann(event)
in influx i am only getting the service name and host ip which seems to be coming from riemann task 0