EDITED: added a Layer3 socket code to speed up the script
I have written this python script that reads log files and re-transmit this data as [network] Syslog traffic .. it may help somebody else who is trying to solve the same problem!
#!/usr/bin/python
# Description: this script retransmits syslog data from flat files to network traffic
# Non-standard dependencies: Scapy libraries
# To use this script on own environment, adjust the GLOBAL VARIABLES section below accordingly
# It will also need to run under sudo because of the use of Scapy
###########
from scapy.all import *
from os import walk
from re import search
import subprocess
import time
#
# As this script will be running from a cronjob once every X minutes, i'll check if it's already
# running before launching a new instance. If one is already running, this script will exit
# The reason it gets relaunched via a cronjob is to have some resilience in case it crashes or forced
# to exit by other external factors
#
pids = subprocess.check_output('pidof -x "textlogs2syslog.py"', shell=True, text=True)
pids = pids.split()
if len(pids) > 1:
print ("Another process is running .. I'm exiting")
exit(1)
#
# GLOBAL VARIABLES
#
source_dir = '/path/to/incoming/' # directory where log files will be picked up from
dest_ip = '10.0.0.63' # destination syslog server
source_port = 10000 # can be changed
dest_port = 514 # destination port number for the SIEM syslog server
archive_path = '/path/to/archive/' # where files will be moved to after processing
#
# this script will run until SIGINT
#
while True:
f = []
for (dirpath, dirnames, filenames) in walk(source_dir):
f.extend(filenames)
for file in f:
if search("^logs_", file):
try: # extract the IP address from the file name, filenames have this naming convention: logs_[IPv4_ADDRESS]_*.*
ip = re.search('^.*_(.+?)_', file).group(1)
source_ip = ip
except AttributeError:
pass
else: # ignores and skip non-conformant filenames
continue
# open the log file and assign a handle to it
file_handle = open(source_dir + file, 'r')
Lines = file_handle.readlines()
# iterate through the text file line by line before transferring every line as a Syslog event
# this is where Scapy gets used to generate the network traffic
s = conf.L3socket()
for line in Lines:
payload = "<134>1 " + line.strip() # strips the newline character
# <134> prepend this to reinstate the syslog event facility header
# 1 prepend this to reinstate the syslog event priority header
spoofed_packet = IP(src=source_ip, dst=dest_ip) / UDP(sport=source_port, dport=dest_port) / payload
s.send(spoofed_packet)
# iterating through a single log file ends here
# when done with transmitting the file content, the log file will be moved to an archive directory
os.system("mv " + source_dir + file + " " + archive_path)
break
print("finished iterating through files, will sleep and try again")
time.sleep(0.01)