하나의 명령으로 B를 통해 시스템 A에 SSH로 연결하는 방법은 무엇입니까?


103

대학 네트워크에 기반한 컴퓨터 A 와 같은 컴퓨터에 액세스하고 싶습니다 . 그러나이 컴퓨터는 대학의 내부 네트워크를 통해서만 액세스 할 수 있으므로 집에서 직접이 컴퓨터에 SSH를 사용할 수 없습니다.

여기 제가 지금하는 일이 있습니다 :

  1. 다른 대학 컴퓨터에 로그인하십시오 (예 : 컴퓨터 B).

    (이 컴퓨터 B는 내 컴퓨터에서 SSH를 통해 액세스 할 수 있습니다.)

  2. B에서 SSH를 사용하여 A에 연결하십시오.

더 빨리 할 수있는 방법이 있습니까? 하나의 ssh 명령 만 사용하십시오.


답변:


97

예, ProxyCommandSSH 구성에서 사용 합니다.

홈 디렉토리에 SSH 구성 파일을 작성하십시오 (시스템 전체를 작성하지 않는 한) ~/.ssh/config.

Host unibroker          # Machine B definition (the broker)
Hostname 12.34.45.56    # Change this IP address to the address of the broker
User myusername         # Change this default user accordingly 
                        # (`user@unibroker` can overwrite it)

Host internalmachine    # Machine A definition (the target host)
ProxyCommand ssh -q unibroker nc -q0 hostname.or.IP.address.internal.machine 22

이제 다음을 사용하여 머신 A에 직접 연결할 수 있습니다

ssh user@internalmachine

또한 이제 단일 SSH 호스트 대상 이름이 있으므로 다른 응용 프로그램에서도이 이름을 사용할 수 있습니다. 예 :

  • SCP가 파일을 복사합니다.

    scp somefile user@internalmachine:~/
    
  • GUI 응용 프로그램에서 :

    sftp://user@internalmachine/기계를 탐색 할 위치로 사용 하십시오.

    KDE 기반 (돌핀) : 사용 fish://user@internalmachine/

노트

마치 마치 마치 마치 마치 마치 마치 원하는 기계로 hostname.or.IP.address.internal.machine포트 ( 22)를 변경하십시오 unibroker.

유니 브로커 호스트의 netcat 버전에 따라 -q0옵션을 생략해야합니다. 인증에 관하여; 기본적으로 워크 스테이션에서 두 개의 SSH 연결을 설정합니다. 이는 유니 브로커 호스트와 내부 머신 호스트가 모두 키 쌍 / 암호 및 호스트 키 확인을 위해 차례로 확인 / 인증되었음을 의미합니다.

설명

ProxyCommand'netcat'을 사용하는 이러한 접근 방식은이 를 수행하는 한 가지 방법 일뿐입니다. SSH 클라이언트가 대상 컴퓨터와 직접 통신하여 클라이언트에서 호스트 키를 확인할 수 있고 브로커의 다른 키를 사용하지 않고 공개 키 인증을 사용할 수 있기 때문에이 기능이 마음에 듭니다.

각각 Host새로운 호스트 섹션의 시작을 정의합니다. Hostname해당 호스트의 대상 호스트 이름 또는 IP 주소입니다. User의 사용자 부분으로 제공 할 내용입니다 ssh user@hostname.

ProxyCommand대상 기계의 파이프로 사용됩니다. 첫 번째 머신에 SSH를 사용 nc하고 거기에서 대상 으로 간단한 'netcat'( )을 직접 설정 하면 기본적으로 이들 사이의 브로커에서 내부 머신으로 전달되는 평문입니다. -q옵션은 출력 (단지 개인적인 취향을) 침묵한다.

netcat이 브로커에 설치되어 있는지 확인하십시오 (일반적으로 Ubuntu에서 기본적으로 사용 가능) -netcat-openbsdnetcat-openbsd 설치 또는 netcat-traditionalnetcat-traditional 설치 .

여기에서는 여전히 암호화를 사용하여 SSH를 두 번 사용하고 있습니다. netcat 채널은 일반 텍스트이지만 PC의 SSH 클라이언트는 최종 대상 시스템과 함께 다른 암호화 된 채널을 설정합니다.


4
-q0 옵션을 사용중인 시스템에서 지원하지 않으므로 제거해야했습니다. 그 외에는 모두 효과가있었습니다. 이것은 환상적인 팁입니다. 정말 고맙습니다. :)
Gerry

나는이 문제에 실행, 당신의 대답은 터미널에서 나를 위해 잘 작동하지만 내가 GUI SFTP를 사용하여 할 수없는 오전, 그것은 말한다 : 처리되지 않은 오류 메시지가에 로그온하는 동안 시간이 초과되었습니다.
Vikash B

@VikashB 글쎄, 정말 작동합니다. 특정 상황을 처리하기 위해 새로운 질문을 작성하십시오.
gertvdijk

여기에 질문이 있습니다 : askubuntu.com/questions/688567/…
Vikash B

