SSH가 쉘을 제어하는지 어떻게 알 수 있습니까?


69

SSH를 통해 제어되는 경우 쉘 스크립트 (특히 .zshrc)에서 감지하고 싶습니다. HOST 변수를 시도했지만 항상 셸을 실행하는 컴퓨터의 이름입니다. SSH 세션이 시작되는 호스트 이름에 액세스 할 수 있습니까? 둘을 비교하면 내 문제가 해결됩니다.

로그인 할 때마다 마지막 로그인 시간과 호스트를 나타내는 메시지가 있습니다.

Last login: Fri Mar 18 23:07:28 CET 2011 from max on pts/1
Last login: Fri Mar 18 23:11:56 2011 from max

이는 서버에이 정보가 있음을 의미합니다.

답변:


90

내가 사용하는 기준은 다음과 같습니다 ~/.profile.

  • 변수 중 하나가 SSH_CLIENT이상이 SSH_TTY정의되고, 그것은 SSH 세션입니다.
  • 로그인 쉘의 상위 프로세스 이름이 sshd이면 ssh 세션입니다.
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
  SESSION_TYPE=remote/ssh
# many other tests omitted
else
  case $(ps -o comm= -p $PPID) in
    sshd|*/sshd) SESSION_TYPE=remote/ssh;;
  esac
fi

(왜 세션 시작이 아닌 쉘 구성에서 이것을 테스트하고 싶습니까?)



1
내가 뭔가 빠지지 않는 한 원격 쉘에서 ssh 에이전트 전달을 활성화하려면 쉘 구성 에서이 작업을 원할 수 있습니다 (전달하려는 각 쉘에서 환경 변수를 설정해야하기 때문에)?
언더런

@underrun 당신의 요점을 이해하지 못합니다. 동일한 세션에서 다른 쉘을 실행하면에 의해 설정된 환경 변수가 상속됩니다 .profile. 그리고 이것이 에이전트 전달과 어떤 관련이 있습니까?
Gilles

1
@underrun SSH 에이전트 전달이 있는지 테스트하려면 SSH_AUTH_SOCK변수를 테스트 하십시오. 그러나 왜 이런 경우 SSH 에이전트를 실행 하시겠습니까? 에이전트 전달없이 로그인 한 경우 에이전트를 시작 했습니까? 아직 에이전트가없는 경우 에이전트를 시작하지 않는 이유는 무엇 [ -n "$SSH_AUTH_SOCK" ] || eval $(ssh-agent)입니까?
Gilles

1
@Praxeolitic SSH_*변수는 SSH를 통해 스크린 세션을 시작하는 경우와 같이 SSH 세션 헤드에있는 쉘의 하위 프로세스에서도 설정됩니다 (원하는 경우 세션을 시작하기 전에 변수를 설정 해제해야 함). 부모 프로세스를 테스트하는 이유는 sshd가 환경 변수를 정의하기 전에 그 작업을 시작했기 때문이라고 생각합니다.
Gilles

21

당신은을 통해 확인 할 수 있어야한다 SSH_TTY, SSH_CONNECTION또는 SSH_CLIENT변수.


1
또한 이러한 추가 env_keepsudoers그것을 통해 작동하도록 su:) 명령
토마스 G.에게

10

Bash를 사용하여 Linux에서 동일한 문제가 발생했습니다. 먼저 환경 변수 SSH_CONNECTION을 사용했지만 그 경우 설정되지 않았다는 것을 깨달았습니다 su -.

위의 lastlog 솔루션은 su또는 이후에 작동하지 않았습니다 su -.

마지막으로 who am iSSH 연결 인 경우 끝에 원격 IP (또는 호스트 이름)를 표시하는을 사용하고 있습니다. su 후에도 작동합니다.

Bash 정규 표현식을 사용하면 다음과 같이 작동합니다.

