Reputation: 31
I have a list of servers and ip:ports (external addressses) and i need to check if each server can connect to those addresses.
Looping through the file and trying to open an sshtunnel and doing connect as below
tunnel=sshtunnel.SSHTunnelForwarder(
ssh_host=host,
ssh_port=22,
ssh_username=ssh_username,
ssh_pkey=privkey,
remote_bind_address=(addr_ip, int(addr_port)),
local_bind_address=('0.0.0.0', 10022)
#,logger=sshtunnel.create_logger(loglevel=10)
)
tunnel.start()
# use socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
res = s.connect(('localhost', 10022))
print(res)
#s.connect((addr_ip, int(addr_port)))
s.close()
except socket.error as err:
print('socket err:')
print(err)
finally:
s.close()
time.sleep(2)
tunnel.stop()
When i do this though, the response is always 0 (i.e. the sock can connect to the local bind) even if the remote is incorrect - however sshtunnelforwarder throws
ERROR | Secsh channel 0 open FAILED: Network is unreachable: Connect failed
ERROR | Could not establish connection from ('127.0.0.1', 10022) to remote side of the tunnel
How do I make my socket command check if the remote_bind_address is available?
I tried to do use telnetlib, but get a similar issue
the code is effectively the same with the socket block replaced with
tn=telnetlib.Telnet()
tn.open('localhost',10022)
tn.close()
Im relatively new to all this, so still learning. If there is a better way to achieve what i need to do please let me know.
Thanks
Upvotes: 0
Views: 1102
Reputation: 25441
I haven't tried that, but there's the tunnel_is_up
attribute of the SSH tunnel class, which according to the documentation:
Describe whether or not the other side of the tunnel was reported to be up (and we must close it) or not (skip shutting down that tunnel)
Example of its content (it's a dictionary):
{('127.0.0.1', 55550): True, # this tunnel is up
('127.0.0.1', 55551): False} # this one isn't
So you shouldn't need to make an explicit connection yourself.
Note: you may need to set the attribute skip_tunnel_checkup
to False
(which is True
by default for backwards compatibility) first before setting up the tunnel, otherwise tunnel_is_up
may always report True
:
When
skip_tunnel_checkup
is disabled or the local bind is a UNIX socket, the value will always beTrue
So the code may look like:
tunnel=sshtunnel.SSHTunnelForwarder(
# ...
)
tunnel.skip_tunnel_checkup = False
tunnel.start()
# tunnel.tunnel_is_up should be populated with actual tunnel status(es) now
In the code you posted, you're setting up a tunnel and then just opening a socket to the local endpoint of the tunnel, which is apparently open no matter what state the tunnel is in, so it always connects successfully.
Another approach would be to actually try to establish an SSH connection through the tunnel, but that's the paramiko.SSHclient
alternative you're mentioning in a comment I guess.
Upvotes: 1
Reputation: 31
Set the attribute skip_tunnel_checkup
to False
to enable checking of the remote side availability (it's disabled by default for backwards compatibility):
tunnel.skip_tunnel_checkup = False
Adding this before starting the tunnel checks the remote side is up on start and throws an exception which can be handled.
Removed my socket code.
Upvotes: 3