Prepare handling of raw ssh tunnels
This commit is contained in:
parent
71c89f1fe7
commit
3e02a366ff
1 changed files with 38 additions and 21 deletions
49
ereshkigal.py
Normal file → Executable file
49
ereshkigal.py
Normal file → Executable file
|
|
@ -34,7 +34,8 @@ from operator import itemgetter
|
||||||
class SSHTunnel(dict):
|
class SSHTunnel(dict):
|
||||||
"""A dictionary that stores an SSH connection related to a tunnel"""
|
"""A dictionary that stores an SSH connection related to a tunnel"""
|
||||||
|
|
||||||
def __init__(self, local_address = '1.1.1.1', local_port = 0, foreign_address = '1.1.1.1', foreign_port = 0, target_host = "Unknown", status = 'UNKNOWN', ssh_pid = 0, autossh_pid = 0 ):
|
def __init__(self, local_address = '1.1.1.1', local_port = 0, foreign_address = '1.1.1.1', foreign_port = 0,
|
||||||
|
target_host = "Unknown", status = 'UNKNOWN', ssh_pid = 0 ):
|
||||||
|
|
||||||
# informations available with netstat
|
# informations available with netstat
|
||||||
self['local_address'] = local_address
|
self['local_address'] = local_address
|
||||||
|
|
@ -44,12 +45,25 @@ class SSHTunnel(dict):
|
||||||
self['target_host'] = target_host
|
self['target_host'] = target_host
|
||||||
self['status'] = status
|
self['status'] = status
|
||||||
self['ssh_pid'] = ssh_pid
|
self['ssh_pid'] = ssh_pid
|
||||||
self['autossh_pid'] = autossh_pid
|
|
||||||
|
|
||||||
# would be nice to have an estimation of the connections latency
|
# FIXME would be nice to have an estimation of the connections latency
|
||||||
#self.latency = 0
|
#self.latency = 0
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
# do not print all the informations by default
|
||||||
|
return "%i\t%i\t%s\t%s" % (
|
||||||
|
self['local_port'],
|
||||||
|
self['target_host'],
|
||||||
|
self['status']
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AutoSSHTunnel(SSHTunnel):
|
||||||
|
def __init__(self, autossh_pid = 0, *args ):
|
||||||
|
self['autossh_pid'] = autossh_pid
|
||||||
|
super().__init__(*args)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
# do not print all the informations by default
|
# do not print all the informations by default
|
||||||
return "%i\t%i\t%s\t%s" % (
|
return "%i\t%i\t%s\t%s" % (
|
||||||
|
|
@ -59,7 +73,6 @@ class SSHTunnel(dict):
|
||||||
self['status']
|
self['status']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class AutoSSHprocess(dict):
|
class AutoSSHprocess(dict):
|
||||||
"""A dictionary that stores an autossh process"""
|
"""A dictionary that stores an autossh process"""
|
||||||
|
|
||||||
|
|
@ -89,6 +102,7 @@ class AutoSSHprocess(dict):
|
||||||
return repr
|
return repr
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME use regexps, for gods sake
|
||||||
class AutoSSHTunnelMonitor(list):
|
class AutoSSHTunnelMonitor(list):
|
||||||
"""List of existing autossh processes and ssh connections"""
|
"""List of existing autossh processes and ssh connections"""
|
||||||
|
|
||||||
|
|
@ -114,15 +128,15 @@ class AutoSSHTunnelMonitor(list):
|
||||||
logging.debug("Autossh processes: %s" % autosshs)
|
logging.debug("Autossh processes: %s" % autosshs)
|
||||||
|
|
||||||
# ssh connections related to a tunnel
|
# ssh connections related to a tunnel
|
||||||
connections = self.get_connections()
|
autocon,rawcon = self.get_connections()
|
||||||
if connections:
|
if autocon:
|
||||||
logging.debug("SSH connections related to a tunnel: %s" % connections)
|
logging.debug("SSH connections related to a tunnel: %s" % autocon)
|
||||||
|
|
||||||
# Bind existing connections to autossh processes.
|
# Bind existing connections to autossh processes.
|
||||||
# Thus the instance is a list of AutoSSHinstance instances,
|
# Thus the instance is a list of AutoSSHinstance instances,
|
||||||
# each of those instances having a 'tunnels' key,
|
# each of those instances having a 'tunnels' key,
|
||||||
# hosting the corresponding list of tunnel connections.
|
# hosting the corresponding list of tunnel connections.
|
||||||
self[:] = self.bind_tunnels(autosshs, connections)
|
self[:] = self.bind_tunnels(autosshs, autocon)
|
||||||
|
|
||||||
# sort on a given key
|
# sort on a given key
|
||||||
self.sort_on( 'local_port')
|
self.sort_on( 'local_port')
|
||||||
|
|
@ -229,7 +243,8 @@ class AutoSSHTunnelMonitor(list):
|
||||||
|
|
||||||
cons = [i.split() for i in status_list if b'ssh' in i]
|
cons = [i.split() for i in status_list if b'ssh' in i]
|
||||||
|
|
||||||
tunnels = []
|
autotunnels = []
|
||||||
|
rawtunnels = []
|
||||||
|
|
||||||
for con in cons:
|
for con in cons:
|
||||||
logging.debug("Candidate connection: %s" % con)
|
logging.debug("Candidate connection: %s" % con)
|
||||||
|
|
@ -286,20 +301,21 @@ class AutoSSHTunnelMonitor(list):
|
||||||
|
|
||||||
# exclude the port
|
# exclude the port
|
||||||
content = f.readlines()
|
content = f.readlines()
|
||||||
|
f.close()
|
||||||
logging.debug("Cmd: %s" % content[0])
|
logging.debug("Cmd: %s" % content[0])
|
||||||
if not 'autossh' in content[0]:
|
if not 'autossh' in content[0]:
|
||||||
logging.warning("Tunnel not managed by autossh, ignore.")
|
logging.warning("Tunnel not managed by autossh, ignore.")
|
||||||
# FIXME display those hanging tunnels in some way.
|
# FIXME display those hanging tunnels in some way.
|
||||||
continue
|
rawtunnels.append( SSHTunnel( local_addr, local_port, foreign_addr, foreign_port, autohost, status, sshpid ) )
|
||||||
|
else:
|
||||||
|
|
||||||
autohost = content[0].split(':')[1]
|
autohost = content[0].split(':')[1]
|
||||||
f.close()
|
|
||||||
logging.debug("Parsed cmd without port: %s" % autohost)
|
logging.debug("Parsed cmd without port: %s" % autohost)
|
||||||
|
|
||||||
# instanciation
|
# instanciation
|
||||||
tunnels.append( SSHTunnel( local_addr, local_port, foreign_addr, foreign_port, autohost, status, sshpid, ppid ) )
|
autotunnels.append( AutoSSHTunnel( ppid, local_addr, local_port, foreign_addr, foreign_port, autohost, status, sshpid ) )
|
||||||
|
|
||||||
return tunnels
|
return autotunnels,rawtunnels
|
||||||
|
|
||||||
|
|
||||||
def bind_tunnels(self, autosshs, tunnels):
|
def bind_tunnels(self, autosshs, tunnels):
|
||||||
|
|
@ -340,8 +356,9 @@ class monitorCurses:
|
||||||
# switch to show only autoss processes (False) or ssh connections also (True)
|
# switch to show only autoss processes (False) or ssh connections also (True)
|
||||||
self.show_tunnels = False
|
self.show_tunnels = False
|
||||||
|
|
||||||
self.update_delay = 1 # seconds of delay between two updates
|
# FIXME pass as parameters+options
|
||||||
self.ui_delay = 0.05 # seconds between two loops
|
self.update_delay = 1 # seconds of delay between two data updates
|
||||||
|
self.ui_delay = 0.05 # seconds between two screen update
|
||||||
|
|
||||||
# colors
|
# colors
|
||||||
self.colors_autossh = {'pid':0, 'local_port':3, 'via_host':2, 'target_host':2, 'foreign_port':3, 'tunnels_nb':4, 'tunnels_nb_none':1}
|
self.colors_autossh = {'pid':0, 'local_port':3, 'via_host':2, 'target_host':2, 'foreign_port':3, 'tunnels_nb':4, 'tunnels_nb_none':1}
|
||||||
|
|
@ -728,7 +745,7 @@ if __name__ == "__main__":
|
||||||
# do not call update() but only get connections
|
# do not call update() but only get connections
|
||||||
logging.debug("UID: %i." % os.geteuid())
|
logging.debug("UID: %i." % os.geteuid())
|
||||||
if os.geteuid() == 0:
|
if os.geteuid() == 0:
|
||||||
con = tm.get_connections()
|
con,raw = tm.get_connections()
|
||||||
for c in con:
|
for c in con:
|
||||||
print(con)
|
print(con)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue