루트가 없고 다른 모든 SSH 연결을 종료하지 않고 SSH 터널을 닫습니다.

루트가 없고 다른 모든 SSH 연결을 종료하지 않고 SSH 터널을 닫습니다.

8888과 같은 로컬 포트를 수신하는 SSH 터널이 있고 ssh -R 8888:localhost:80 myuser@myhost. 이 터널을 닫을 "myhost"의 "myuser"에 대한 스크립트를 작성해야 합니다.

스크립트는 "myhost"의 "myuser"에 의해 실행됩니다. 루트에서는 실행되지 않으며 sudo도 불가능합니다.

한 가지 접근 방식은 lsof 또는 netstat를 사용하여 8888에서 수신 대기하는 프로세스의 PID를 찾은 다음 프로세스를 종료하는 것입니다. 그러나 lsof와 netstat는 모두 sudo를 사용하지 않고 PID 제공을 거부합니다. netstat를 사용하면 -sudo 없이 "PID/프로그램 이름" 대신 얻을 수 있습니다 .

루트 권한 없이 특정 포트에서 수신 대기하는 프로세스의 PID를 찾는 방법이 있습니까? 이 포트에서 수신 대기하는 프로세스는 우리와 동일한 사용자로 실행 중입니다. 아니면 외부에서 SSH 터널을 닫는 다른 방법이 있습니까?

ssh 이스케이프 시퀀스를 사용하여 연결을 재설정하는 것은 우리가 하는 것처럼 해결책이 아닙니다.~ 아니다터널에서. 우리 스크립트는 동일한 사용자가 동일한 호스트에서 터널과 별도로 실행해야 합니다.

또한 단지 실행하는 것은 killall sshd이 연결뿐만 아니라 다른 모든 SSH 연결을 종료하므로 해결책이 아닙니다.

이 질문은 내가 찾은 모든 허용된 답변에 루트 권한이 필요하거나 모든 SSH 연결을 종료하기 때문에 많은 유사한 질문과 중복되지 않습니다.

호스트 "myhost"는 Ubuntu 12.04.5를 실행 중입니다.


편집: @Jakuje의 요청에 따른 토론 요약:

  • @Patrick은 사용자가 전체 sudo 없이 루트 권한으로 스크립트를 실행할 수 있도록 사용하거나 setuid수정하는 접근 방식을 제안했습니다 . /etc/sudoers하지만 setuid스크립트 대신 바이너리를 작성해야 하기 때문입니다. 그러나 사용자가 루트 권한으로 스크립트를 실행하도록 허용하면 잠재적인 보안 위험이 발생할 수 있습니다. 하지만 이 솔루션은 사용자에게 루트 액세스 권한이 전혀 없어 수정할 수 없는 경우에는 적용되지 않습니다 /etc/sudoers. @Patrick이 이것을 답변으로 쓴다면 나는 확실히 찬성할 것이지만 아직 승인된 것으로 표시하지는 않을 것입니다.

  • @EricRenouf는 sshd가 사용자에게 소켓을 표시하여 사용자가 /proc/*/fd소켓이 있는 프로세스를 찾는 데 사용할 수 없다는 것을 발견했습니다. 이것이 아마도 lsof나 netstat가 이를 표시하지 않는 이유일 것입니다.

더 많은 아이디어:

@EricRenouf가 발견한 대로 열린 소켓 포트 번호나 inode로 sshd PID를 얻을 수 있는 방법이 없을 것입니다. 하지만 이 sshd PID를 찾는 방법이나 연결을 닫으라고 지시하는 다른 방법이 없는지 궁금합니다. 아마도 sshd를 사용하여 직접적으로 가능할 수도 있습니다.

예를 들어, sshd 디버그 모드를 활성화하면 어떤 sshd 프로세스가 사용자가 읽을 수 있는 sshd -d포트에 대한 터널을 열었는지 기록합니다 . /var/log/auth.log따라서 스크립트는 로그를 구문 분석하고 거기에서 PID를 찾을 수 있습니다. 그러나 디버그 모드 sshd를 실행하는 것은 좋은 생각이 아닙니다. 실제로는SSHD를 위한 간단한 패치디버그 모드 없이도 열린 터널을 기록합니다. 하지만 패치된 SSHD를 실행하는 것도 좋은 생각인지 잘 모르겠습니다.

다른 비결이 있나요?

답변1

"myhost"에 연결하기 위한 사용자 정의 SSH 키를 설정하는 것부터 시작하세요. 그런 다음 "myhost"에서 .ssh/authorized_keys 파일을 편집하여 셸의 상위 PID가 파일에 기록되도록 합니다.

command="echo $PPID > tunnel.pid; bash" ssh-rsa AAA...

보안을 위해 다른 설정을 조정하거나 PID만 작성하고 정지하는 사용자 정의 스크립트를 작성할 수도 있습니다. 어느 쪽이든 원칙은 동일합니다.

SSH 세션을 열어두는 프로세스의 PID가 있으면 스크립팅만 하면 됩니다.

kill `cat tunnel.pid`

...프로세스를 종료하여 SSH 세션을 닫습니다.

-i명령 에 플래그를 사용하여 ssh연결에 사용할 개인 키를 지정할 수 있습니다.

편집: 활성 연결이 있는 경우 셸 프로세스를 종료해도 터널이 닫히지 않으므로 상위 SSH 프로세스를 종료합니다.

편집: 자동화된 SSH 연결에 대한 첫 번째 성향은 SSH 키를 사용하는 것이지만 다음을 사용하여 동일한 프로세스를 에뮬레이션할 수 있습니다.

ssh -R 8888:localhost:80 myuser@myhost 'echo $PPID > tunnel.pid; for ((;;)); do sleep 1; done'

또한 종료 시기를 결정하기 위해 다른 기준을 확인하는 스크립트를 대체할 수도 있습니다. 아마도 이것을 처리하는 더 깔끔한 방법 일 것입니다.

관련 정보