-
Notifications
You must be signed in to change notification settings - Fork 0
/
watchdog_ssh_login.py
140 lines (112 loc) · 4.7 KB
/
watchdog_ssh_login.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Script:
watchdog_ssh_login.py
Description:
Script that periodically check for successfull SSH logins in the actual system, determine if a
new login has occurred, and run the response subprograms (plugins) to act accordingly when a
login has been detected.
Examples of response plugins subprograms:
- Plugin that notify the detected SSH login to system owner via email, Telegram, Slack,
web service, webhook, etc.
- Plugin to execute or make a custom action in the system.
- Plugin to setup an specified system configuration to that loged user.
- Whatever that crosses your mind...
Author:
Jose Miguel Rios Rubio
Creation date:
25/03/2019
Last modified date:
28/03/2019
Version:
0.0.1
'''
####################################################################################################
### Imported modules ###
from os import path
from sys import exit
from time import sleep
from signal import signal, SIGTERM, SIGINT
from threading import Thread
from commons import printts, system_call, file_read_all_text
####################################################################################################
MAIN_SCRIPT_PATH = path.dirname(path.realpath(__file__))
####################################################################################################
### Plugins to use (comment/uncomment to disable/enable plugins) ###
PLUGINS = [
f"{MAIN_SCRIPT_PATH}/plugins/log2file_login/log2file_login.py",
f"{MAIN_SCRIPT_PATH}/plugins/gmail_notifier/gmail_notifier.py",
f"{MAIN_SCRIPT_PATH}/plugins/telegram_bot_notifier/tlg_bot_notifier.py"
]
####################################################################################################
### Withelist file ###
WHITELIST_F = f"{MAIN_SCRIPT_PATH}/whitelist.txt"
####################################################################################################
### Threading Function that call plugins ###
def run_plugin(plugin, login):
'''make a system call to execute the provided plugin.'''
print(system_call(f"python3 {plugin} \"{login}\""))
####################################################################################################
### Main and Finish Functions ###
def main():
'''Main Function.'''
printts("Script started.")
# Load actual SSH logins
ssh_logins = system_call("./ssh_check_logins.sh")
l_last_logins = ssh_logins.split("\n")
if len(l_last_logins) > 0:
print("Previous logins:")
for login in l_last_logins:
print(f" {login}")
print(" ")
while True:
try:
# Check if there is a new SSH login
new_logins = []
ssh_logins = system_call(f"{MAIN_SCRIPT_PATH}/ssh_check_logins.sh")
l_logins = ssh_logins.split("\n")
for login in l_logins:
if login not in l_last_logins:
new_logins.append(login)
l_last_logins = l_logins
# Launch plugins if any login was detected
for login in new_logins:
printts(f"New login detected: {login}")
# Check and ignore if it is in the withelist
withelist_text = file_read_all_text(WHITELIST_F)
withelist_text = withelist_text.replace("\r,", "")
withelist = withelist_text.split("\n")
login_ip = login[login.find(" - ")+3:login.rfind(":")]
if login_ip in withelist:
print(f"Ignoring known connection from {login_ip}")
continue
for plugin in PLUGINS:
# Launch a new thread to handle plugin execution
th = Thread(target=run_plugin, args=(plugin, login))
th.start()
# Wait 10s between checks
sleep(10)
except Exception as e:
printts(f"{e}")
finish(1)
finish(0)
####################################################################################################
### Script End Functions ###
def finish(return_code):
'''Finish function.'''
printts(f"\nScript stoped, exit({return_code}).\n")
exit(return_code)
def signal_handler(signal, frame):
'''Termination signals (SIGINT, SIGTERM) handler for program process.'''
finish(0)
# Signals attachment
signal(SIGTERM, signal_handler) # SIGTERM (kill pid) to signal_handler
signal(SIGINT, signal_handler) # SIGINT (Ctrl+C) to signal_handler
####################################################################################################
### Script Input - Main Script ###
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
finish(0)