Answers:
我通常设置这样的东西。假定中间主机将能够解析该名称。
Host *%homeproxy
ProxyCommand ssh user@proxyhost /bin/netcat -w 1 $(echo %h | cut -d%% -f1) 22
所以我会连接到喜欢ssh blah%homeproxy
。
%
角色没有什么特别的。您可以使用任何东西。使用百分比是因为它在主机名或用户名中无效。cut
带有ProxyCommand 的命令使用%
用作分隔符来提取主机名。
ssh targetH
,表示从home目标。如果要在本地网络中定位,只需ssh target
。不过,很高兴能在回答中更直接地说明这一点。
我使用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。
感谢@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
。
我通常会创建另一个类似这样的条目-
Host myVM
ProxyCommand ssh -W internal.ip:22 external-server
User ubuntu
Host myVM-np
User ubuntu
然后,根据您当前的代理环境,仅调用所需的那个即可。