〜/ .ssh / config中的条件ProxyCommand?


14

我为我~/.ssh/config配置了各种主机,这些主机可以在公司VPN上或通过SSH代理服务器访问。

此刻我只有

Host internal-server
    ProxyCommand ssh -W internal.ip:22 external-server

但是,如果我在内部网络中,则可以直接访问内部ip,因此通过外部服务器进行代理只会增加连接延迟。

如果无法访问内部IP,是否可以临时代理,否则直接连接?

Answers:


8

我通常设置这样的东西。假定中间主机将能够解析该名称。

Host *%homeproxy
    ProxyCommand ssh user@proxyhost /bin/netcat -w 1 $(echo %h | cut -d%% -f1) 22

所以我会连接到喜欢ssh blah%homeproxy


我的谷歌福使我失败。您能再解释一下吗?我以前从未见过这种*%语法。
fukawi2

3
%角色没有什么特别的。您可以使用任何东西。使用百分比是因为它在主机名或用户名中无效。cut带有ProxyCommand 的命令使用%用作分隔符来提取主机名。
Zoredache

1
这很好,但这确实意味着我必须拼写完整的主机名,而不是ssh别名。
alt 2013年

@mobiusnz实际上,这只是意味着您需要为每种不同连接方式使用不同的名称。以我为例,例如,如果我在家,则使用ssh targetH,表示从home目标。如果要在本地网络中定位,只需ssh target。不过,很高兴能在回答中更直接地说明这一点。
鲁本斯2015年

4

我使用Match的另一种方法。就我而言,我想使用本地代理(如果正在运行),或者不使用本地代理。以下指令可以很好地完成此任务:

Match Exec "nc -z 127.0.0.1 1086"
    ProxyCommand nc -X 5 -x 127.0.0.1:1086 %h %p

它匹配每次ssh尝试,并执行快速检查nc以查看我的代理是否已启动并在1086上运行(在这种情况下,nc退出时没有错误)。如果发生这种情况,它将设置ProxyCommand。


2

十年前,我为这种情况编写了一个代理命令。在您的使用情况下,可以这样使用我的proxy命令:

Host internal-server
    ProxyCommand ssh-multipath-proxy %h:%p -- ssh -W %h:%p external-server

请注意以下几点:我有点尴尬地承认,它不处理IPv6,并且每个主机名只能尝试一个IP地址。同样,在发送服务器标语之前,它不会将客户端标语传输到服务器。但这不太可能引起问题。


2

感谢@till的Answer,这启发了我很多。

我发现您可以通过强制重定向连接ProxyCommand nc dst dst-port

例如,实际上,B.com如果您使用

ssh A.com -o ProxyCommand="nc B.com 22"

UserKnownHostsFile仍会记录为A.com

因此,您可以将域“自动”添加到您的 ssh_config

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(timeout 0.1 nc -z %h %p) && nc %h %p || ssh -W %h:%p external-server'

我替换nc -w 1 %h %p(timeout 0.1 nc -z %h %p) && nc %h %p,如果您可以不到100ms到达内部服务器,它将更快。

或者,您可以将其替换为ping,但是如果您使用基于TCP的代理(如)proxychains,或者服务器不允许ICMP回显,则可能表示错误的信息。

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(ping %h &>/dev/null) && nc %h %p || ssh -W %h:%p external-server'

您可以(timeout 0.1 nc -z %h %p)用任何可以检测您是否在内部服务器中的东西代替。

如果您有多个候选IP,甚至可以使用以下选项:

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c 'f(){(timeout 0.1 ping -c 1 $1 &>/dev/null) && nc $1 %p;}; f 1.1.1.1 || f 2.2.2.2 || f 3.3.3.3'

它会尝试连接1.1.1.1,如果失败尝试连接2.2.2.2,然后3.3.3.3


0

如果您不在防火墙后面,并且防火墙不拒绝,则可以自动进行一些额外的1秒延迟,从而更加自动。

Host proxyhost.example.com
ProxyCommand none

Host *.example.com
ProxyCommand sh -c "nc -w 1 %h %p || ssh -W  %h:%p proxyhost.example.com"

0

我通常会创建另一个类似这样的条目-

Host myVM
    ProxyCommand ssh -W internal.ip:22 external-server
    User ubuntu

Host myVM-np
    User ubuntu

然后,根据您当前的代理环境,仅调用所需的那个即可。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.