1
@gertvdijk의 현명한 단어를 보완하기 위해 ssh 프록시와 점프 호스트 에 관한 훌륭한 위키 북이 있으며 귀중한 참조 자료가 될 수 있습니다.
트래비스 클라크

51

한 번에 홉

다른 답변 에서 제공 한 ProxyCommand 접근 방식에 대한 확실한 대안 은 대상 시스템에 직접 '홉핑'하는 것입니다.

ssh -t user@machineB ssh user@machineA

-t첫 번째 ssh명령 에 유의하십시오 . 그것이 없으면 실패합니다.

Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
[...]

실제 TTY를 강제로 할당합니다

이것의 단점은 이제 모든 구성, 확인 및 인증이 머신 B에서 발생한다는 것입니다. 보안상의 이유로 실제로는 상황이 마음에 들지 않습니다. 내 PC에서 키 페어를 좋아하고 내 PC에서 최종 대상 컴퓨터를 인증하고 확인합니다. 또한 SSH에는 대화식 쉘만 사용할 수 있으므로 SCP와 같은 다른 도구 나 GUI 파일 관리자를 사용하지 않습니다.

위에서 언급 한 모든 이유로 ProxyCommand 접근 방식을 강력히 권장 하지만 빠른 연결을 위해서는 잘 작동합니다.


'일회용'솔루션과 영구 솔루션 모두에 대해 하나의 답변이 필요하지 않습니까?
16:22에

5
@demure 이것이 바로 StackExchange 사이트의 작동 방식입니다 ... 참조 : 질문에 두 번 대답하는 공식 예절은 무엇입니까? 말한다 "한 대답에 넣어하는 것보다 그것은, 두 개의 서로 다른 답변을 게시하는 것이 좋습니다." . 그리고 나는 이것이 같은 해결책이라고 생각하지 않습니다. 내 생각에 영구 / 임시가이 접근 방식을 다르게 만드는 것은 아닙니다.
gertvdijk

다른 가이드에서는 -A 스위치와 함께 사용하지만 보안 관련 문제가 있음을 나타냅니다. 인증 에이전트 연결을 전달하거나 전달하지 않는 것이 무엇을 의미하는지 알고 있습니까?
Diagon

@gertvdijk 슈퍼 닌자 여기! 최고의 두 가지 솔루션이 있습니다. 나는 전에 그것을 본 적이 없다. 슈퍼 쿨. N 솔루션으로 메가 롱 솔루션을 만드는 것보다 낫습니다 (보통 내가 보는 것입니다).
Trevor Boyd Smith

이것은 다른 ssh를 방해하는 구성을 설정하는 것보다 훨씬 편리합니다.
Nikhil Sahu

37

-J명령 행 옵션을 사용할 수 있습니다 .

ssh -J user@machineB user@machineA

보낸 사람 man ssh:

-J [user@]host[:port]
     Connect to the target host by first making a ssh connection to
     the jump host and then establishing a TCP forwarding to the
     ultimate destination from there.  Multiple jump hops may be
     specified separated by comma characters.  This is a shortcut to
     specify a ProxyJump configuration directive.

OpenSSH 버전 7.3 (2016 년 8 월 릴리스)에 도입되었습니다 . Ubuntu 16.10 이상에서 사용할 수 있습니다.


3
machineA에 대한 키 파일을 지정해야하는 경우에도 +1
Grief

1
+1, 이것은 모든 호스트가 최근 OpenSSH 버전을 충분히 실행하고있는 경우 내 ProxyCommand 답변과 비교하여 더 나은 버전입니다.
gertvdijk

이 경우 OpenSSH 서버를 A 및 B 시스템 모두에 설치해야합니까? 이해가 되나요?
미하일

17

사용해보십시오

Host <visible hostname alias>
        Controlmaster auto
        User <user>
        hostname <visible hostname>
        port <port>
        IdentityFile ~/.ssh/<id file>

Host <private LAN hostname alias>
     ProxyCommand ssh -q -W <private LAN hostname>:<private LAN port> <visible hostname alias>

~ / .ssh / config에서 컴퓨터에만있는 키로 한 번에 모두 수행하십시오.


1
이것은 netcat을 믹스에 도입하는 것보다 더 깨끗합니다. 또한 개인 SSH 키도 B시스템 에 존재할 필요가 없습니다 .
danemacmillan

1

이것은 매우 유용한 제안입니다. 몇 시간 동안 엉망으로 만든 후에이 메모를 발견 했으며이 문서가 올바르게 작동하는지 확인했습니다. 원격 machineC에서 MachineA를 통해 MachineB에 연결하려면 다음을 수행하십시오.

예 : [xuser @ machineC ~] ssh -t MachineA ssh MachineB

