Hace ya más de un año, he hablado de este tema y desarrollado un script que cumplía su cometido… Pero ya que hemos actualizado el Servidor a Debian 9, he aprovechado para actualizar el Script de monitoreo para que sea más funcional y más claro en sus avisos.
Parte de este código fue obtenido del Blog de Stephen C Phillips y gracias a su contribución, no he tenido que exprimir más mis sesos 😛
Entre las mejoras aplicadas, es la utilización de un script en bash. Este script lo utilizamos para crear un servicio donde podremos lanzar el script Python o en otro lenguaje como un Servicio en el inicio del equipo. Con este cambio, tendremos el control en el script para arrancarlo, pararlo o reiniciarlo.
- seguridad_users.sh start
- seguridad_users.sh stop
- seguridad_users.sh restart
#!/bin/bash
DIR=/root
DAEMON=$DIR/seguridad_users.py
DAEMON_NAME=seguridad_users
# Add any command line options for your daemon here
DAEMON_OPTS=""
# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
DAEMON_USER=root
# The process ID of the script when it runs is stored here:
PIDFILE=/var/run/$DAEMON_NAME.pid
. /lib/lsb/init-functions
do_start () {
log_daemon_msg "Starting system $DAEMON_NAME daemon"
start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
log_end_msg $?
}
do_stop () {
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
log_end_msg $?
}
case "$1" in
start|stop)
do_${1}
;;
restart|reload|force-reload)
do_stop
do_start
;;
status)
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
;;
*)
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
exit 1
;;
esac
exit 0
Copy
#!/usr/bin/env python
import logging
import logging.handlers
import argparse
import smtplib
import subprocess
import sys
import time
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# CUANTA DE CORREO PARA ENVIAR EL AVISO --> User/Password para enviar correo electronicos
mail_destino = 'xxxxxx@xxxxxx.xxx'
mail_origen = 'xxxxxx@xxxxxx.xx'
username = 'xxxxxx'
password = 'xxxxxx'
def send_mail (sms_mail):
# Parametrizacion del mensaje
msg = MIMEMultipart()
msg['From'] = mail_origen
msg['To'] = mail_destino
msg['Subject'] = "Logueo en el Servidor --> valero-torres.es <--"
msg.attach(MIMEText(sms_mail, 'plain'))
# Modulo smtplib -- https://docs.python.org/3/library/smtplib.html
try:
smtpObj = smtplib.SMTP('xxxxxx.xx') # Servidor SMTP
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.ehlo()
smtpObj.login(username,password)
smtpObj.sendmail(mail_origen, mail_destino, msg.as_string())
print 'Correo enviado con Exito.'
smtpObj.quit()
except SMTPException:
print 'Error: el mensaje no pudo enviarse.'
return;
def writelastline (fname):
f = open (fname, 'a')
f.write('n------------------> WARNING | AVISANDO DE ESTA ULTIMA CONEXION <------------------')
f.write('n ' + mail_origen )
f.write('n------------------> WARNING | AVISANDO DE ESTA ULTIMA CONEXIONN <-----------------nn')
f.close()
LOG_FILENAME = "/var/log/seguridad-users.log"
parser = argparse.ArgumentParser(description="Servicio de Control de Acceso")
parser.add_argument("-l", "--log", help="file to write log to (default '" + LOG_FILENAME + "')")
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO) # Could be e.g. "DEBUG" or "WARNING"
handler = logging.handlers.TimedRotatingFileHandler(LOG_FILENAME, when="midnight", backupCount=3) # 3 Copias del LOG
formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
# Make a class we can use to capture stdout and sterr in the log
class MyLogger(object):
def __init__(self, logger, level):
"""Needs a logger and a logger level."""
self.logger = logger
self.level = level
def write(self, message):
# Only log if there is a message (not just a new line)
if message.rstrip() != "":
self.logger.log(self.level, message.rstrip())
sys.stdout = MyLogger(logger, logging.INFO)
sys.stderr = MyLogger(logger, logging.ERROR)
while True :
return_getlastline = subprocess.check_output('tail -6 /var/log/auth.log', shell=True)
for line in return_getlastline.splitlines():
if 'Successful login as' in line: # Webmin
intruso = line.split("as ")
datos_intruso = intruso[1].split("from ")
txt_mail = 'Conexion establecida al Servidor a traves de Webmin...nn Usuario = '+ datos_intruso[0] +'n IP = '+ datos_intruso[1] +'nnUltimas 10 lineas del log /var/log/auth.logn------------------------------------------------------- n' + subprocess.check_output('tail -10 /var/log/auth.log', shell=True)
send_mail(txt_mail)
writelastline('/var/log/auth.log')
if 'Accepted password for' in line: # SSH
intruso = line.split("for ")
datos_intruso = intruso[1].split("from ")
txt_mail = 'Conexion establecida al Servidor a traves de SSH...nn Usuario = '+ datos_intruso[0] +'n IP = '+ datos_intruso[1] +'nnUltimas 10 lineas del log /var/log/auth.logn------------------------------------------------------- n' + subprocess.check_output('tail -10 /var/log/auth.log', shell=True)
send_mail(txt_mail)
writelastline('/var/log/auth.log')
time.sleep(1) # Esperar (1 segundos).
Copy
Como mejorar del Script Python y para mí la más importante, es el envío de un mensaje al destinatario más entendible en vez de enviar las últimas 10 líneas de /var/log/auth.log cuando detecta una conexión.
Mensaje SSH

Mensaje WEBMIN
