질문 (TL; DR)
원격 전달 (일명 -R
옵션)을 위해 포트를 동적으로 할당 할 때 원격 시스템의 스크립트 (예 : 소스 .bashrc
)는 OpenSSH에서 선택한 포트를 어떻게 확인할 수 있습니까?
배경
OpenSSH (양쪽 끝)를 사용하여 여러 다른 사용자와 공유하는 중앙 서버에 연결합니다. 내 원격 세션 (현재)에 대해 X, 컵 및 펄스 오디오를 전달하고 싶습니다.
가장 사소한 것은 -X
옵션을 사용하여 X를 전달하는 것입니다. 할당 된 X 주소는 환경 변수에 저장되며 DISPLAY
그로부터 대부분의 경우 해당 TCP 포트를 결정할 수 있습니다. 그러나 Xlib이 영광이기 때문에 거의 필요하지 않습니다 DISPLAY
.
컵과 펄스 오디오에도 비슷한 메커니즘이 필요합니다. 두 서비스에 대한 기본 사항은 각각 환경 변수 CUPS_SERVER
및 의 형태로 존재합니다 PULSE_SERVER
. 사용 예는 다음과 같습니다.
ssh -X -R12345:localhost:631 -R54321:localhost:4713 datserver
export CUPS_SERVER=localhost:12345
lowriter #and I can print using my local printer
lpr -P default -o Duplex=DuplexNoTumble minutes.pdf #printing through the tunnel
lpr -H localhost:631 -P default -o Duplex=DuplexNoTumble minutes.pdf #printing remotely
mpg123 mp3s/van_halen/jump.mp3 #annoy co-workers
PULSE_SERVER=localhost:54321 mpg123 mp3s/van_halen/jump.mp3 #listen to music through the tunnel
문제는 설정입니다 CUPS_SERVER
및 PULSE_SERVER
올바르게.
포트 포워딩을 많이 사용하므로 동적 포트 할당이 필요합니다. 정적 포트 할당은 옵션이 아닙니다.
OpenSSH에는 0
원격 전달을위한 바인드 포트 ( -R
옵션) 를 지정하여 원격 서버에서 동적 포트 할당을위한 메커니즘 이 있습니다. 다음 명령을 사용하면 OpenSSH가 컵 및 펄스 전달을위한 포트를 동적으로 할당합니다.
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
해당 명령을 사용 ssh
하면 다음을 인쇄합니다 STDERR
.
Allocated port 55710 for remote forward to 127.0.0.1:4713
Allocated port 41273 for remote forward to 127.0.0.1:631
내가 원하는 정보가 있습니다! 궁극적으로 나는 생성하고 싶다 :
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
그러나 "할당 된 포트 ..."메시지가 로컬 컴퓨터에서 생성되어로 전송되어 STDERR
원격 컴퓨터에서 액세스 할 수 없습니다. 이상하게도 OpenSSH는 포트 전달에 대한 정보를 검색 할 수단이없는 것 같습니다.
어떻게 적절하게 설정하는 쉘 스크립트에 넣어 그 정보를 가져 않는 CUPS_SERVER
및 PULSE_SERVER
원격 호스트에?
막 다른 골목
내가 찾을 수있는 유일한 것은 sshd
로그에서 정보를 읽을 수있을 때까지의 자세한 정보를 늘리는 것이 었 습니다. 정보가 루트가 아닌 사용자가 액세스 할 수있는 것보다 훨씬 많은 정보를 공개하기 때문에 이는 실행 불가능합니다.
내부 구조체의 멋진 표현을 인쇄하는 추가 이스케이프 시퀀스를 지원하기 위해 OpenSSH를 패치하는 것에 대해 생각하고 permitted_opens
있었지만, 원하는 경우에도 서버 측에서 클라이언트 이스케이프 시퀀스에 액세스하는 스크립트를 작성할 수 없습니다.
더 좋은 방법이 있어야합니다
다음 접근 방식은 매우 불안정하고 사용자 당 하나의 SSH 세션으로 제한됩니다. 그러나 적어도 두 개의 동시 세션과 다른 사용자가 더 필요합니다. 그러나 나는 시도했다 ...
닭이 하나 또는 두 개를 희생하여 별이 제대로 정렬되면 sshd
사용자로 시작되지 않은 사실을 남용 할 수 있지만 성공적인 로그인 후 권한을 삭제하여 다음을 수행 할 수 있습니다.
내 사용자의 모든 청취 소켓에 대한 포트 번호 목록을 얻습니다.
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
사용자가 시작한 프로세스에 속하는 모든 청취 소켓의 포트 번호 목록을 얻습니다.
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
첫 번째 세트에있는 모든 포트이지만 두 번째 세트 내 전달 포트, 실제로 세트 수율을 감산 할 수있는 높은 동반 할 가능성이없는
41273
,55710
및6010
; 컵, 펄스 및 X.6010
를 사용하여 X 포트로 식별됩니다DISPLAY
.41273
은 컵 포트이며을lpstat -h localhost:41273 -a
반환 하기 때문0
입니다.55710
는를pactl -s localhost:55710 stat
반환 하기 때문에 펄스 포트0
입니다. (내 클라이언트의 호스트 이름도 인쇄합니다!)
(설정된 빼기 I을 수행하고 sort -u
위 명령 줄의 출력을 저장 comm
하고 빼기를 수행하는 데 사용 합니다.)
Pulseaudio를 사용하면 클라이언트를 식별 할 수 있으며 모든 의도와 목적에 따라 분리해야하는 SSH 세션을 분리하는 앵커 역할을 할 수 있습니다. 그러나, 나는 넥타이를하는 방법을 발견하지 않은 41273
, 55710
그리고 6010
동일로 sshd
처리. netstat
해당 정보를 루트가 아닌 사용자에게 공개하지 않습니다. 나는 단지를 얻을 수 -
에서 PID/Program name
내가 읽고 싶은 열 2339/54
(이 특정 인스턴스에서). 너무 가까이 ...
netstat
소유하지 않거나 커널 공간 인 프로세스의 PID를 표시하지 않는 것이 더 정확 합니다. 예를 들어