如何根据本地子网自动切换ssh配置?
当我在某个网络(子网是10.10.11.x)上时,我需要跳转通过一个中间主机到达我的目标,因为目标端口我不能更改,并且可以退出受限网络的端口有限。我成功地使用了如下所示的ssh配置:如何根据本地子网自动切换ssh配置?,ssh,Ssh,当我在某个网络(子网是10.10.11.x)上时,我需要跳转通过一个中间主机到达我的目标,因为目标端口我不能更改,并且可以退出受限网络的端口有限。我成功地使用了如下所示的ssh配置: Host web-direct web HostName web.example.com Port 1111 Host web-via-jump jweb HostName web.example.com Port 1111 ForwardAgent yes Pro
Host web-direct web
HostName web.example.com
Port 1111
Host web-via-jump jweb
HostName web.example.com
Port 1111
ForwardAgent yes
ProxyCommand ssh -p 110 -q relay.example.com nc %h %p
通过跳投箱是一个重大的性能打击,所以我需要避免它的大多数时候,它是不需要的。切换ssh/scp/rsync主机昵称对于交互使用来说很好,但是有一些自动化/脚本化的任务非常痛苦
我的shell在网络转换期间保持打开状态,因此启动(.zshrc)机制没有帮助
我曾想过运行一个脚本来轮询受限子网,并通过修改.ssh/config文件来自动切换,但我甚至不确定是否会出现缓存问题。在我实施之前,我想我会问是否有更好的方法
基于源主机子网检测交换ssh配置的最佳方法是什么
在伪配置中,类似于:
if <any-active-local-interface> is on 10.10.11.x:
Host web
HostName web.example.com
Port 1111
ForwardAgent yes
ProxyCommand ssh -p 110 -q relay.example.com nc %h %p
else:
Host web
HostName web.example.com
Port 1111
endif
如果在10.10.11.x上:
主机站点
主机名web.example.com
端口1111
货运代理是的
ProxyCommand ssh-p 110-q relay.example.com nc%h%p
其他:
主机站点
主机名web.example.com
端口1111
恩迪夫
我正在为此使用以下函数:
函数ssh(){
network=`networksetup-getairportnetwork en0 | cut-d:-f2 | tr-d[:空格:]`
如果[-n“$network”-a-f$HOME/.ssh/config.$network];则
/usr/bin/ssh-F$HOME/.ssh/config.$network“$@”
其他的
/usr/bin/ssh“$@”
fi
}
导出-f ssh
因此,我需要一个单独的配置文件,为每个无线网络,我想要一个自定义的解决方案。它现在对我有用,但很难看。我只能把它作为一个想法而不是最好的解决方案来推荐
我很高兴知道更好的解决方案。您可以使用的exec
选项来执行shell命令,因此您可以编写如下内容:
Match exec "[[ '%h' =~ ^10\.10\.11\. ]]"
...
Match host web exec“hostname-I | grep-qF 10.10.11。”
货运代理是的
ProxyCommand ssh-p 110-q relay.example.com nc%h%p
主机站点
主机名web.example.com
端口1111
Match
选项布尔逻辑可能会短路,因此首先放置host
以跳过其他主机的exec
术语。尝试ssh-web-vvv
查看匹配的逻辑是否起作用。基于Fedor Dikarev编写的bash脚本,名为onsubnet
:
#/usr/bin/env bash
如果[[“$1”==”--help”]||[[“$1”==”-h”]|[[“$1”==”];然后
printf“用法:\n\t子网[--非]部分ip地址\n\n”
printf“示例:\n\t子网10.10。\n\t子网--不是192.168.0。\n\n”
printf“注意:\n\t部分ip地址必须从第一个开始匹配\n”
printf“\t ip地址的字符,因此是第一个示例\n”
printf“\tabove将匹配10.10.10.1,但不匹配110.10.10.1\n”
出口0
fi
on=0
关闭=1
如果[[“$1”==”--不是“]];然后
转移
on=1
关闭=0
fi
regexp=“^$(sed's/\./\\\./g'您可以检查DHCP为您提供的域后缀
- 如果您试图在内部网之外使用跳转框,此方法比检查分配中的IP范围更可靠(例如,您的家庭网络或远程工作位置使用与
example.com
的内部网相同的块)
- 如果您的intranet在任何地方都使用相同的DNS后缀,并且您正试图在intranet内遍历子网,则此方法将无效。如果您的情况是这样,请使用
匹配主机web执行器“hostname-d |!grep-q-E'^example\.com”
货运代理是的
ProxyCommand ssh-p 110-q relay.example.com nc%h%p
主机站点
主机名web.example.com
端口1111
如果您没有具有-d
选项的最新版本的hostname
(例如,您在MacOS上),您可以直接查询resolve.conf
:
Match Host web Exec“!grep-q-E'^\s*search[\t]+example\.com'/etc/resolv.conf”
...
...
我对此问题的解决方案如下:
主机myserver
主机名[内部IP]
...
匹配主机[内部IP]!Exec“nc-w1-q0%h%p
首先使用主机myserver
行非常重要,这样SSH客户机就可以知道IP地址
在Match
表达式中
Host
选项在该IP上匹配。(它接受*
,因此您也可以匹配到/8、/16或/24子网。)
Exec
选项执行netcat
并超时1秒,以测试SSH端口是否打开。如果未打开,则使用proxy命令
这是我发现的实际测试是否需要jumphost的最清晰方法。如果您的网络滞后,当然可以设置更高的超时。有关更多详细信息,请参阅。匹配ip的最简单方法是使用如下正则表达式:
Match exec "[[ '%h' =~ ^10\.10\.11\. ]]"
...
你可以扩展它:
Match exec "[[ '%h' =~ ^10\.10\.1(1|2)\. ]]"
...
我猜这不适用于rsync、scp和/或git。你试过这些吗?它只是别名,不会影响其他程序。对于scp
和rsync
很容易产生类似的别名,而对于git
则不确定这是否容易。@Jakuje使用Match exec
给出解决方案,我将根据需要重写配置看起来是更好的解决方案。如果你让Match exec
解决方案运行起来,请根据你的经验进行评论。除非你想使用真正的regexp,否则我会将grep改为fgrep。我会使用fgrep或grep-F,你的测试会匹配我认为你不期望的东西,比如10.10.110。
当然。这更像是一个概念rk.把细节留给读者。虽然更新了答案。琐碎的优化:使其grep-Fq
。-q