외부 프로세스에서 SSH 클라이언트 프로세스 내의 작업 디렉터리 가져오기

외부 프로세스에서 SSH 클라이언트 프로세스 내의 작업 디렉터리 가져오기

SSH를 통해 원격 컴퓨터에 연결했습니다. ls해당 원격 컴퓨터의 현재 작업 디렉터리를 가져오고(바람직하게는 유사한 명령을 실행하고 싶지만) 프로세스 외부에서 가져오고 싶습니다 .

이것이 나의 과정이다

$ ps
49100 ttys001    0:00.21 -zsh
52134 ttys002    0:00.21 -zsh
52171 ttys002    0:00.05 ssh [email protected]

터미널 2(ttys002)는 현재 원격 시스템에 SSH로 접속하는 곳입니다.

클라이언트 시스템에서 원격 호스트의 현재 작업 디렉토리를 가져올 수 있습니까? 즉, pwd터미널 2에는 입력할 필요가 없습니다 .

을 실행하면 lsof프로세스의 로컬 컴퓨터에서 현재 작업 디렉터리를 얻을 수 있지만 원격 컴퓨터에서는 얻을 수 없습니다.

~ $ lsof -p 52171
COMMAND   PID    USER   FD      TYPE             DEVICE SIZE/OFF                NODE NAME
ssh     52175   falky  cwd       DIR                1,4     2816              994619 /Users/falky

이것이 가능하지 않은 경우 SSH를 통해 원격 시스템에 연결하기 전에 이를 수행할 수 있는 방법이 있습니까? 예를 들어 의사 터미널을 설정할 수 있나요? 아니면 내 로컬 컴퓨터로 핑을 다시 보내는 원격 컴퓨터에 무언가를 설치할 수 있습니까? 여기에 조언이나 지침이 있으면 도움이 될 것입니다.

답변1

이것이 가능하지 않은 경우 SSH를 통해 원격 시스템에 연결하기 전에 이를 수행할 수 있는 방법이 있습니까?

"연결 공유 모드"에서 SSH 클라이언트를 시작할 수 있습니다.

ssh -M -S ~/.ssh/%r@%h:%p user@localhost
user@localhost's password:
...
user@localhost$ echo $$
5555
user@localhost$ cd /some/path

다른 터미널에서:

ssh -S ~/.ssh/%r@%h:%p user@localhost
<no need to enter the password again>
user@localhost$ ls -l /proc/5555/cwd
<listing of /some/path>

ssh(1)맨페이지를 참조 하여 알아보세요.-S그리고-M옵션 ssh_config(1)Control*구성 옵션.

답변2

이 작업을 수행할 수 있는 유일한 방법은 다음과 같습니다.

  1. ioctl을 사용하여 로컬 터미널에 명령을 삽입하십시오 TIOCSTI. 이는 OpenBSD에서는 작동하지 않으며 Linux에서는 CAP_SYS_ADMIN호출 프로세스의 제어 tty가 아닌 다른 tty에서 이를 사용하려면 cap(즉, 루트)이 필요합니다. TIOCSTI이 사이트에서는 이미 많은 사용 예를 찾을 수 있습니다 .

  2. ptrace(2)SSH 클라이언트를 조작하고(예: 디버거 또는 다른 디버거를 통해) gdb(1)암호화된 채널에 명령을 삽입합니다. 이를 수행하는 방법은 주로 ssh 클라이언트 내부에 따라 다릅니다(즉시 실행 가능한 예제의 경우 디버깅 기호로 컴파일된 ssh 클라이언트가 필요합니다). 다른 솔루션과 마찬가지로 , 제한이 있는 경우 (예: 루트 사용자)가 ptrace(2)아니면 다른 사용자의 프로세스(또는 프로세스 자체가 덤프 불가능하게 되는 경우)에서는 작동하지 않습니다 .CAP_SYS_PTRACE

  3. 포인트 2를 따르십시오. SSH 클라이언트를 실행하는 pseudo-tty 호스트의 프로세스를 제어하고 pseudo-tty 호스트의 파일 설명자에 명령을 씁니다. 일부 내부 채널이 아닌 파일 설명자에 데이터를 써야 하기 때문에 예를 드는 것이 더 쉬울 수 있습니다.

터미널에서:

$ tty
echo $PPID
6666
$ ssh localhost
localhost$ cd /tmp
localhost$

다른 터미널에서 PPID=6666(로컬 쉘의 상위 프로세스)가 터미널 에뮬레이터의 프로세스라고 가정하면(보장 없음!) 어떤 파일 설명자가 해당 쉘의 터미널을 참조하는지 정확하게 추측할 수 있습니다(터미널 에뮬레이터가 이 시점까지 실행 중일 때는 수행하기 어렵습니다). GNU 스크린과 같은 일종의 단일 프로세스 멀티플렉서입니다):

$ pid=6666
$ ls -l /proc/$pid/fd
...

lrwx------ 1 xxx xxx 64 Oct 12 08:52 3 -> /dev/ptmx  # the pty master
...
$ grep flags /proc/$pid/fdinfo/3
flags:  0104002    # OK, it's opened in rw mode (2)
$ gdb -p $pid
...
(gdb) call write(3, "pwd\r", 4)
$1 = 4
(gdb) continue
Continuing.
...

모든 것이 순조롭게 진행되면 pwd명령은 원격 SSH에서 실행됩니다.

ssh 시작 방법을 제어할 수 있는 경우 3번 항목에 따라 pseudo-tty를 제어하는 ​​프로세스가 복잡한 멀티플렉서가 아닌 간단한 프로세스인지 확인할 수 있습니다. Linux에서는 다음을 사용할 수 있습니다.script(1)유용:

script /dev/null -c 'ssh user@host'

script=프로세스 내 tty 마스터의 파일 설명자언제나Linux에서는 ssh가 직접 실행되는지 아니면 .3을 통해 실행되는지 걱정할 필요가 없습니다 /bin/some/sh -c.

관련 정보