SSH에서 호스트 당 두 개의 다른 IP 주소 사용 HostName 192.168.1.100

라는 서버가 gamma지속적으로 작동하고 있습니다. 때로는 집에서 연결하는 경우도 있습니다.이 경우 공용 IP 주소를 사용합니다 55.22.33.99. 때로는 직장에있을 때 연결하고 불필요하게 패킷을 반송하지 않고 로컬 IP 주소를 통해 연결합니다 192.168.1.100.

현재 두 가지 항목으로 나뉘 었습니다. ~/.ssh/conf

Host gamma-local
        HostName 192.168.1.100
        Port 22
        User andreas

Host gamma-remote
        HostName 55.22.33.99
        Port 12345
        User andreas

그래서, 내가 일을하고 있다면, 입력 ssh gamma-local만하면됩니다. 집에 있거나 세계 어느 곳에서나 실행하는 경우을 실행 ssh gamma-remote합니다.

서버에 연결할 때 현재 위치에 따라 다른 이름을 입력 할 필요가 없으며 해당 부분이 자동으로 수행됩니다. 예를 들어, 어떤 경우에는 내가 어디에 있는지 모르는 사람을 연결하는 자동화 된 스크립트가 있습니다.

Bash 스크립트사용 하여 로컬에 먼저 “시도” 하여이 문제를 해결하는 질문 이 있는데 , 연결되지 않은 경우 원격 IP 주소에 연결해보십시오. 이것은 좋지만 (1) 비효율적으로 보입니다 (특히 때로는 즉시 오류를 즉시 보내지 않기 때문에 연결이 시간 초과 될 때까지 “대기”해야하므로) (2) 스크립트 주위에 Bash 및 lugging이 필요합니다.

이것을 달성하는 다른 방법이 Bash 스크립트의 사용에 의존하지 않고 연결이 먼저 작동하는지 “테스트”하지 않습니까?



답변

사용중인 네트워크를 인식 할 수있는 방법이 있다면 Match키워드를 사용하여 ~/.ssh/config원하는 작업을 수행 할 수 있습니다. 이를 위해서는 OpenSSH ≥6.5가 필요합니다.

나는 비슷한 것을 사용한다

Match originalhost gamma exec "[ x$(/sbin/iwgetid --scheme) != xMyHomeESSID ]"
  HostName 192.168.1.100
  Port 22

Host gamma
  User andreas
  Port 12345
  HostName 55.22.33.99

그래서 나는 사용 된 wifi 네트워크의 식별자를 사용하여 SSH 연결을 목적으로 집에 있는지 여부를 결정하고 있지만 컴퓨터에 할당 된 IP 주소 또는 두 네트워크를 구별하는 다른 것을 확인할 수 있습니다. .


답변

직장에 개인 네임 서버가 있고 사무실과 집에서 같은 랩톱을 사용하는 경우 다음과 같은 이점을 얻을 수 있습니다.

  1. nsswitch.conf컴퓨터에서 DNS를 먼저 체크인하도록 수정하십시오 .
  2. gamma사무실의 개인 DNS에서 192.168.1.100 으로 확인할 DNS 항목을 만듭니다 .
  3. 시스템의 / etc / hosts 파일에 항목을 작성하여 gamma55.22.33.99 로 해결 하십시오.

이렇게 ssh gamma하면 사무실에서 사무실 DNS에서 192.168.1.100으로, 집에서 연결하면 호스트 파일에서 55.22.33.99로 해석됩니다.

추신 :이 답변은 감마가 공개 DNS 항목을 갖기를 원하지 않는다고 가정합니다. 또한 Windows 시스템에서 서버로 SSH 연결하는 경우 호스트 파일 항목을 재정의하기 위해 nssswitch.conf 파일과 동등한 위치가 있어야한다고 생각합니다.


답변

이 방법을 통해 가능한지 ~/.ssh/config모르겠지만 다른 방법은 외부 IP 주소를 기반으로 서로 연결하는 것입니다. 아마도 직장에서 일할 때 IP가 55.22.33.NNN다음과 같이 실행될 수 있습니다.

