我已~/.ssh/config
配置了各种主机,可通过公司 VPN 或 SSH 代理服务器访问。
目前我只有
Host internal-server
ProxyCommand ssh -W internal.ip:22 external-server
但是如果我在内部网络中,我可以直接访问内部 IP,因此通过外部服务器代理只会增加连接延迟。
如果内部 IP 无法访问,是否有办法可以临时代理,否则直接连接?
答案1
我通常会设置类似的东西。它假设中间主机能够解析名称。
Host *%homeproxy
ProxyCommand ssh user@proxyhost /bin/netcat -w 1 $(echo %h | cut -d%% -f1) 22
所以我会连接到喜欢ssh blah%homeproxy
。
答案2
我使用 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。
答案3
感谢@till 的回答,给了我很大的启发。
我发现您可以使用 强制重定向您的连接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
,如果您能在 100 毫秒之内到达内部服务器,速度会更快。
或者您可以用 替换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
。
答案4
只需额外增加 0.1 秒的延迟,这个工作就会更加自动化:
Host proxyhost.example.com
ProxyCommand none
Host *.example.com
ProxyCommand sh -c "socat 2>/dev/null - tcp4:%h:%p,connect-timeout=0.1 || exec ssh -W %h:%p proxyhost.example.com"