-
Notifications
You must be signed in to change notification settings - Fork 2
/
monitor.py
109 lines (88 loc) · 3.83 KB
/
monitor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import telegram
from dotenv import load_dotenv
import os
import sh
import ipaddress
import argparse
import sys
load_dotenv()
ERROR_AUTH_LOG_LINES_TOKENS = ['invalid user', 'connection closed']
TELEGRAM_BOT_AUTHENTICATION_TOKEN = os.getenv('TELEGRAM_BOT_AUTHENTICATION_TOKEN')
SECURITY_ALERTS_CHANNEL = os.getenv('TELEGRAM_SECURITY_ALERTS_TARGET')
SYSTEM_MONITORING_CHANNEL = os.getenv('TELEGRAM_SYSTEM_REPORTS_TARGET')
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def main():
parser = argparse.ArgumentParser(description='System monitoring via Telegram', add_help=True)
parser.add_argument('--send-report', action='store_true', help='sends week use summary to TELEGRAM_SYSTEM_REPORTS_TARGET')
parser.add_argument('--listen-auth-log', action='store_true', help='listens to login attempts on /var/log/auth.log and sends reports to TELEGRAM_SECURITY_ALERTS_TARGET')
args = parser.parse_args()
bot = telegram.Bot(TELEGRAM_BOT_AUTHENTICATION_TOKEN)
if args.send_report:
bot.send_message(SYSTEM_MONITORING_CHANNEL, get_system_summary_str(), parse_mode=telegram.ParseMode.MARKDOWN)
elif args.listen_auth_log:
# listen to log files
auth_log_path = '/var/log/auth.log'
def on_log_auth_path_new_line(line):
line = line.strip()
print('new line detected in auth.log={}'.format(line))
if any(token in line.lower() for token in ERROR_AUTH_LOG_LINES_TOKENS):
bot.send_message(SECURITY_ALERTS_CHANNEL, get_security_alert_str(line), parse_mode=telegram.ParseMode.MARKDOWN)
auth_log_tail = sh.tail('-f', '-n 0', auth_log_path, _out=on_log_auth_path_new_line, _bg=True)
auth_log_tail.wait()
else:
parser.print_usage()
sys.exit(1)
def get_security_alert_str(text):
return '⚠️📢 `{}`'.format(text)
def get_last_week_logins():
last_week_logins_dict_list = []
for line in sh.lastlog('-t 7'):
line = line.strip().split()
if line[0] != 'Username':
login_dict = dict()
login_dict['user'] = line[0]
try:
ipaddress.ip_address(line[2])
login_dict['ip'] = line[2]
login_dict['date'] = ' '.join(line[3:])
except ValueError:
login_dict['ip'] = None
login_dict['date'] = ' '.join(line[2:])
last_week_logins_dict_list.append(login_dict)
return last_week_logins_dict_list
def get_system_summary_str():
SECURITY_UPDATES_COUNT_COMMAND = 'apt list --upgradable 2>/dev/null | grep "\-security" | wc -l'
security_updates_count = sh.bash('-c', SECURITY_UPDATES_COUNT_COMMAND)
last_week_logins = get_last_week_logins()
last_week_logins_str = ''
for i, login_dict in enumerate(last_week_logins):
last_week_logins_str += 'User: {}\n'.format(login_dict['user'])
ip = login_dict['ip']
if ip != None:
last_week_logins_str += 'IP: {}\n'.format(ip)
last_week_logins_str += 'Date: {}\n'.format(login_dict['date'])
if i < len(last_week_logins) - 1:
last_week_logins_str += '--\n'
available_space_str = ''
for i, line in enumerate(sh.df('-h', '--total')):
line = line.strip().split()
if line[0] != 'Filesystem':
if line[5] == '-':
line[5] = 'TOTAL'
available_space_str += '{} {}\n'.format(line[4], line[5])
uptime_str = sh.uptime('-p')
return \
'''\
⏳🖥️ *UPTIME*: {}
🔔📋 *SECURITY UPDATES AVAILABLE*: {}
💻 *LAST WEEK LOGINS*
`{}`
💽 *% DISK USAGE*
`{}`\
'''.format(uptime_str.strip(), security_updates_count.strip(), last_week_logins_str.strip(), available_space_str.strip())
if __name__ == '__main__':
main()