#!/opt/imh-python/bin/python3
from collections import Counter
"""Check for modsec hits"""
log_file = Path('/usr/local/apache/logs/modsec_audit.log')
inode = log_file.stat().st_ino
prev_inode = get_previous('modsec')[0]
prev_line = get_previous('modsec')[1]
# Files dont exist, or were removed. Assume starting from scratch
if int(inode) != int(prev_inode):
# Inode changed. Logfile was most likely rotated. Start over
with open(log_file, encoding='ascii') as file:
for line in file.readlines():
line_number += 1 # Line number counter
if line.split()[-1] in ('80', '443'):
remote_ip = line.split()[3]
hits_list.append(remote_ip)
with open(log_file, encoding='ascii') as file:
line_number = int(prev_line)
for _ in range(int(prev_line)):
next(file) # Skip ahead past the lines we already did
line_number += 1 # Line number counter
if line.split()[-1] in ('80', '443'):
remote_ip = line.split()[3]
hits_list.append(remote_ip)
# update the cache file so we know where to pick up next time
update_marker('modsec', inode, line_number)
"""Check /var/log/messages for failed FTP logins"""
log_file = Path('/var/log/messages')
inode = log_file.stat().st_ino
prev_inode = get_previous('ftp')[0]
prev_line = get_previous('ftp')[1]
except Exception: # No cache files, start over
if int(inode) != int(prev_inode): # log rotated, start from beginning
with open(log_file, encoding='ascii') as file:
for line in file.readlines():
line_number += 1 # Increase line counter
if 'pure-ftpd' in line and 'Authentication failed' in line:
ip = line.split()[5].split("@")[1][:-1]
with open(log_file, encoding='ascii') as file:
line_number = int(prev_line)
for _ in range(int(prev_line)):
next(file) # Skip past lines we already parsed
line_number += 1 # Increase line counter
if 'pure-ftpd' in line and 'Authentication failed' in line:
ip = line.split()[5].split("@")[1][:-1]
# update the cache file so we know where to pick up next time
update_marker('ftp', inode, line_number)
"""check /var/lib/mysql/$server.err for failed logins"""
log_file = Path(f'/var/lib/mysql/{FQDN}.err')
inode = log_file.stat().st_ino
prev_inode = get_previous('mysql')[0]
prev_line = get_previous('mysql')[1]
except Exception: # No cache files, start over
if int(inode) != int(prev_inode): # log rotated, start from beginning
with open(log_file, encoding='ascii') as file:
for line in file.readlines():
line_number += 1 # increase line counter
if "Access denied" in line:
ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', line)
hits_list = hits_list + ip
with open(log_file, encoding='ascii') as file:
line_number = int(prev_line)
for _ in range(int(prev_line)):
next(file) # skip through
line_number += 1 # increase line counter
if 'Access denied' in line:
ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', line)
hits_list = hits_list + ip
update_marker('mysql', inode, line_number) # update the cache file
def update_marker(file_name, inode, line_number):
"""Update the file in /var/cache with the inode and line number"""
store_folder = Path('/var/cache/iptrack')
store_folder.mkdir(mode=0o755, parents=True, exist_ok=True)
store_file = store_folder / file_name
with open(store_file, 'w+', encoding='ascii') as file:
file.write(str(inode) + ':' + str(line_number))
except Exception as e: # If this fails, something is seriously wrong
def get_previous(log_name):
"""Get the previous line number we were on"""
with Path('/var/cache/iptrack', log_name).open(encoding='ascii') as file:
inode = line.split(":")[0]
line_no = line.split(":")[1]
def send_message(channel, service, server, ip, hits):
"""Send a message to rabbitmq"""
properties=pika.BasicProperties(
headers=({'service': service, 'server': server, 'hits': hits})
"""Scrape the log files, get some ips, and sent it to rabbitmq"""
with open('/opt/sharedrads/etc/rabbit_pass', encoding='ascii') as file:
for line in file.readlines():
rabbit_pass = line.strip()
host = 'ash-sys-pro-iptrack1.imhadmin.net'
credentials = pika.PlainCredentials('iptrack', rabbit_pass)
connection = pika.BlockingConnection(
pika.ConnectionParameters(host, credentials=credentials)
channel = connection.channel()
channel.queue_declare(queue='iptrack')
for key, val in Counter(scrape_http()).items():
send_message(channel, 'http', FQDN, key, val)
for key, val in Counter(scrape_ftp()).items():
send_message(channel, 'ftp', FQDN, key, val)
for key, val in Counter(scrape_mysql()).items():
send_message(channel, 'mysql', FQDN, key, val)
if __name__ == '__main__':