如何检查 SSH 连接是否打开?

如何检查 SSH 连接是否打开?

我正在尝试连接到public.sigmadesigns.com网站。实际上,我已通过向该服务器发送我的 RSA 公钥获得了该服务器的授权。但现在当我尝试执行 时repo,我得到:

Getting manifest ...
   from [email protected]:mipsandroid/platform/manifest.git
ssh: connect to host public.mipsandroid.com port 22: Connection refused
ssh: connect to host public.mipsandroid.com port 22: Connection refused
fatal: The remote end hung up unexpectedly
fatal: cannot obtain manifest [email protected]:mipsandroid/platform/manifest.git

由于我在公司代理网络内,我想知道我对此 IP 的访问是否开放。我该如何检查?

答案1

我的 ~/.bashrc 和 ~/.zshrc 中的一些函数的简化版本(完全兼容 POSIX,可用于您的 shell 脚本):

# true if we have the given command(s)
we_have() { type "$@" >/dev/null 2>&1; }

# Usage: probe SERVER PORT|SERVICE
# returns true when SERVER has PORT opened (and responds within one second)
if we_have nc
  then probe() { nc -zw1 "$@" >/dev/null 2>&1; }
  else probe() { echo X |telnet -e X "$@" >/dev/null 2>&1; }
fi

# Usage: poke SERVER [PORT|SERVICE]
# As probe.  Also: PORT defaults to 80 (http) and reports the result
poke() {
  local RETVAL STATUS
  probe "$1" "${2:-80}"
  RETVAL=$?
  if [ $RETVAL != 0 ]; then
    STATUS=" not"
  fi
  echo "could$STATUS connect to port ${2:-80} on host '$1'"
  return $RETVAL
}

它支持端口号和任何由 ​​索引的服务名称/etc/services。(请小心测试;如果您的测试由于错误的服务名称而失败,您将不会知道。)

一些示例测试:

$ poke localhost ssh
could connect to port ssh on host 'localhost'
$ poke localhost 12345
could not connect to port 12345 on host 'localhost'

probe如果您只想使用返回值编写脚本,请使用

if probe localhost ssh; then
  echo something contingent on hosting ssh goes here
fi

如果您nmap安装了版本 5+,则可以使用ncat --send-only --recv-only -w 334ms $1 $2而不是nc命令。这会更快地失败(我已确定为 334 毫秒。nc 仅允许精确到秒的分辨率,因此您必须等待整整一秒)。


请注意,这确实不是验证正在托管的内容,仅验证端口是否打开。99% 的情况下,这已经足够了。如果您需要更多,请尝试以下操作:

nmap -sV -p ssh localhost |grep -qi 'open.*ssh.*ssh[^?]'

这将告诉我们nmap扫描服务器 localhost 上的 ssh 端口 (22) 并确定服务/版本信息。在我的系统上,如果没有 grep,它会报告:

Starting Nmap 6.40 ( http://nmap.org ) at 2014-02-14 17:01 PST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000048s latency).
Other addresses for localhost (not scanned): 127.0.0.1
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.4p1 Debian 2 (protocol 2.0)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.24 seconds

因此,grep 命令会越过 SSH 的第一个实例(仅指示 /etc/services 中的映射)查看托管服务器和版本信息,这些信息必须与“ssh”(不区分大小写)匹配。该-q标志仅抑制输出(因此可以替换probe)。如果 nmap 无法确定服务是什么,它会说ssh?,因此 grep 正则表达式会避免匹配它。

让我们将它们结合起来使其快速运行,同时仍能验证 SSH 是否真正得到服务:

# Usage: vet_ssh SERVER [PORT|SERVICE]
# True when SERVER has PORT (default=22) both opened and serving SSH
vet_ssh() {
  probe $1 ${2:-22} && nmap -sV -p ${2:-22} $1 |grep -qiE 'open.....*ssh[^?]'
}

现在,您可以在函数中使用vet_ssh代替。这几乎与我原来的函数一样快:当端口未打开时,速度相同;当端口打开并提供 SSH 服务时,速度会稍慢;当端口打开并提供 nmap 无法快速识别(或根本无法识别)的服务时,速度会慢得多。此处的 grep 正则表达式略有不同,以适应备用端口。probepokepoke


如果我完全误解了你的问题...如果你想知道你是否已经连接到这个服务器(而不是你是否可以),使用netstat方式如下:

# Usage: am_i_sshed_to SERVER [PORT|SERVICE]
# True when you have an established connection to SERVER on PORT (default=22)
am_i_sshed_to() {
  local IP_QUERY=`host "$1" |awk -v port="${2:-22}" '
    $2 != "mail" { printf "-e %s:%s ", $NF, port }
  '`
  netstat -tn |grep -w $IP_QUERY |grep -wq ESTABLISHED
}

然后您可以以与或am_i_sshed_to相同的方式使用。probevet_ssh

(解释: netstat查找每个地址需要很长时间。我们只需要对要检查的一台服务器进行一次查找,因此我们将其缓存在第一行。该awk命令表示任何不讨论邮件传递的行都必须$NF以 IP 结尾 ( )。将其作为我们即将进行的 netstat 调用的 grep 查询,因此1.2.3.4变为例如-e 1.2.3.4:22,我们可以有多个 IP(在达到命令行大小限制之前最多几百个)。然后,我们运行 netstat,只查看 TCP 连接,而不将任何内容映射到名称。我们针对缓存的查询 grep 单词(不匹配“11.2.3.4:22”或“1.2.3.4:2234”)(请注意故意不使用引号,我们不需要它们,它们会改变参数结构!)然后确保连接仍然建立。同样,grep -q没有输出,所以这是一个替代品,probe但不是poke

答案2

您可以通过 ssh 访问 sdf.org 进行测试。我刚刚这样做了,它要求进行身份验证。如果没有,您将不得不要求您的 IT 部门打开端口 22。

相关内容