检查ip:port是否在远程主机上打开

时间:2020-03-02 16:47:50

标签: python sockets paramiko ssh-tunnel telnetlib

我有一个服务器和ip:ports(外部地址)列表,我需要检查每个服务器是否可以连接到这些地址。

浏览文件并尝试打开sshtunnel并按如下所示进行连接

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()

尽管这样做,即使遥控器不正确,响应始终为0(即,袜子可以连接到本地绑定)-但是sshtunnelforwarder会抛出

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

如何使我的套接字命令检查remote_bind_address是否可用?

我尝试使用telnetlib,但遇到类似的问题

代码实际上是相同的,只是将套接字块替换为

tn=telnetlib.Telnet()
tn.open('localhost',10022)
tn.close()

我对这一切还比较陌生,因此仍需学习。如果有更好的方法来实现我需要做的事情,请告诉我。

谢谢

2 个答案:

答案 0 :(得分:2)

将属性skip_tunnel_checkup设置为False以启用对远程端可用性的检查(出于向后兼容性的考虑,默认情况下,该功能处于禁用状态):

tunnel.skip_tunnel_checkup = False

在启动隧道之前添加此内容,以检查远程端是否已启动并抛出可以处理的异常。

删除了我的套接字代码。

答案 1 :(得分:1)

我还没有尝试过,但是SSH隧道类的tunnel_is_up属性,根据文档:

描述是否已报告隧道另一侧(我们必须将其关闭)(跳过以关闭该隧道)

其内容示例(这是一本字典):

{('127.0.0.1', 55550): True,  # this tunnel is up
('127.0.0.1', 55551): False}  # this one isn't

因此您不需要自己进行显式连接。

注意:在设置隧道之前,您可能需要先将属性skip_tunnel_checkup设置为False(为了向后兼容,默认为True) ,否则tunnel_is_up可能始终会报告True

如果禁用skip_tunnel_checkup或本地绑定是UNIX套接字,则该值将始终为True

所以代码可能像这样:

tunnel=sshtunnel.SSHTunnelForwarder(
    # ...
)
tunnel.skip_tunnel_checkup = False
tunnel.start()

# tunnel.tunnel_is_up should be populated with actual tunnel status(es) now

在您发布的代码中,您正在建立一个隧道,然后仅打开该隧道的本地终结点套接字,无论该隧道处于什么状态,该套接字显然都是打开的,因此它总是可以成功连接。

另一种方法是实际尝试通过隧道建立SSH连接,但这是您在评论中提到的paramiko.SSHclient替代方案。