-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtu++.py
executable file
·282 lines (254 loc) · 13.2 KB
/
tu++.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#! /usr/bin/python3
from colorama import Fore, Back, Style
from datetime import datetime
import sys
import os
import json
import signal
JsFilePath = "<JSPATH>/config.json"
def FnBanner():
print (Fore.BLUE + " ______ ______ __ ______ " + Fore.RESET)
print (Fore.CYAN + " / / / / /_ __/_ ______ ____ ___ / / __ _\ \ \ \ " + Fore.RESET)
print (Fore.GREEN + " / / / / / / / / / / __ \/ __ \/ _ \/ /_/ /___/ /\ \ \ \ " + Fore.RESET)
print (Fore.RED + " \ \ \ \ / / / /_/ / / / / / / / __/ /_ __/_ __/ / / / " + Fore.RESET)
print (Fore.YELLOW + " \_\_\_\/_/ \__,_/_/ /_/_/ /_/\___/_/ /_/ /_/ /_/_/_/ " + Fore.RESET)
print (Fore.MAGENTA + " " + Fore.RESET)
def FnPrintMenu():
print("")
print (Style.DIM + "press 'q' for quit" + Style.RESET_ALL)
print (Style.DIM + "press 'h' for help" + Style.RESET_ALL)
usrInput = input(Style.BRIGHT + "Command Mode ( " + Fore.BLUE + "Status [ " + Fore.YELLOW + "*U*" + Fore.BLUE + " ] Sart [ " + Fore.YELLOW + "S" + Fore.BLUE + " ] / Drop/Kill [ " + Fore.YELLOW + "D" + Fore.BLUE + " ]"+ Fore.RESET + " ) : " + Style.RESET_ALL)
try:
usrInput = usrInput[0]
except:
usrInput = "u"
if usrInput.lower() == "u":
FnCheckStatus()
elif usrInput.lower() == "s":
FnStartTunnle()
elif usrInput.lower() == "d":
FnKillProcess()
elif usrInput.lower() == "q":
sys.exit()
elif usrInput.lower() == "h":
print("")
Fnhelp()
FnPrintMenu()
else:
os.system('clear')
print ("-----------------------")
print (Style.BRIGHT + Fore.BLACK + Back.WHITE + "(" + usrInput + ") is Not Valid Code ")
print (Style.RESET_ALL + "-----------------------")
FnPrintMenu()
def FnLoadJsonFile():
try:
JsFile = open(JsFilePath, "r")
except:
print(Fore.RED + "Json File Not Found " + Fore.RESET)
sys.exit()
js = JsFile.read()
js = js.replace('\n', '')
global JsonConfig
JsonConfig = json.loads(js)
def FnStartTunnle():
# ListOfTunnel = JsonConfig["tunnel"]
try:
ListOfTunnel = JsonConfig["tunnel"]
a = len(ListOfTunnel)
if a > 0:
for x in ListOfTunnel:
TName = x["role_name"]
Tlocal_port = x["local_port"]
TDestinationPort = x["destination_port"]
Ttype = x["type"]
TSSHIp = x["ssh_ip"]
TSSHPort = x["ssh_port"]
TSSHUser = x["ssh_user"]
if Ttype == "local":
print (Style.BRIGHT + Fore.WHITE + "Tunneling Port [ " + Fore.RED + TDestinationPort + Fore.WHITE + " ] Server [ " + Fore.RED + TSSHIp + Fore.WHITE + " ] to [ " + Fore.RED + Tlocal_port + Fore.WHITE + " ] server Local for [ " + Fore.BLUE + TName + Fore.WHITE + " ]" + Style.RESET_ALL )
Command = "sudo ssh -NTC -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -f -N -p {SSHPort} {SSHUser}@{SSHIp} -L 0.0.0.0:{local_port}:0.0.0.0:{DestinationPort}"
Command = Command.format(SSHPort = TSSHPort, SSHUser = TSSHUser, SSHIp = TSSHIp, local_port = Tlocal_port, DestinationPort = TDestinationPort )
os.system(Command)
Logit("start-local")
elif Ttype == "remote":
print (Style.BRIGHT + Fore.WHITE + "Remote Tunneling port [ " + Fore.RED + Tlocal_port + Fore.WHITE + " ] local server to server [ " + Fore.RED + TSSHIp + Fore.WHITE + " ] port [ " + Fore.RED + TDestinationPort + Fore.WHITE + " ] for [ " + Fore.BLUE + TName + " ] " + Style.RESET_ALL)
Command = "ssh -R 0.0.0.0:{DestinationPort}:127.0.0.1:{local_port} -N -f -p {SSHPort} {SSHUser}@{SSHIp}"
Command = Command.format(DestinationPort = TDestinationPort, local_port = Tlocal_port, SSHPort = TSSHPort, SSHUser = TSSHUser, SSHIp = TSSHIp)
os.system(Command)
Logit("start-remote")
elif len(ListOfTunnel) == 0:
print(Style.BRIGHT + Fore.YELLOW + "Tunnel Key Empty")
else:
print(Style.BRIGHT + Fore.RED + "Error for tunnel key from json file")
except KeyError:
print(Style.BRIGHT + Fore.YELLOW + "Tunnel Key Not Found in jsonfile")
except:
print(Style.BRIGHT + Fore.YELLOW + "Unknown error in Load Json file")
if VarParameterMode is False:
FnPrintMenu()
def FnCheckStatus():
try:
ListOfTunnel = JsonConfig["tunnel"]
a = len(ListOfTunnel)
if a > 0:
TiTunnelType = Style.BRIGHT + "Tunnel type" + Style.RESET_ALL
TiTitle = Style.BRIGHT + "Title" + Style.RESET_ALL
TiIP = Style.BRIGHT + 'IP(Host)' + Style.RESET_ALL
TiLocalport = Style.BRIGHT + 'Local port' + Style.RESET_ALL
TiDestPort = Style.BRIGHT + 'Destination Port' + Style.RESET_ALL
TiStatus = Style.BRIGHT + 'Status' + Style.RESET_ALL
print ("")
print ("{:<20} {:<30} {:<20} {:<20} {:<30} {:<15}".format(TiTunnelType, TiTitle, TiIP, TiLocalport, TiDestPort, TiStatus))
for x in ListOfTunnel:
TName = x["role_name"]
Tlocal_port = x["local_port"]
TDestinationPort = x["destination_port"]
Ttype = x["type"]
SSHIp = x["ssh_ip"]
if Ttype == "local":
#str = "0.0.0.0:{local_port}:0.0.0.0:{DestinationPort}"
str = "{local_port}:0.0.0.0:{DestinationPort}"
str = str.format(local_port = Tlocal_port, DestinationPort = TDestinationPort)
TaTunnelType = Style.BRIGHT + "Local" + Style.RESET_ALL
elif Ttype == "remote":
str = "0.0.0.0:{DestinationPort}:127.0.0.1:{local_port}"
str = str.format(local_port = Tlocal_port, DestinationPort = TDestinationPort)
TaTunnelType = Style.BRIGHT + "Remote" + Style.RESET_ALL
pids = os.popen("ps ax | grep " + str + " | grep -v grep")
if pids.read() == "":
TaStatus = Style.NORMAL + Fore.WHITE + Back.RED + "Not active" + Style.RESET_ALL
else:
TaStatus = Style.NORMAL + Fore.WHITE + Back.GREEN + "Active" + Style.RESET_ALL
TaTitle = Style.BRIGHT + TName + Style.RESET_ALL
TaIP = Style.BRIGHT + SSHIp + Style.RESET_ALL
TaLocalport = Style.BRIGHT + Tlocal_port + Style.RESET_ALL
TaDestPort = Style.BRIGHT + TDestinationPort + Style.RESET_ALL
print ("{:<20} {:<30} {:<20} {:<20} {:<30} {:<15}".format(TaTunnelType, TaTitle, TaIP, TaLocalport, TaDestPort, TaStatus))
except KeyError:
print(Style.BRIGHT + Fore.YELLOW + "Tunnel Key Not Found in jsonfile")
except:
print(Style.BRIGHT + Fore.YELLOW + "Unknown error in Load Json file")
if VarParameterMode is False:
FnPrintMenu()
def FnKillProcess():
ActiveSSHTunnel = False
ListOfTunnel = JsonConfig["tunnel"]
a = len(ListOfTunnel)
if a > 0:
TiTunnelType = Style.BRIGHT + "Tunnel type" + Style.RESET_ALL
TiTitle = Style.BRIGHT + "Title" + Style.RESET_ALL
TiIP = Style.BRIGHT + 'IP(Host)' + Style.RESET_ALL
TiLocalport = Style.BRIGHT + 'Local port' + Style.RESET_ALL
TiDestPort = Style.BRIGHT + 'Destination Port' + Style.RESET_ALL
TiStatus = Style.BRIGHT + 'Action' + Style.RESET_ALL
print ("")
print ("{:<20} {:<30} {:<20} {:<20} {:<30} {:<15}".format(TiTunnelType, TiTitle, TiIP, TiLocalport, TiDestPort, TiStatus))
for x in ListOfTunnel:
TName = x["role_name"]
Tlocal_port = x["local_port"]
TDestinationPort = x["destination_port"]
Ttype = x["type"]
SSHIp = x["ssh_ip"]
if Ttype == "local":
#str = "0.0.0.0:{local_port}:0.0.0.0:{DestinationPort}"
str = "{local_port}:0.0.0.0:{DestinationPort}"
str = str.format(local_port = Tlocal_port, DestinationPort = TDestinationPort)
TaTunnelType = Style.BRIGHT + "Local" + Style.RESET_ALL
elif Ttype == "remote":
str = "0.0.0.0:{DestinationPort}:127.0.0.1:{local_port}"
str = str.format(local_port = Tlocal_port, DestinationPort = TDestinationPort)
TaTunnelType = Style.BRIGHT + "Remote" + Style.RESET_ALL
pids = os.popen("ps ax | grep " + str + " | grep -v grep")
if pids.read() == "":
pass
else:
TaStatus = Style.NORMAL + Fore.WHITE + Back.RED + "** KILLED **" + Style.RESET_ALL
TaTitle = Style.BRIGHT + TName + Style.RESET_ALL
TaIP = Style.BRIGHT + SSHIp + Style.RESET_ALL
TaLocalport = Style.BRIGHT + Tlocal_port + Style.RESET_ALL
TaDestPort = Style.BRIGHT + TDestinationPort + Style.RESET_ALL
print ("{:<20} {:<30} {:<20} {:<20} {:<30} {:<15}".format(TaTunnelType, TaTitle, TaIP, TaLocalport, TaDestPort, TaStatus))
ActiveSSHTunnel = True
try:
for line in os.popen("ps ax | grep " + str + " | grep -v grep"):
fields = line.split()
pid = fields[0]
os.kill(int(pid), signal.SIGKILL)
except:
pass
Logit("drop")
if ActiveSSHTunnel is True:
pass
else:
print ("")
print (Style.BRIGHT + Fore.YELLOW +"--------------------" + Style.RESET_ALL)
print (Style.BRIGHT + Fore.RED +"Active SSH Tunnel Not Found " + Style.RESET_ALL)
print (Style.BRIGHT + Fore.YELLOW +"--------------------" + Style.RESET_ALL)
Logit("drop-fail")
if VarParameterMode is False:
FnPrintMenu()
def Logit(type):
if type == "drop":
FnLogit("KILL", "drop All Active SSH Tunnel","Parameter mode is {}".format(VarParameterMode),"successfully" )
elif type == "drop-fail":
FnLogit("KILL", "drop All Active SSH Tunnel","Parameter mode is {}".format(VarParameterMode),"Fail" )
elif type == "start-local":
FnLogit("START", "Start Local SSH Tunnel","Parameter mode is {}".format(VarParameterMode),"--" )
elif type == "start-remote":
FnLogit("START", "Start Remote SSH Tunnel","Parameter mode is {}".format(VarParameterMode),"--" )
elif type == "restart":
FnLogit("RESTART", "ReStart SSH Tunnel","Parameter mode is {}".format(VarParameterMode),"---" )
def FnLogit(VactionName,Massege,Mode,Status):
LogFileName = JsonConfig["logfile"]
try:
f = open(LogFileName, "a")
try:
now = datetime.now()
now = now.strftime("%d/%m/%Y %H:%M:%S")
logs = "\n[ {vDate} ] - [ {vAction} ] - [ {vMode}] -[ {vStatus} ] - [ {vMassege} ]"
f.write(logs.format(vDate = now, vAction = VactionName , vMassege = Massege, vMode = Mode, vStatus = Status))
except:
print("Something went wrong when writing to the log file [ " + Fore.RED + LogFileName + Fore.RESET + " ]")
finally:
f.close()
except:
print("Something went wrong when writing to the log file [ " + Style.BRIGHT + Fore.RED + LogFileName + Style.RESET_ALL + " ]")
def Fnhelp():
InFo = """ This program can manage SSH tunnels between two Linux servers.
The information of the tunnels read from a json file.
This program can be run in UI and parameter mode (for scheduled execution)."""
print(Style.BRIGHT + Fore.WHITE + InFo + Style.RESET_ALL)
print("")
print(Style.BRIGHT + Fore.WHITE + "Run without parameter [ " + Fore.BLUE + "tunnel++" + Fore.WHITE + " ] for run in UI Mode" + Style.RESET_ALL)
print(Style.BRIGHT + Fore.WHITE + "Run with parameter [ " + Fore.BLUE + "tunnel++ -s" + Fore.WHITE + " ] for start All tunnel/s" + Style.RESET_ALL)
print(Style.BRIGHT + Fore.WHITE + "Run with parameter [ " + Fore.BLUE + "tunnel++ -u" + Fore.WHITE + " ] for Chek Status of tunnel/s" + Style.RESET_ALL)
print(Style.BRIGHT + Fore.WHITE + "Run with parameter [ " + Fore.BLUE + "tunnel++ -d" + Fore.WHITE + " ] for Drop/kill all tunnel/s" + Style.RESET_ALL)
print(Style.BRIGHT + Fore.WHITE + "Run with parameter [ " + Fore.BLUE + "tunnel++ -r" + Fore.WHITE + " ] for Restart ( Drop & Start) all tunnel/s" + Style.RESET_ALL)
if len(sys.argv) == 1:
VarParameterMode = False
FnLoadJsonFile()
FnBanner()
FnPrintMenu()
else:
VarParameterMode = True
FnLoadJsonFile()
for i in sys.argv:
if i.lower() == "-d":
FnBanner()
FnKillProcess()
elif i.lower() == "-u":
FnBanner()
FnCheckStatus()
elif i.lower() == "-s":
FnBanner()
FnStartTunnle()
elif i.lower() == "-r":
Logit("restart")
FnBanner()
FnKillProcess()
FnStartTunnle()
elif i.lower() == "-h":
FnBanner()
Fnhelp()
else:
print(Style.BRIGHT + Fore.GREEN + "-h" + Fore.WHITE + " for Help")