Linux 检查SSH隧道是否已启动并正在运行
我有一个perl脚本,当有点失败时,它看起来像这样:Linux 检查SSH隧道是否已启动并正在运行,linux,perl,telnet,ssh-tunnel,Linux,Perl,Telnet,Ssh Tunnel,我有一个perl脚本,当有点失败时,它看起来像这样: my $randport = int(10000 + rand(1000)); # Random port as other scripts like this run at the same time my $localip = '192.168.100.' . ($port - 4000); # Don't ask... backwards compatibility system("ssh -NL $randpor
my $randport = int(10000 + rand(1000)); # Random port as other scripts like this run at the same time
my $localip = '192.168.100.' . ($port - 4000); # Don't ask... backwards compatibility
system("ssh -NL $randport:$localip:23 root\@$ip -o ConnectTimeout=60 -i somekey &"); # create the tunnel in the background
sleep 10; # Give the tunnel some time to come up
# Create the telnet object
my $telnet = new Net::Telnet(
Timeout => 10,
Host => 'localhost',
Port => $randport,
Telnetmode => 0,
Errmode => \&fail,
);
# SNIPPED... a bunch of parsing data from $telnet
问题是,目标$ip位于带宽不可预测的链路上,因此隧道可能会立即出现,可能需要一段时间,可能根本不会出现。因此,睡眠是必要的,给隧道一些时间起床和运行
所以问题是:我如何测试隧道是否正常运行?如果隧道直接到达,10秒是一个非常不受欢迎的延迟。理想情况下,我希望检查它是否启动,并在启动后继续创建telnet对象,最长为30秒
编辑:Ping没有帮助我移动,因为隧道的远端通常是向上的,但是有非常高的包丢失量
已解决:根据mikebabcock建议的提示推断,sleep 10
已替换为此块,其效果类似于符咒:
my $starttime = time();
while (1)
{
# Check for success
if (system("nc -dzw10 localhost $randport > /dev/null") == 0) { last }
# Check for timeout
if (time() > $starttime + 30) { &fail() }
# 250ms delay before recheck
select (undef, undef, undef, 0.25);
}
您可以将ping集成到ssh服务器中,如果工作正常,ssh隧道就启动了
# only a ping sample :-D
if ! ping -c 1 192.168.101.9
then
echo ":-("
else
echo ":-)"
fi
我认为fping可能比通常的ping更好,脚本更友好 fping-t 60000[您的服务器] 应在放弃前60秒尝试连接到服务器 差不多
if(fping -t 60000 [your server]) {
execute desired code;
} else {
execute this script again to rerun;;
}
即使编码不是真的,我想你也会明白这一点。在Linux系统上使用netcat——通常nc
:
nc -dvzw10 ${HOSTNAME} 23
对我来说很有效,回答如下:
Connection to ${HOSTNAME} 23 port [tcp/telnet] succeeded!
如果成功,它也会返回0,并对一个简单的连接感到满意,然后它就会离开
- -d表示不从键盘侧读取任何内容
- -v表示冗长(在脚本中关闭此选项)
- -z表示连接后断开连接
- -w10表示最多等待10秒,否则放弃
Net::Telnet
模块,您是否尝试过使用open
调用并测试成功?我不是Telnet专家,但如果是我,我可能会尝试这样做……如果没有一种简单的测试方法,我可能会这样做:如果尝试时间<30秒,则重试直到成功