if [[ $(who am i) =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then echo SSH; else echo no; fi

zsh가 정규 표현식을 지원하지 않는 경우 grep, cut, sed 등을 사용하여 여러 가지 방법으로 동일하게 수행 할 수 있습니다.

궁금한 점은 아래의 루트 .bashrc에서 내가 사용하는 것입니다.

    # We don't allow root login over ssh.
    # To enable root X forwarding if we are logged in over SSH, 
    # use the .Xauthority file of the user who did su

    w=$(who am i)
    if [[ $w =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then
        olduser=${w/ .*/}
        oldhome=$(getent passwd $olduser | cut -d: -f 6)
        [ -f "$oldhome/.Xauthority" ] \
          && export XAUTHORITY=$oldhome/.Xauthority
    fi

함께 작동하는 대안 은 부모 프로세스 susshd통해 반복적으로 검색 하는 것입니다 .

#!/bin/bash

function is_ssh() {
  p=${1:-$PPID}
  read pid name x ppid y < <( cat /proc/$p/stat )
  # or: read pid name ppid < <(ps -o pid= -o comm= -o ppid= -p $p) 
  [[ "$name" =~ sshd ]] && { echo "Is SSH : $pid $name"; return 0; }
  [ "$ppid" -le 1 ]     && { echo "Adam is $pid $name";  return 1; }
  is_ssh $ppid
}

is_ssh $PPID
exit $?

함수가 .bashrc에 추가되면 다음과 같이 사용할 수 있습니다 if is_ssh; then ...


1
원격 tmux세션 에서 작동하지 않으며 IPv6을 통해 로그인했으며 DNS 역방향 이름이없는 경우에도 문제가 있습니다.
bene

@ bene : 작동하지 않는 것은 무엇입니까? 정규식 또는 who am iIPv6 주소가 표시되지 않습니까?
mivk

1) who am i원격 tmux세션 에서 아무것도 반환하지 않습니다 . 2) IPv6 주소에는 정규 표현식에서 허용하지 않는 콜론이 포함될 수 있습니다. X 세션에 who am i포함 (:0.0)되어 있기 때문에 까다로울 수 있습니다 (xterm).
bene

@bene : 방금 추가 한 대체 솔루션은 IPv6에서도 작동합니다. tmux에 대해서는 잘 모르지만에서 작동 screen합니다.
mivk

7

Gilles와 Cakemox의 답변은 훌륭하지만 완벽 함을 위해서만 생각합니다 ...

Last login: Fri Mar 18 23:07:28 CET 2011 from max on pts/1

pam_lastlog1 에서 온다 .

예를 들어 2 명령을 pam_lastlog사용하여 정보를 인쇄 할 수 있습니다.lastlog

$ lastlog -u mikel  
Username         Port     From             Latest
mikel            tty1                      Fri Jan 28 10:58:10 +1100 2011

로컬 로그인의 경우

Username         Port     From             Latest
mikel            pts/9    mikel-laptop     Sat Mar 19 11:11:58 +1100 2011

SSH 로그인 용.

내 시스템에서는 추출하기 위해 작동합니다.

$ lastlog -u mikel | sed -ne '2{p;q}' | cut -c 27-42
mikel-laptop 

last그리고 w예를 들어, 너무 도움이 될 수

$ TTY=$(tty)
$ last -n 1 ${TTY#/dev/} | sed -ne '1{p;q}'
mikel    pts/12       :0.0             Sat Mar 19 11:29   still logged in 


1 Linux / FreeBSD 문서 pam_lastlog.
2 개의 Linux / FreeBSD lastlog(8) 매뉴얼 페이지.


1

환경을 살펴보고 올바른 옵션을 찾는 것으로 시작하십시오.

printenv|grep SSH
SSH_CLIENT=192.168.1.xxx
SSH_CONNECTION=192.168.1.xxx
SSH_TTY=/dev/ttys021

이러한 많은 환경 변수에 연결하여 해당 존재에 따라 특정 조치를 트리거 할 수 있습니다.


-1

이것은 SSH를 사용하여 다른 사용자로부터 설정된 모든 연결을 확인하는 것입니다

netstat | grep ssh

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