Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何根据本地子网自动切换ssh配置?_Ssh - Fatal编程技术网

如何根据本地子网自动切换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

当我在某个网络(子网是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
    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