"-t"는 중요하며 ssh가 없으면 실패합니다. 먼저 MachineA에서 암호를 입력 한 다음 MachineB에서 두 번째로 입력하라는 메시지가 두 번 표시됩니다. 또한이 세 시스템 모두에 사용자 "xuser"가 정의되어 있다고 가정합니다. 그렇지 않은 경우 ssh 구문 "yuser @ MachineA ..."을 사용하십시오. 원한다면 점으로 구분 된 쿼드 raw IP #을 사용할 수도 있습니다. 이것은 세계에 노출되지 않은 IP를 사용하는 개인 로컬 네트워크를 통해 연결하는 경우에 유용합니다. 로컬 호스트 파일이나 DNS에 없습니다. MachineB에서 원격 machineC로 파일을 가져 오려면 MachineB에서 MachineA로, MachineA에서 원격 machineC로 scp 할 수 있습니다. (예 : 원격 machineC는 MachineA를 ping 할 수 있지만 MachineB는 할 수 없습니다.) 경고 : Fedora와 WindowsXP로 테스트 한 MachineA는 ICS (Internet Connection Sharing)를 실행하는 XP-box입니다. MachineB와 원격 machineC는 Fedora-Linux 박스입니다. 이 제안은 나에게 중요한 문제를 해결했다. 원격 사이트 LAN에 대한 제한된 원격 모니터링 액세스. 또한 MachineB에서 "로그 아웃"할 때 두 개의 "xxx.xxx.xxx.xxx에 대한 연결이 닫혔습니다"라는 메시지가 표시됩니다. 메시지.


공개 키 인증을 설정하고 구성하면 비밀번호 입력에 대해 걱정할 필요가 없습니다. 그러나 -t여전히 필요합니다.
Felipe Alvarez

@FelipeAlvarez 컴퓨터 B가 A로 비밀번호없이 로그인 할 수 있다고 믿지 않으면 두 번째 비밀번호 입력에 대해 걱정할 필요가 있습니다.
Michael

1

ProxyCommand는 두 시스템 모두에서 쉘 액세스를 허용하는 경우를위한 완벽한 솔루션입니다. 우리는 원격 사용자에게 브로커 (B)를 통해 내부 시스템 (A)에 대한 액세스 권한을 부여하고 싶지만 사용자에게 보안 향상을 위해 B에 대한 쉘 액세스를 허용하지 않았습니다. 이것은 효과가 있었다 :

로그인 쉘 교체

브로커 에서 로그인 쉘 (use chsh)을 extuser다음 스크립트 (파일에 저장 됨)로 바꾸십시오.

#!/bin/sh   # this is essential to avoid Exec format error
ssh internaluser@A

원격 사용자의 경우 extuser @ B 및 extuser @ B의 internaluser @ A에 비밀번호 로그인이 설정되지 않은 경우 다음 명령을 실행하면 원격 사용자가 A로 직접 이동합니다.

ssh extuser@B

: 사용자 정의 로그인 쉘로 변경하기 전에 extuser @ B에 필요한 비밀번호 로그인 인증되지 않은 설정을 작성하십시오. 변경 후에는이 계정에 쉘을 통해 누구나 액세스 할 수 없으므로 sudoer @ B만이 authorization_keys 파일을 직접 편집하여 파일을 변경할 수 있습니다.

sudo vi ~extuser/.ssh/authorized_keys
sudo touch ~extuser/.hushlogin

마지막 행은 B에서 로그인 배너 표시를 억제하여 원격 사용자가 A에 투명하게 액세스 할 수 있도록하는 것입니다.


매우 흥미로운 접근법. 그러나 이것의 주요 단점은 다음과 같습니다. 1) 사용은 표준 SSH 사용으로 제한됩니다 (SFTP / SCP 지원 없음). 2) 사용자가 단일 호스트 이외의 다른 대상 호스트를 선택할 수 없음 (로그인 쉘에 하드 코딩 되었기 때문에) 3) 워크 스테이션에서 최종 대상 호스트로 호스트 키 유효성 검증을 수행 할 수 없습니다 (브로커 SSH 바이너리를 사용하므로) . 4) 사용자가 최종 대상 호스트에 액세스 할 수있는 개인 키는 사용자가 아닌 브로커에 있습니다. 이를 통해 관리자가 사용자를 가장 할 수 있습니다 (일반적으로 불가능 함).
gertvdijk

모든 점이 사실입니다. 정교 해 주셔서 감사합니다. 그러나 기본 목적은 B에 로그인하지 않고 신뢰할 수있는 사용자 ssh에게 A에 대한 액세스를 제공하는 것입니다. 관리자 만 B에 신뢰할 수있는 사용자의 공개 키를 추가 할 수 있기 때문에 (로그인하지 않고 sudo를 통해) 관리자) 외부의 신뢰할 수있는 사용자가 아닌 extuser @ B의 개인 키에 액세스하여 처음 설정했습니다!
Sunthar

1

당신은 여러 점퍼가 필요하다는 것을 의미합니다 :)

최근에, 나는 sol과 같이 jumper1 jumper2와 내 최종 시스템 에서이 문제를 만났습니다.

로컬 스크립트 :

#!/bin/bash
sshpass -p jumper1Passwd ssh -t jumper1@jumper1IP ./Y00.sh

그런 다음 첫 번째 점퍼 (내 라우터)에 Y00.sh라는 스크립트를 배치했습니다.

ssh -tt jumper2@jumper2 -i ~/.ssh/id_rsa sshpass -p finalPassWord ssh -tt final@final

당신은 이것을 당신의 IP와 암호로 바꿀 수 있습니다.

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