[[ $(wget -qO - http://wtfismyip.com/text) =~ ^'55.22.33.' ]] &&
    ssh 192.168.1.100 ||
    ssh -p 12345 55.22.33.99

더 간단한 방법은 내부 IP를 사용하는 것입니다. 두 네트워크가 어떻게 설정되어 있는지 모르겠지만 IP를 통해 근무 중인지 여부를 쉽게 판단 할 수있는 경우 (예 :와 같은 특정 IP가있는 경우 192.168.1.12) eth0네트워크 카드 이름을 바꾸 십시오).

[[ $(ip address show dev eth0 | grep -Po 'inet \K[\d.]+') = '192.168.1.12' ]] &&
    ssh 192.168.1.100 ||
    ssh -p 12345 55.22.33.99

당신이 사용하기로 결정하든, 당신은 당신의 쉘 별칭으로 추가 할 수 있습니다 (쉘의 초기화 파일에 다음 행을 추가 ~/.bashrc당신이 사용하는 경우 bash) :

alias gamma="[[ $(wget -qO - http://wtfismyip.com/text) =~ ^'55.22.33.' ]] && ssh 192.168.1.100 || ssh -p 12345 55.22.33.99

다른 스크립트가 액세스 할 수있게하려면 스크립트로 스크립트를 만들 수도 있습니다 (스크립트를 .bashrc실행할 때의 별칭을 읽을 수 없음).


답변

~/.ssh/configIP 주소를 호스트 이름으로 사용하면 이를 달성 할 수 없습니다 . 사실은 다른 IP 주소뿐만 아니라 다른 포트에도 연결하고 있다는 사실에 의해 추가 문제가 발생합니다. 왜냐하면 DNS 확인 자의 조정이 거의 없기 때문입니다.

나는 정정했다-당신은 Match originalhost ... exec ...콤보를 사용할 수 있습니다 ~/.ssh/config@ MichałPolitowski의 대답을 참조하십시오 . 그러나 OpenSSH에서는 완벽하게 작동하지만 다른 SSH 클라이언트에서 유사한 기능을 찾을 필요는 없습니다.

에 대한 간단한 래퍼 (쉘 함수 또는 다양한 쉘에서 사용해야하는 경우 스크립트)를 사용하여 문제를 해결할 수 있습니다. 그러면 현재 사용중인 ssh네트워크를 확인하고 적절한 Host항목을 사용할 수 있습니다 . 가장 큰 문제는 현재 사용중인 네트워크를 안정적으로 감지하는 방법입니다. 로컬 IP 주소를 염두에두고 있지만 회사 네트워크와 동일한 서브넷을 사용하는 LAN에서 연결할 수도 있으므로 신뢰할 수 없습니다.

로컬 및 원격 네트워크 모두에 대해 동일한 포트를 사용할 수있는 경우 사용 /etc/resolv.conf중인 네트워크에 따라 편집 할 수 있습니다. 분명히 자동으로 수행되어야합니다 (대부분 DHCP 클라이언트의 후크 스크립트에서 가능). 또는 로컬 이름 서버 (예 : 등 dnsmasq)를 더 잘 실행 하고 적절한 구성을 제공하십시오. 그것은이 질문의 범위를 넘어선 다.

대화식으로 만 연결해야하는 다른 옵션은 스캔 할 명령 완료를 사용하는 것 ~/.ssh/config입니다. 이렇게하면 타이핑이 줄어 듭니다 (특히 충분한 Host항목이있는 경우). 이와 같은 것 ( bash초기화) :

# complete session names for ssh
declare -g _ssh_complete_hostlist 2> /dev/null
function _ssh_complete_init () {
    _ssh_complete_hostlist=$( \
        sed -nr '/^\s*Host\s*=/{s/^[^=]+= *//;s/ /\n/g;p}' ~/.ssh/config \
        | sort )
}
_ssh_complete_init

function _ssh_complete () {
    local match=${COMP_WORDS[${COMP_CWORD}]}
    local hosts=
    local default=
    for h in $_ssh_complete_hostlist; do
        if [[ $h =~ ^$match ]]; then
            hosts="$hosts $h"
        fi
    done
    if ! (( ${COMP_CWORD} == ${#COMP_WORDS[@]}-1 )); then
        default=$( compgen -f ${COMP_WORDS[${COMP_CWORD}]} )
    fi
    COMPREPLY=($hosts $default)
}
complete -F _ssh_complete ssh

첫 번째 함수는 호스트가 완료되는 목록을 작성합니다 (일반적으로 모든 쉘에서 한 번만 실행하면 충분 함). 두 번째 함수는 약간 어색한 방식으로 실제 완료를 수행합니다. 명령 행의 마지막 토큰

이 문제에 접근하는 올바른 방법은 VPN을 통해 회사 네트워크에 연결하는 것이므로 사무실에있는 것처럼 로컬 회사 IP 주소에 액세스 할 수 있습니다. 당신은 당신이 원하는 어느 계층이든에 다음 하드 와이어 주소를 할 수 있습니다 ~/.ssh/config, /etc/resolv.conf또는 (이럴 최선의 선택) 사무실 이름 서버.


답변

몇 년 전, 비슷한 목적 으로 프로그램 을 작성 했습니다 . 그것은 당신의 요구를 충족시킬 수 있습니다. 이 프로그램으로 ssh 구성은 다음과 같습니다.

Host gamma
    ProxyCommand ssh-multipath-proxy 192.168.1.100:22 55.22.33.99:12345
    User andreas

답변

또 다른 해결책은 SSH에 두 개의 다른 구성 파일을 사용하는 것입니다. 하나의 구성 파일에 모든 것을 두는 것보다 약간 우아하지는 않지만 유지 관리가 더 쉽습니다.

사용하려는 구성 파일을 선택합니다 -F <configfile>.


답변

부분 답변 :

위의 많은 답변은 “사용중인 네트워크를 감지 할 수있는 경우”로 시작합니다. 이를 위해 인터페이스를 연결할 때 실행되는 스크립트를 사용하여 일반적인 네트워크 중 하나에 연결할 때 다양한 것을 시작합니다 (일반적으로 VPN). 이 기술은 ARP를 사용하여 게이트웨이의 MAC 주소를 얻는 것입니다.

function identifyConnection {
    gatewayIP=$(route -n | grep -e '^0\.0\.0\.0' | tr -s ' ' | cut -d ' ' -f 2)

    if [[ ! -z "$gatewayIP" ]]
    then
        # Identify the gateway by its MAC (uniqueness...)
        log "Gateway IP address=$gatewayIP"
        log "Obtaining corresponding gateway MAC address"
        gatewayData=($(arp -n $gatewayIP | grep -e $gatewayIP | tr -s ' '))
        if [[ "${gatewayData[1]}" == "(incomplete)" ]]
        then
            log "Status of gateway $gatewayIP "incomplete""
            echo ""
        elif [[ "${gatewayData[2]}" == "--" ]]
        then
            log "No MAC address found for $gatewayIP"
            echo ""
        else
            log "Gateway MAC address=[${gatewayData[2]}]"
            echo "${gatewayData[2]}"
        fi
    fi
}

그런 다음 네트워크를 게이트웨이 MAC에 연결하는 조회 테이블이 있습니다. 물론이 테이블에는 동일한 네트워크에 대해 여러 개의 MAC을 보유 할 수 있습니다 (일반적인 경우는 대기업 사이트의 다양한 Wi-Fi 핫스팟입니다). 해당 네트워크에 대해 실행할 스크립트를 결정하는 데 다른 조회 테이블이 사용됩니다.

필자의 경우 스크립트는 Plasma 데스크톱 알림을 사용하여 실행되므로 모든 것이 사용자 영역에 있습니다.