SSH 구성 파일용 ProxyJump에 대한 여러 대안

SSH 구성 파일용 ProxyJump에 대한 여러 대안

터미널 서버가 있는 경우 프록시 서버 a 또는 프록시 서버 b를 통해 연결할 수 있지만 때로는 둘 중 하나만 작동하는 경우도 있습니다. ProxyJump가 프록시 서버 a 또는 b가 될 수 있도록 지정하는 방법이 있습니까 config? ProxyCommand나쁘지 않다,그러나 명령줄 솔루션(매개변수 또는 bash 스크립트 포함)은 허용되지 않습니다.

Host proxya proxyb
    HostName %h.example.com
    User user1

# Proxy servers
Host end-server.example.com
    User user1
    ProxyJump   # Here, how should I configure "either `proxy1` or `proxy2`"?

답변1

이 답변은 쉘 스크립트에 의존하지만 openssh의 구성 단계에서 실행됩니다.

사용Match

Match선언(이것은 선언의 상위 집합입니다 Host.) 호스트 이름 이외의 기준을 적용할 수 있습니다. 이러한 표준에는 exectrue 또는 false 반환 코드로 결과를 얻기 위해 스크립트를 실행하는 키워드가 있습니다 .

exec키워드는 사용자 쉘에서 지정된 명령을 실행합니다. 명령이 종료 상태 0을 반환하면 조건은 true로 간주됩니다. 공백 문자가 포함된 명령은 따옴표로 묶어야 합니다. exec토큰 섹션에 설명된 토큰을 허용하는 매개변수입니다.

에이전트가 시작되었는지 확인하는 데 사용할 수 있지만 부울 결과가 필요하므로 사용할 에이전트를 제공하는 데는 사용할 수 없습니다. 이는 Match가능한 각 프록시에 대해 항목을 구성해야 함을 의미합니다. 평소와 같이 첫 번째로 일치하는 항목이 사용됩니다(그러나 끝에 있는 경고도 참조하세요).

예를 들어 스크립트를 다음 위치에 넣으세요 ~/.ssh/bin.

mkdir ~/.ssh/bin

TCP 계층을 최소한으로 감지하려면 다음을 사용할 수 있습니다.socat( nc또는 nmap다른 후보) 제공된 호스트 및 포트 매개변수를 사용하여 TCP 연결을 확인합니다. sh아래 구성에서 추가 항목을 피하기 위해 실행 가능하게 만들 수 있습니다 .

~/.ssh/bin/isjumphostavailable.sh:

#!/bin/sh

MAXDELAY=4
socat /dev/null tcp:"$1":"$2",connect-timeout="$MAXDELAY"

socat연결이 즉시 종료되는 경우(의 /dev/nullEOF로 인해) 여기서는 4초 이상 기다리지 않습니다. 반환 코드는 스크립트의 반환 코드를 제공합니다. 연결이 성공하면 0(=> true), 그렇지 않으면 0(=> false)입니다.

위 스크립트를 사용하려면 구성은 다음과 같습니다.

# Jump hosts' fixed settings
Host proxya proxyb
    Hostname %h.example.com
    User user1

# End server's fixed settings (the factorized part)
Host end-server.example.com
    User user1

# End server's settings with runtime detection (2 lines per distinct proxy)
Match host end-server.example.com exec "sh ~/.ssh/bin/isjumphostavailable.sh proxya.example.com 22"
    ProxyJump proxya

Match host end-server.example.com exec "sh ~/.ssh/bin/isjumphostavailable.sh proxyb.example.com 22"
    ProxyJump proxyb

노트:

  • host이전 인수 Hostname(있는 경우)의 해결 방법을 상속하고 이를 ,구분 기호로 사용합니다. 따라서 host !proxy*.example.com,*.example.com에이전트 자체를 제외한 다른 터미널 서버 상황에 적용하는 데 사용할 수 있습니다.
  • exec단일 문자열을 인수로 허용합니다. 모든 항목은 큰따옴표 안에 제공되어야 합니다.

경고하다:

  • exec스크립트는 구성에서 일치하는 모든 항목에 대해 항상 평가되므로 proxya사용 가능하고 첫 번째 일치 항목으로 사용 되더라도 proxyb여전히 검사됩니다. 이를 방지하기 위해 추가 파일을 사용하여 상태 및 이전 결정(캐시로도 사용 가능)을 저장하는 등 추가 인텔리전스를 스크립트에 추가하여 실제로 프로브하는 횟수를 제한할 수 있습니다. 사용 가능한 서버가 아닌 사용 가능한 경로에 관한 것이라면(예: VPN이 특정 경로를 추가합니까?) ip -json route get ... | jq ...아무 것도 내보내지 않고 스크립트에서 사용할 수 있습니다. 당신은 이해했습니다.

사용ProxyCommand

ProxyJump주로 래퍼ProxyCommand. verbose 모드 에서도 ssh다음과 같이 작성할 수 있습니다.

debug1: Setting implicit ProxyCommand from ProxyJump: ssh -v -W '[%h]:%p' proxya
debug1: Executing proxy command: exec ssh -v -W '[end-server.example.com]:22' proxya

따라서 이 래퍼 외에 다른 래퍼를 사용하면 됩니다. 이번에는 사용 가능한 첫 번째 프록시 후보가 직접 선택되어 이전 Match ... exec경고를 극복합니다. 스크립트에는 시도할 프록시 목록이 포함되며 발견된 첫 번째 액세스 가능한 프록시를 사용합니다.

~/.ssh/bin/usefirstavailablejumphost.sh:

#!/bin/sh

MAXDELAY=4
for p in proxya proxyb; do
    if socat /dev/null tcp:"$p".example.com:22,connect-timeout="$MAXDELAY"; then
        exec ssh -W "[$1]:$2" "$p"
    fi
done
exit 1

참고: 이 쌍 [](use 에서 방금 복사함 ) 은 이 매개변수를 사용하여 IPv6 주소를 올바르게 처리 ProxyJump할 수도 있습니다 .-W

이 스크립트를 사용하여 다음을 구성합니다.

# Jump hosts' fixed settings
Host proxya proxyb
    Hostname %h.example.com
    User user1

# End server's settings
Host end-server.example.com
    User user1
    ProxyCommand sh ~/.ssh/bin/usefirstavailablejumphost.sh %h %p

이전과 마찬가지로 이 줄( Hosts와 정확히 동일하게 동작하지 않음)은 다음과 같이 작성할 수도 있습니다.Matchhost

Host !proxy* *.example.com

답변2

여러 대기 서버를 지정하는 구문은 없지만 ProxyJump다음을 수행할 수 있습니다.

Host end-server-p1
  Hostname end-server.example.com
  User user1
  ProxyJump proxy1

Host end-server-p2
  Hostname end-server.example.com
  User user1
  ProxyJump proxy2

이제 시도해 볼 수 ssh end-server-p1있으며 이것이 작동하지 않으면 실행할 수 있습니다 end-server-p2.

관련 정보