如何根据本地子网自动切换ssh配置?

Mik*_*ike 9 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
    ProxyCommand ssh -p 110 -q relay.example.com nc %h %p
Run Code Online (Sandbox Code Playgroud)

通过跳跃盒是一个重要的性能打击,所以我需要避免它在大多数情况下不需要它.切换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
Run Code Online (Sandbox Code Playgroud)

根据@ fedor-dikarev的回答,我创建了名为onsubnet的bash脚本:

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
Run Code Online (Sandbox Code Playgroud)

然后在我的ssh-config文件中我使用类似的东西:

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
Run Code Online (Sandbox Code Playgroud)

Jak*_*uje 14

有可能使用Match exec选项来执行特定命令,因此您可以编写如下内容:

Match exec "hostname -I | grep -F 10.10.11." host web
    ForwardAgent yes
    ProxyCommand ssh -p 110 -q relay.example.com nc %h %p
Host web
    HostName web.example.com
    Port 1111
Run Code Online (Sandbox Code Playgroud)

  • 我会使用 fgrep 或 grep -F,你的测试会匹配我认为你不期望的东西,比如“10.10.110”。 (2认同)
  • 简单的优化:将其设为“grep -Fq”。`-q` 抑制输出,这正是我们想要的,因为我们只对退出状态感兴趣。 (2认同)

Mic*_*ael 8

根据Fedor Dikarev 的回答, Mike 创建了一个名为 的 bash 脚本onsubnet

#!/usr/bin/env bash

if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]  || [[ "$1" == "" ]] ; then
  printf "Usage:\n\tonsubnet [ --not ] partial-ip-address\n\n"
  printf "Example:\n\tonsubnet 10.10.\n\tonsubnet --not 192.168.0.\n\n"
  printf "Note:\n\tThe partial-ip-address must match starting at the first\n"
  printf "\tcharacter of the ip-address, therefore the first example\n"
  printf "\tabove will match 10.10.10.1 but not 110.10.10.1\n"
  exit 0
fi

on=0
off=1
if [[ "$1" == "--not" ]] ; then
  shift
  on=1
  off=0
fi

regexp="^$(sed 's/\./\\./g' <<<"$1")"

if [[ "$(uname)" == "Darwin" ]] ; then
  ifconfig | grep -F 'inet ' | grep -Fv 127.0.0. | cut -d ' ' -f 2 | grep -Eq "$regexp"
else
  hostname -I | tr -s " " "\012" | grep -Fv 127.0.0. | grep -Eq "$regexp"
fi

if [[ $? == 0 ]]; then 
  exit $on
else
  exit $off
fi
Run Code Online (Sandbox Code Playgroud)

然后在他的.ssh/config文件中,他使用了Match execJakuje的答案

Match exec "onsubnet 10.10.1." host my-server
    HostName web.example.com
    Port 1111
    ForwardAgent yes
    ProxyCommand ssh -p 110 -q relay.example.com nc %h %p

Match exec "onsubnet --not 10.10.1." host my-server
    HostName web.example.com
    Port 1111
Run Code Online (Sandbox Code Playgroud)