SSH를 통해 로그인했는지 확인하는 방법


17

현재 여러 컴퓨터에서 사용할 상당히 복잡한 bash 구성을 설정 중입니다. SSH를 통해 로그인했는지 로컬 컴퓨터에 로그인했는지 확인할 수 있는지 확인하려고합니다. 예를 들어, 이런 식으로 그 사실에 따라 별명을 설정할 수 있습니다. 별명처럼 haltrestart원격 서버를 중지하는 것이 할 수있는 최선의 일은하지 않을 수도 있기 때문이다.

내가 지금까지 아는 것은 SSH_CLIENTssh를 통해 로그인 할 때 환경 변수 가 설정 된다는 것입니다 . 불행히도이 변수는로 수퍼 유저 셸을 시작할 때 삭제됩니다 sudo -s. 또한 sudo에 모든 환경 변수를 새 셸 환경에 복사하도록 지시하는 매개 변수를 sudo에 전달할 수 있다는 것을 알고 있지만, 이것을 원하지 않으면 다른 방법이 있습니까?

답변:


14

"w"또는 "who"명령 출력을 사용할 수 있습니다. ssh를 통해 연결하면 소스 IP가 표시됩니다.


1
교육받은 추측을하십시오. 예를 들어, run ps afx및 쉘이 실행되고 있지 않은 TTY ps는 다른 로그인입니다.
Warner

6
사용하십시오 who am i.
Paul Tomblin

1
"uname -n"은 호스트 이름을 제공합니다
Hubert Kario

1
질문은에서 추출하는 것과 관련이 who am i있으므로 SSHing 여부를 결정할 수 있습니다. 작동 :hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
blueyed

4
@PaulTomblin 실제로 who두 개의 추가 인수와 함께 사용할 수 있습니다 . who am i동일한 같다 who is me하거나 who is awesome또는 who potato potato. 내가 조금 흥미로운 사실을 발견했다.
kirkpatt

9

다음은 unix.stackexchange 에서 찾은 훌륭한 답변입니다 .


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

sudo -s에서 작동하지 않음
Matt


4

bash 쉘이 sshd의 하위 프로세스인지 알고 싶다면 (n> 1 레이어 깊이 아님)

고양이 / proc / $ PPID / status | 헤드 -1 | 컷 -f2

sshd현재 쉘의 상위 프로세스 이름 또는 다른 것을 제공해야합니다 .


sudo -s에서 작동하지 않음
Matt

ps -o cmd= $PPID또는awk '/^Name:/ {print $2}' /proc/$PPID/status
Six

3

문제를 생각하는 방식을 다시 생각하고 싶다고 생각합니다. 문제는 "특정 명령을 끄고 싶기 때문에 SSH를 통해 로그인 한 것"이 아닙니다. "콘솔에 로그인했는데 특정 명령을 사용할 수 있기 때문입니다."


3

예, 다른 사람들이 지적했듯이 정보는의 출력에 괄호 안에 IP가 who am i있습니다.

Bash 정규식을 사용하여이를 감지 할 수 있습니다.

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

1
호스트 이름 일 수도 있습니다.
blueyed

호스트 이름에 숫자가 포함되어 있으면 작동하지 않습니다.
YoYoYonnY

1

나는 다른 사람들의 팁을 바탕으로 다음을 생각해 냈습니다.

캐싱에 변수를 사용합니다. 저는 쉘 테마에서 사용하고 있습니다.

is_ssh() {
    (( $+SSH_CLIENT )) && return
    if ! (( $+_ZSH_IS_SSH )); then
        # "who am i" displays current user from utmp(5).  This will be empty for
        # a "normal" terminal.  With Konsole, it is ":0" for display :0,
        # for ssh it is the hostname and with tmux sth like "tmux(PID).ID".
        local whoami="$(who am i)"}
        local host="${whoami#*\(*}"
        [[ -n $host && $host != tmux* && $host != :* ]]
        _ZSH_IS_SSH=$?
    fi
    return $_ZSH_IS_SSH
}

출처 : is_sshhttps://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63 .


0

쉘의 부모 cmdline을 찾아 재귀하십시오. 다음과 같은 것이있을 수 있습니다.

#!/usr/bin/env bash

## Find out how I'm logged in
# Tested on RHEL5.5

PD=${1:-$$}
ME=`basename $0`

## Read the shell's PPID
PAR=`ps --no-headers -p $PD -o ppid`

## CMDLINE can contain stuff like the following:
# /sbin/getty-838400tty4 // logged in at a console
# gnome-terminal         // logged in Gnome Terminal
# -bash                  // in a subshell
# su-                    // we became another user using su
# sshd: jc@pts/1         // logged in over ssh
# login                  // logged in terminal or serial device

eval `python - << __EOF__
import re
f = open("/proc/${PAR}/cmdline", 'r')
ln = f.readline()
if re.search(r'^ssh', ln): 
    print "echo Logged in via ssh"
if re.search(r'getty.*?tty', ln):
    print "echo Logged in console"
if re.search("gnome-terminal", ln):
    print "echo Logged in Gnome"
if re.search(r'^login', ln):
    print "echo Logged in console"
if re.search(r'^-?bash', ln) or re.search(r'^su', ln): 
    print "./$ME $PAR"
f.close()
__EOF__
`

실제로 작동하도록 편집 :)


0

첫 번째 로그인 수준에 있으면 다른 모든 답변이 작동합니다. 그러나 일단 로그인하면 'su'또는 'sudo'를 실행하면 (보안상의 이유로 쉘없이 사용자 계정으로 전환하려면 sudo su-<userid> -s / bin / bash- l) , 그들의 해결책은 실패합니다.

다음은 보편적 인 해결책입니다. pstree를 사용하면 sshd를 부모로 확인합니다.

if pstree -p | egrep --quiet --extended-regexp ".*sshd.*\($$\)"; then
  echo "I am remote."
else
  echo "I am local."
fi

--quiet이 제거 될 때 egrep의 출력은 다음과 같습니다. 원격으로 연결된 경우 일치하는 전체 계층 구조를 보여줍니다.

   |            |-sshd(18599)---sshd(18603)---bash(18604)---sudo(18823)---bash(18824)-+-egrep(22417)

0

이 답변은 매우 Linux에 따라 다릅니다.

parent_pid=$$
while [[ -z "${tty_bits-}" || $tty_bits -ne 0 ]]; do
  read initiator_name parent_pid tty_bits < <(
    awk '{ print substr($2, 2, length($2) - 2) " " $4 " " $7 }' /proc/$parent_pid/stat
  )
done

echo $initiator_name

로그인 프로세스에는 제어 TTY가 없습니다. 이 코드를 실행하기 전에 제어 TTY 있는지 확인하고 싶을 것입니다.

코드는 TTY를 제어하지 않는 프로세스를 찾을 때까지 프로세스 트리를 통해 위쪽으로 반복됩니다. $initiator_name이 프로세스의 이름이됩니다 (예 : "sshd").

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