~/.ssh/config 中的条件代理命令?

~/.ssh/config 中的条件代理命令?

我已~/.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"

相关内容