2016-11-22 17 views
5

當我在某個網絡上時(子網爲10.10.11.x),我需要跳過中間主機才能到達目的地,因爲目標端口無法更改,而且我可以退出受限制的端口網絡。我使用的是SSH的配置一樣成功如下:如何根據本地子網自動切換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 

通過的JumpBox走出去是打,所以我需要避免它爲廣大它不需要倍顯著的性能。切換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 

解決方案

基於由@費多爾 - dikarev答案我創建onsubnet名爲bash腳本:

#!/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 | fgrep 'inet ' | fgrep -v 127.0.0. | cut -d ' ' -f 2 | egrep "$regexp" >/dev/null 
else 
    hostname -I | tr -s " " "\012" | fgrep -v 127.0.0. | egrep "$regexp" >/dev/null 
fi 

if [[ $? == 0 ]]; then 
    exit $on 
else 
    exit $off 
fi 

然後在我的ssh-config文件中使用類似於:

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 

回答

4

有可能使用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 
+0

我會使用fgrep或grep -F,你的測試會匹配我認爲你不會期望的東西,比如'10.10.110.' – Mike

+0

當然。這更像是概念如何運作。搞清楚細節留在讀者身上。雖然更新了答案。 – Jakuje

0

我使用下面的函數爲:

function ssh() { 
    network=`networksetup -getairportnetwork en0 | cut -d: -f2 | tr -d [:space:]` 
    if [ -n "$network" -a -f $HOME/.ssh/config.$network ]; then 
    /usr/bin/ssh -F $HOME/.ssh/config.$network "[email protected]" 
    else 
    /usr/bin/ssh "[email protected]" 
    fi 
} 
export -f ssh 

所以我必須爲每個WiFi網絡我想自定義解決方案單獨的配置文件。它適用於我現在,但它很醜,所以我可以推薦它只作爲想法不是最好的解決方案。
很高興能夠更好地瞭解任何解決方案。

+0

我猜這並沒有解決的rsync,scp和/或混帳。你嘗試過那些嗎? – Mike

+0

它只是別名,它不影響其他程序。對於'scp'和'rsync',很容易做出類似的別名,而'git'不確定它會很容易。 @Jakuje使用'Match exec'給出解決方案,我將重寫我的配置,因爲它看起來更好的解決方案。 –

+0

如果您獲得'Match exec'解決方案,請評論您的經驗。除非你想使用真正的正則表達式,否則我會將grep改爲fgrep。 – Mike

相關問題