115 lines
4.2 KiB
Python
115 lines
4.2 KiB
Python
|
|
import logging
|
||
|
|
import logging.handlers
|
||
|
|
import socketserver
|
||
|
|
import threading
|
||
|
|
import time
|
||
|
|
from datetime import datetime
|
||
|
|
import os
|
||
|
|
|
||
|
|
from sqlalchemy import create_engine, Column, Integer, String, DateTime
|
||
|
|
from sqlalchemy.orm import sessionmaker, scoped_session
|
||
|
|
from sqlalchemy.ext.declarative import declarative_base
|
||
|
|
|
||
|
|
|
||
|
|
LOG_FILE_LOCATION = os.path.join(os.path.dirname(__file__), 'logs')
|
||
|
|
DB_FILE_NAME = "traffic.db" # set name of the sql database file
|
||
|
|
LOG_FILE_NAME = "Syslog-Server-Errors.log" # set desired output file name
|
||
|
|
FILENAME = os.path.join(LOG_FILE_LOCATION,LOG_FILE_NAME)
|
||
|
|
os.makedirs(os.path.dirname(FILENAME), exist_ok=True)
|
||
|
|
DATABASE_URI = f"sqlite:///{os.path.join(LOG_FILE_LOCATION,DB_FILE_NAME)}" # set desired database URI
|
||
|
|
|
||
|
|
# Here you can put IP addresses what will be allowed to send Syslog messages to the server
|
||
|
|
ALLOWED_SOURCE = ['10.10.10.254',]
|
||
|
|
|
||
|
|
# Set up logging
|
||
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
|
||
|
|
logger = logging.getLogger()
|
||
|
|
|
||
|
|
# Set up SQLAlchemy
|
||
|
|
engine = create_engine(DATABASE_URI, pool_size=200, pool_recycle=3600, connect_args={'timeout': 60})
|
||
|
|
Base = declarative_base()
|
||
|
|
|
||
|
|
class Traffic(Base):
|
||
|
|
__tablename__ = 'traffic'
|
||
|
|
id = Column(Integer, primary_key=True)
|
||
|
|
source_ip = Column(String)
|
||
|
|
data = Column(String)
|
||
|
|
timestamp = Column(DateTime, default=datetime.now())
|
||
|
|
|
||
|
|
# Create database table if it doesn't exist
|
||
|
|
Base.metadata.create_all(engine)
|
||
|
|
|
||
|
|
# Set up thread-local SQLAlchemy session
|
||
|
|
Session = scoped_session(sessionmaker(bind=engine))
|
||
|
|
|
||
|
|
class SyslogHandlerUDP(socketserver.BaseRequestHandler):
|
||
|
|
def handle(self):
|
||
|
|
try:
|
||
|
|
source_ip = self.client_address[0]
|
||
|
|
if source_ip in ALLOWED_SOURCE:
|
||
|
|
data = bytes.decode(self.request[0].strip())
|
||
|
|
protocol = 'UDP'
|
||
|
|
port = self.server.server_address[1]
|
||
|
|
# Save data to database
|
||
|
|
traffic = Traffic(source_ip=source_ip, data=data)
|
||
|
|
session = Session()
|
||
|
|
session.add(traffic)
|
||
|
|
session.commit()
|
||
|
|
else:
|
||
|
|
time_now = datetime.now()
|
||
|
|
raise Exception(f"Unauthorized Syslog client data received at: {time_now}")
|
||
|
|
|
||
|
|
logger.info(f'Received {protocol} data from {source_ip} on port {port}: {data}')
|
||
|
|
except Exception as e:
|
||
|
|
logger.error(f'Error handling request: {e}')
|
||
|
|
with open(FILENAME, 'a') as f:
|
||
|
|
f.write(f'ERR: {source_ip} -> {e}'.strip() + '\n')
|
||
|
|
|
||
|
|
class SyslogHandlerTCP(socketserver.StreamRequestHandler):
|
||
|
|
def handle(self):
|
||
|
|
try:
|
||
|
|
source_ip = self.client_address[0]
|
||
|
|
if source_ip in ALLOWED_SOURCE:
|
||
|
|
data = self.rfile.readline().decode().strip()
|
||
|
|
protocol = 'TCP'
|
||
|
|
port = self.server.server_address[1]
|
||
|
|
# Save data to database
|
||
|
|
traffic = Traffic(source_ip=source_ip, data=data)
|
||
|
|
session = Session()
|
||
|
|
session.add(traffic)
|
||
|
|
session.commit()
|
||
|
|
else:
|
||
|
|
time_now = datetime.now()
|
||
|
|
raise Exception(f"Unauthorized Syslog client data received at: {time_now}")
|
||
|
|
|
||
|
|
logger.info(f'Received {protocol} data from {source_ip} on port {port}: {data}')
|
||
|
|
except Exception as e:
|
||
|
|
logger.error(f'Error handling request: {e}')
|
||
|
|
with open(FILENAME, 'a') as f:
|
||
|
|
f.write(f'ERR: {source_ip} -> {e}'.strip() + '\n')
|
||
|
|
|
||
|
|
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||
|
|
pass
|
||
|
|
|
||
|
|
class ThreadedUDPServer(socketserver.ThreadingMixIn, socketserver.UDPServer):
|
||
|
|
pass
|
||
|
|
|
||
|
|
def start_servers(tcp_port, udp_port):
|
||
|
|
logger.info(f'Starting TCP server on port {tcp_port}')
|
||
|
|
tcp_server = ThreadedTCPServer(('0.0.0.0', tcp_port), SyslogHandlerTCP)
|
||
|
|
tcp_thread = threading.Thread(target=tcp_server.serve_forever)
|
||
|
|
tcp_thread.daemon = True
|
||
|
|
tcp_thread.start()
|
||
|
|
|
||
|
|
logger.info(f'Starting UDP server on port {udp_port}')
|
||
|
|
udp_server = ThreadedUDPServer(('0.0.0.0', udp_port), SyslogHandlerUDP)
|
||
|
|
udp_thread = threading.Thread(target=udp_server.serve_forever)
|
||
|
|
udp_thread.daemon = True
|
||
|
|
udp_thread.start()
|
||
|
|
|
||
|
|
while True:
|
||
|
|
time.sleep(1)
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
start_servers(tcp_port=514, udp_port=514)
|