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

Posted

技术标签:

【中文标题】检查 ip:port 在远程主机上是不是打开【英文标题】:Checking ip:port is open on remote host检查 ip:port 在远程主机上是否打开 【发布时间】:2020-06-15 00:13:49 【问题描述】:

我有一个服务器列表和 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(即 sock 可以连接到本地绑定) - 但是 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()

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

谢谢

【问题讨论】:

我的替代方案是使用 paramiko.SSHclient 并使用 exec_command 进行远程登录,但我宁愿尝试使用 python 完成所有操作,而不是在服务器上调用命令。 【参考方案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 替代方案。

【讨论】:

@zkssyth 是否帮助您解决了问题?如果是,请接受我的回答。它将帮助其他人找到正确的答案,它还会奖励我一些声誉积分。 只是为了澄清隧道的另一端是不同的服务器。我试过隧道是正常的 - 即使我尝试了一个虚构的地址。 @zkssyth 我明白了,好的,谢谢你的信息!是的,我知道您正在尝试建立通往远程机器的隧道。【参考方案2】:

将属性 skip_tunnel_checkup 设置为 False 以启用远程端可用性检查(默认情况下禁用它以实现向后兼容性):

tunnel.skip_tunnel_checkup = False

在启动隧道之前添加它会检查远程端在启动时是否已启动并引发可以处理的异常。

删除了我的套接字代码。

【讨论】:

太好了,您设法解决了您的问题!我只是想问你,你能否添加一段代码来显示异常何时何地被抛出,好吗?从答案中不是很清楚。它可能对其他寻找类似解决方案的人有用。

以上是关于检查 ip:port 在远程主机上是不是打开的主要内容,如果未能解决你的问题,请参考以下文章

使用 ssh 检查远程主机上是不是存在文件

检查远程主机上一个端口的状态[关闭]

什么情况下可以用TELNET命令连接到远程电脑上?

如何检测(远程)主机上的某个端口是不是开启

如何检查端口是不是在带有批处理文件且没有第三方软件的远程服务器上打开? [关闭]

使用 python 中的 telnet 检查远程主机是不是已启动