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


23

라는 서버가 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 스크립트의 사용에 의존하지 않고 연결이 먼저 작동하는지 "테스트"하지 않습니까?


내가 찾으려고하는 것은 /etc/hosts이것을 달성하기 위해 바이올린 구성 파일이나 SSH 구성 파일을 사용할 수 있는지 여부입니다 . 아니면 현재 어떤 LAN을 "감지"할 수 있습니까?
IQAndreas

사무실 네트워크에서 사용하는 별도의 네임 서버 세트가 있습니까?
Sree

@Sree Ah, 나는 당신이 어디로 향하고 있는지 봅니다; 영리한! 현재 네임 서버를 운영하고 있지는 않지만, 머신 중 하나를 하나로 변환 할 수 있습니다.
IQAndreas

@Sree "사무실 네트워크에 네임 서버가 있다면 ..."
해주십시오.

그거 했어. 자유롭게 위 / 아래로 투표하십시오 :)
Sree

답변:


28

사용중인 네트워크를 인식 할 수있는 방법이 있다면 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 영리한 사용 Match, 감사합니다! 종료 상태가 0이거나 0이 아닌 스크립트로 탐지를 래핑하는 것이 좋습니다. 재사용이 가능하기 때문입니다.
peterph

@ peterph 그것은 분명히 외부 스크립트로 추상화 될 수 있지만 지금까지 한곳에서만 필요했기 때문에 세 가지 규칙은 아직 시작되지 않았습니다.
Michał Politowski

직장에 있지만 실제로 다른 컴퓨터에 연결하려고하면 어떻게됩니까? HomeESSID로 WiFi를 사용하지 않으므로 exec 문이 일치하지 않으므로 호스트 이름을 192.168.1.100으로 설정 하시겠습니까?
사라

@이 질문을 이해하지 못합니다. 일치하는 대상 호스트에도 있습니다.
Michał Politowski

1
@typelogic 내가 아는 한 쉽지 않습니다. 을 사용하려고 시도 ProxyCommand nc $address ssh했지만 예를 들어. 모든 장치에 동일한 호스트 키가 있습니까? 어쨌든 환경 변수를 설정 해야하는 경우 주소를 단순히 인수로 직접 연결하는 것이 쉽지 ssh않습니까?
Michał Politowski

5

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

  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 파일과 동등한 위치가 있어야한다고 생각합니다.


있습니다-호스트 파일입니다. 그리고 이것은 정확히 내가 어떻게하는지-집에서 공개 도메인이 로컬 IP로 확인됩니다. 훌륭한 답변-그것은 내가 생각한 첫 번째 일이었습니다. 글쎄 ... 오늘은 몇 년 전에 설정했을 때 솔루션을 찾기 위해 많은 구글을해야했습니다.
mikeserv

2

이 방법을 통해 가능한지 ~/.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실행할 때의 별칭을 읽을 수 없음).


2

~/.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또는 (이럴 최선의 선택) 사무실 이름 서버.


포트가 돌로 설정되어 있지 않습니다. gamma원격 포트와 일치하도록 로컬 SSH 포트를 확실히 변경 하여 더 쉽게 만들 수 있습니다.
IQAndreas

2

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

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

1

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

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


감사. 나는 -F옵션을 좋아한다 .
typelogic

0

부분 답변 :

위의 많은 답변은 "사용중인 네트워크를 감지 할 수있는 경우"로 시작합니다. 이를 위해 인터페이스를 연결할 때 실행되는 스크립트를 사용하여 일반적인 네트워크 중 하나에 연결할 때 다양한 것을 시작합니다 (일반적으로 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 데스크톱 알림을 사용하여 실행되므로 모든 것이 사용자 영역에 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.