SSH를 사용하여 호스트에 연결할 때 일반적으로 호스트와 게스트 사이에 stdin
, stdout
및 의 세 가지 "파이프"가 제공됩니다 stderr
.
3
다른 파일 설명자(및 그 이상)에 대한 전달을 생성 하는 명령줄 옵션이 있습니까 ?
예를 들어 내가 하고 싶은 말은
ssh --forwardfd=10:3 remotehost 'echo test >&3'
그러면 로컬에서 열린 파일 설명자 10에 "test"가 인쇄됩니다.
답변1
openssh-6.7부터 사용할 수 있는 소켓 전달을 사용하여 이 작업을 수행할 수 있습니다. 이것은 일종의 파이프라인이다. 기술은 다음과 같이 설명됩니다.http://www.25thandclement.com/~william/projects/streamlocal.html
데이터에 대한 양방향 경로를 얻게 됩니다. mysql 예제가 있습니다:
원격 서버의 MySQL 클라이언트 연결을 로컬 인스턴스로 프록시합니다.
ssh -R/var/run/mysql.sock:/var/run/mysql.sock \ -R127.0.0.1:3306:/var/run/mysql.sock somehost
답변2
@jakuje의 답변의 문제점은 다음과 같은 경우에만 작동한다는 것입니다.소켓하지만 예상되는 표준 UNIX 도구를 사용할 수 없습니다.문서그들과 대화하세요:
ssh -R/tmp/sock.remote:/tmp/sock.local "$HOST" 'LANG=C cat >/tmp/sock.remote'
bash: /tmp/sock.remote: 해당 장치나 주소가 없습니다.
원격 호스트에서 로컬 소켓 파일이 삭제되지 않는 문제도 있습니다. 다음에 동일한 명령을 실행할 때 경고가 표시되고 소켓이 올바르게 다시 생성되지 않습니다. 이전 소켓의 -o StreamLocalBindUnlink=yes
링크를 해제하도록 선택할 수 있지만 테스트 결과 이 옵션이 작동하려면 해당 옵션을 포함 ssh
하도록 편집해야 했습니다 .sshd_config
StreamLocalBindUnlink=yes
socat
하지만 netcat
다음을 지원하는 다른 유사한 도구를 사용할 수 있습니다.UNIX 로컬 소켓( netcat-traditional
예아니요충분한! ) 파일 전송을 위해 로컬 소켓 전달을 사용합니다.
# start local process listening on local socket, which receives the data when ssh opens the connections and saves it to a local file
nc -l -N -U /tmp/sock.local >/tmp/file.local &
# connect to remote $HOST and pipe the remote file into the remote socket end
ssh \
-o ExitOnForwardFailure=yes \
-o StreamLocalBindUnlink=yes \
-R /tmp/sock.remote:/tmp/sock.local \
"$HOST" \
'nc -N -U /tmp/sock.remote </tmp/file.remote'
ssh -t
대화형 명령을 실행할 수도 있으며, 이 경우 TTY를 할당하는 데 사용해야 합니다 .
$$
이 해결 방법의 문제점은 UNIX 로컬 소켓에 대한 경로를 하드코딩해야 한다는 것입니다. 로컬 에서는 임시 디렉토리를 경로에 포함하여 각 프로세스나 사용자에게 고유하게 만들 수 있으므로 이는 그다지 큰 문제가 아닙니다. 고유하지만 원격 측에서는 /tmp/
예제에서처럼 누구나 쓸 수 있는 디렉터리를 사용하지 않는 것이 좋습니다. 이 디렉터리는 세션이 시작될 때 ssh
이미 존재해야 합니다 . 소켓 inode는 세션이 닫힌 후에도 유지되므로 "$HOME/.ssh.$$"와 같은 것을 사용하면 시간이 지남에 따라 죽은 inode로 디렉터리가 복잡해집니다.
또한 TCP 소켓에 바인딩을 사용하면 localhost
죽은 inode로 인해 파일 시스템이 복잡해지는 것을 방지할 수 있지만, 이를 사용하더라도 여전히 사용되지 않는 (고유한) 포트 번호를 선택해야 합니다. 그래서 아직은 이상적이지 않습니다. ( ssh
동적으로 포트를 할당하는 코드가 있는데 원격 호스트에서는 해당 정보를 검색할 수 있는 방법이 없다는 것을 알았습니다.)
아마도 파일을 복사하는 가장 쉬운 솔루션은 SSH의 내장 기능을 사용하는 것입니다.연결 공유대화형 세션이 여전히 병렬로 실행되는 동안 함수를 실행하거나 scp
명령을 실행합니다. sfrp
바라보다SSH를 사용하여 파일을 로컬 시스템으로 다시 복사.
답변3
나는 이것이 가능하다고 확신합니다. 나는 추가 SSH 연결을 사용하여 연결당 다른 파일 설명자 쌍을 전달하는 해킹만 제안할 수 있습니다. 예를 들어, 다음 개념 증명 스크립트는 먼저 ssh에서 더미 명령(sleep)을 실행하여 로컬 fds 5와 6을 원격 stdin 및 stdout에 연결합니다. 이러한 fd가 일반적인 0,1,2에 추가하려는 fd라고 가정합니다.
그런 다음 실제 SSH가 완료되고 원격에서 원격 fds 5 및 6을 다른 SSH의 stdin 및 stdout에 연결합니다.
예를 들어, 이 스크립트는 gzip으로 압축된 매뉴얼 페이지를 원격 장치에 전달하고, 원격지는 man을 통해 압축을 풀고 실행합니다. 실제 SSH의 stdin 및 stdout은 다른 목적으로 계속 사용할 수 있습니다.
#!/bin/bash
exec 5</usr/share/man/man1/ssh.1.gz 6>/tmp/out6 # pretend need 5 and 6
ssh remote 'echo $$ >/tmp/pid; exec sleep 99999' <&5 >&6 &
sleep 1 # hack. need /tmp/pid to be set
ssh remote '
pid=$(</tmp/pid)
exec 5</proc/$pid/fd/0 6>/proc/$pid/fd/1
echo start
gzip -d <&5 | man /dev/stdin >&6
echo stop
kill -hup $pid
'
wait
less /tmp/out6