Wie kann ich feststellen, ob ich über SSH angemeldet bin?

17

Ich richte gerade eine ziemlich komplexe Bash-Konfiguration ein, die auf mehreren Computern verwendet werden soll. Ich versuche herauszufinden, ob es möglich ist, festzustellen, ob ich über SSH oder auf einem lokalen Computer angemeldet bin. Auf diese Weise könnte ich zum Beispiel einige Aliase festlegen, die von dieser Tatsache abhängen. Wie Aliasing halt, restartda das Stoppen eines Remote-Servers möglicherweise nicht das Beste ist.

Was ich bisher weiß ist, dass die Umgebungsvariable gesetzt SSH_CLIENTwird, wenn ich mich über ssh anmelde. Leider wird diese Variable verworfen, wenn ich eine Superuser-Shell mit starte sudo -s. Ich weiß auch, dass ich sudo einen Parameter übergeben kann, der sudo anweist, alle meine Umgebungsvariablen in die neue Shell-Umgebung zu kopieren.

t6d
quelle

Antworten:

14

Sie können die Befehlsausgabe "w" oder "who" verwenden. Wenn Sie eine Verbindung über ssh herstellen, wird Ihre Quell-IP angezeigt.

facha
quelle
1
Machen Sie fundierte Vermutungen. Beispielsweise ist run ps afxund das TTY für die nicht laufende Shell psdas andere Login.
Warner
6
Verwenden Sie who am i.
Paul Tomblin
1
"uname -n" gibt Ihnen den Hostnamen
Hubert Kario
1
Die Frage scheint eher mit dem Extrahieren zu who am itun zu haben, sodass Sie von dort aus feststellen können, ob Sie SSHing verwenden oder nicht. Dies funktioniert:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
blueyed
4
@PaulTomblin Tatsächlich können Sie whozwei zusätzliche Argumente verwenden. who am iist dasselbe wie who is meoder who is awesomeoder who potato potato. Eine Tatsache, die ich ein wenig interessant fand.
Kirkpatt
9

Hier ist eine großartige Antwort, die ich auf unix.stackexchange gefunden habe :


  • Wenn eine der Variablen SSH_CLIENToder SSH_TTYdefiniert ist, handelt es sich um eine SSH-Sitzung.
  • Der übergeordnete Prozess der Login-Shell kann mit überprüft werden ps -o comm= -p $PPID. Wenn dies sshdder Fall ist , handelt es sich um eine SSH-Sitzung.
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
quelle
Funktioniert nicht für sudo -s
Matt
6

Man könnte hinzufügen , SSH_*um env_keepin sudoersso dass diese während an den anderen Benutzern eingeschaltet erkannt werden können.

Ignacio Vazquez-Abrams
quelle
4

Wenn Sie wissen möchten, ob die Bash-Shell direkt ein untergeordneter Prozess von sshd ist (nicht n> 1 Ebenen tief), können Sie dies

cat / proc / $ PPID / status | head -1 | schnitt -f2

Es sollte Ihnen sshdoder was auch immer der übergeordnete Prozessname Ihrer aktuellen Shell sein.

Rhlee
quelle
Funktioniert nicht für sudo -s
Matt
ps -o cmd= $PPIDoderawk '/^Name:/ {print $2}' /proc/$PPID/status
Six
3

Ich denke, Sie möchten die Art und Weise überdenken, in der Sie über das Problem denken. Die Frage lautet nicht "Bin ich über SSH angemeldet, weil ich bestimmte Befehle deaktivieren möchte?". Es ist "Bin ich an der Konsole angemeldet, dann werde ich bestimmte Befehle aktivieren."

Andy Lester
quelle
3

Ja, wie andere angemerkt haben, ist die Info bei Vorhandensein Ihrer IP in Klammern in der Ausgabe von who am i.

Sie können reguläre Bash-Ausdrücke verwenden, um dies zu erkennen:

if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
mivk
quelle
1
Es kann auch ein Hostname sein.
bläulich
Funktioniert nicht, wenn der Hostname Zahlen enthält.
YoYoYonnY
1

Ich habe mir Folgendes ausgedacht, basierend auf Tipps von anderen hier.

Es verwendet eine Variable zum Zwischenspeichern - ich verwende sie in meinem Shell-Thema.

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
}

Quelle: is_sshin https://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63 .

bläulich
quelle
0

Suchen Sie nach der übergeordneten Cmdline Ihrer Shell und wiederholen Sie den Vorgang. Vielleicht so etwas wie das Folgende:

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

Bearbeitet, damit es tatsächlich funktioniert :)

Justin
quelle
0

Alle anderen Antworten funktionieren, wenn Sie sich auf der ersten Login-Ebene befinden. Wenn Sie jedoch nach dem Anmelden "su" oder "sudo" ausführen (in meinem Fall musste ich aus Sicherheitsgründen Folgendes ausführen, um zu einem Benutzerkonto ohne Shell zu wechseln: sudo su - <Benutzer-ID> -s / bin / bash - l) , scheitern ihre Lösung.

Das Folgende ist eine universelle Lösung; Mit pstree suchen Sie als übergeordnetes Element nach sshd.

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

Hier ist die Ausgabe des egrep, wenn --quiet entfernt wird. Es wird die gesamte Hierarchie angezeigt, die übereinstimmt, wenn eine Verbindung über Fernzugriff besteht.

   |            |-sshd(18599)---sshd(18603)---bash(18604)---sudo(18823)---bash(18824)-+-egrep(22417)
Hans Deragon
quelle
0

Bitte beachten Sie, dass diese Antwort sehr, sehr Linux-spezifisch ist.

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

Dies ist eine wichtige Annahme: Der Anmeldevorgang hat kein steuerndes TTY. Sie möchten wahrscheinlich überprüfen, ob Sie über ein kontrollierendes TTY verfügen, bevor Sie diesen Code ausführen (was je nach Ihren Anforderungen wahrscheinlich ohnehin eine sichere Sache ist).

Der Code durchläuft den Prozessbaum nach oben, bis er den Prozess findet, der kein steuerndes TTY hat. $initiator_nameDer Name dieses Prozesses (z. B. "sshd").

Christian Henry
quelle