Jak ustalić, czy jestem zalogowany przez SSH?

17

Obecnie konfiguruję dość złożoną konfigurację bash, która będzie używana na wielu komputerach. Próbuję dowiedzieć się, czy można ustalić, czy jestem zalogowany przez SSH, czy na komputerze lokalnym. W ten sposób mogłem na przykład ustawić pewne aliasy w zależności od tego faktu. Podobnie jak aliasing haltdo restartzatrzymania zdalnego serwera może nie być najlepszym rozwiązaniem.

Wiem do tej pory, że zmienna środowiskowa SSH_CLIENTjest ustawiana, gdy loguję się przez ssh. Niestety ta zmienna jest odrzucana, gdy uruchamiam powłokę superużytkownika sudo -s. Wiem również, że mogę przekazać parametr sudo, który instruuje sudo, aby skopiować wszystkie moje zmienne środowiskowe do nowego środowiska powłoki, ale jeśli nie chcę tego robić, czy jest inny sposób?

t6d
źródło

Odpowiedzi:

14

Możesz użyć polecenia „w” lub „who”. Kiedy połączysz się przez ssh, pokażą twój źródłowy adres IP.

facha
źródło
1
Rób wykształcone domysły. Na przykład uruchom, ps afxa TTY dla powłoki, która nie działa, psbędzie drugim loginem.
Warner
6
Zastosowanie who am i.
Paul Tomblin,
1
„uname -n” da ci nazwę hosta
Hubert Kario
1
Wydaje się, że pytanie jest bardziej powiązane z jego wydobyciem who am i, abyś mógł stamtąd ustalić, czy korzystasz z SSHing, czy nie. Działa to:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
niebiesko
4
@PaulTomblin W rzeczywistości można używać whodowolnych dwóch dodatkowych argumentów. who am ijest taki sam jak who is melub who is awesomelub who potato potato. Fakt był dla mnie trochę interesujący.
kirkpatt
9

Oto świetna odpowiedź, którą znalazłem na unix.stackexchange :


  • Jeśli jedna ze zmiennych SSH_CLIENTlub SSH_TTYjest zdefiniowana, jest to sesja ssh.
  • Proces macierzysty powłoki logowania można sprawdzić za pomocą ps -o comm= -p $PPID. Jeśli tak sshd, to sesja ssh.
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
Nicole
źródło
Nie działa dla sudo -s
Matt
6

Można dodać SSH_*do env_keepw sudoerstak, że może to zostać wykryte podczas włączony do innego użytkownika.

Ignacio Vazquez-Abrams
źródło
4

Jeśli chcesz wiedzieć, czy bash shell jest bezpośrednio potomnym procesem sshd (nie n> 1 warstwy głębokości)

cat / proc / $ PPID / status | głowa -1 | cut -f2

powinien dać ci sshdnazwę cokolwiek nadrzędnego twojej bieżącej powłoki.

rhlee
źródło
Nie działa dla sudo -s
Matt
ps -o cmd= $PPIDlubawk '/^Name:/ {print $2}' /proc/$PPID/status
Six
3

Myślę, że chcesz przemyśleć sposób, w jaki myślisz o problemie. Pytanie nie brzmi „czy jestem zalogowany przez SSH, ponieważ chcę wyłączyć niektóre polecenia”. „Jestem zalogowany na konsoli, ponieważ wtedy włączę określone polecenia”.

Andy Lester
źródło
3

Tak, jak zauważyli inni, informacje są w obecności twojego adresu IP w nawiasach wyjściowych who am i.

Możesz użyć wyrażeń regularnych Bash, aby je wykryć:

if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
mivk
źródło
1
Może to być również nazwa hosta.
blueyed,
Nie działa, jeśli nazwa hosta zawiera liczby.
YoYoYonnY
1

Wymyśliłem następujące, oparte na wskazówkach innych tutaj.

Wykorzystuje zmienną do buforowania - używam jej w motywie powłoki.

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
}

Źródło: is_sshw https://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63 .

niebieskawy
źródło
0

Poszukaj cmdline rodzica twojej powłoki i powtórz. Może coś takiego:

#!/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__
`

Edytowane, aby faktycznie działało :)

Justin
źródło
0

Wszystkie pozostałe odpowiedzi działają, jeśli jesteś na pierwszym poziomie logowania. Ale jeśli po zalogowaniu uruchomisz „su” lub „sudo” (w moim przypadku ze względów bezpieczeństwa przełączysz się na konto użytkownika bez powłoki, musiałem uruchomić: sudo su - <userid> -s / bin / bash - l) ich rozwiązanie zawodzi.

Poniżej znajduje się uniwersalne rozwiązanie; używając pstree, sprawdzasz sshd jako rodzic.

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

Oto wynik działania polecenia egrep, po usunięciu opcji --quiet. Pokazuje całą pasującą hierarchię, jeśli jedna jest połączona zdalnie.

   |            |-sshd(18599)---sshd(18603)---bash(18604)---sudo(18823)---bash(18824)-+-egrep(22417)
Hans Deragon
źródło
0

Proszę pamiętać, że ta odpowiedź jest bardzo, bardzo specyficzna dla Linuksa.

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

To powoduje kluczowe założenie: proces logowania nie będzie miał kontrolnego TTY; prawdopodobnie chcesz, aby sprawdzić, czy mają kontrolę TTY przed uruchomieniem tego kodu (który, na podstawie wymagań, prawdopodobnie jest to bezpieczny zakład, w każdym razie).

Kod iteruje w górę przez drzewo procesów, dopóki nie znajdzie procesu, który nie kontroluje TTY. $initiator_namebędzie nazwą tego procesu (na przykład „sshd”).

Christian Henry
źródło