26 votes

Comment déterminer si je suis connecté via SSH ?

Je suis en train de mettre en place une configuration bash assez complexe qui sera utilisée sur plusieurs machines. J'essaie de savoir s'il est possible de déterminer si je suis connecté via SSH ou sur une machine locale. De cette façon, je pourrais, par exemple, définir des alias en fonction de ce fait. Comme les alias halt a restart car arrêter un serveur distant n'est peut-être pas la meilleure chose à faire.

Ce que je sais jusqu'à présent, c'est que la variable d'environnement SSH_CLIENT est défini lorsque je me suis connecté via ssh. Malheureusement, cette variable est ignorée lorsque je lance un super utilisateur Shell avec sudo -s . Je sais aussi que je peux passer un paramètre à sudo qui demande à sudo de copier toutes mes variables d'environnement dans le nouvel environnement Shell, mais si je ne veux pas faire cela, y a-t-il un autre moyen ?

4voto

rhlee Points 141

Si vous voulez savoir si votre bash Shell est directement un processus enfant de sshd (pas n>1 couches profondes) vous pouvez

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

cela devrait vous donner sshd ou quel que soit le nom du processus parent de votre Shell actuel.

0 votes

Ne fonctionne pas pour sudo -s

0 votes

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

2voto

GmNoob Points 1435

J'ai trouvé ce qui suit, en me basant sur les conseils d'autres personnes ici.

Il utilise une variable pour la mise en cache - je l'utilise dans mon thème Shell.

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
}

Fuente: is_ssh en https://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63 .

2voto

Hans Deragon Points 113

Toutes les autres réponses fonctionnent si vous êtes au premier niveau de connexion. Mais si, une fois connecté, vous exécutez 'su' ou 'sudo' (dans mon cas, pour passer à un compte utilisateur sans Shell pour des raisons de sécurité, j'ai dû exécuter : sudo su - <userid> -s /bin/bash -l) leur solution échoue.

Voici une solution universelle ; en utilisant pstree, vous vérifiez si sshd est un parent.

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

Voici la sortie de l'egrep, quand --quiet est enlevé. Il montre toute la hiérarchie qui correspond si on est connecté à distance.

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

0 votes

C'est la bonne solution ! Simple et efficace dans toutes les conditions que j'ai essayées. Je vous remercie de votre attention.

2voto

hdante Points 101

Si vous êtes sur un système qui utilise logind, alors loginctl vous indiquera si la session est distante :

$ loginctl show-session $XDG_SESSION_ID -P Remote
yes

Cependant, il y a des cas où XDG_SESSION_ID n'est pas défini (y compris après sudo), donc j'ai écrit un script pour vérifier plus de choses. Il essaie loginctl, ssh, l'affichage X à distance et si tout échoue, se connecte à logind via D-Bus et tente de découvrir la session actuelle en utilisant le PID du processus actuel comme clé :

#!/usr/bin/env python3
from os import environ, getpid, system
from sys import argv, stderr

from dbus import SystemBus
from dbus.exceptions import DBusException

DEBUG=0

LOGIND = ('org.freedesktop.login1', '/org/freedesktop/login1')
MANAGER = '%s.Manager' % LOGIND[0]
SESSION = '%s.Session' % LOGIND[0]
SESSION_NOT_FOUND = '%s.NoSessionForPID' % LOGIND[0]
REMOTE = 'Remote'
LOGINCTL = 'loginctl show-session %s -P %s'
PROPERTIES = 'org.freedesktop.DBus.Properties'
DISPLAY = 'DISPLAY'
SSH='SSH_CLIENT'

def debug(msg):
    if DEBUG: print(msg, file=stderr)

def try_loginctl():
    debug('Trying loginctl...')
    try:
        r = system(LOGINCTL % (environ['XDG_SESSION_ID'], REMOTE))
        # exit early if loginctl prints the result by itself
        if r == 0: raise SystemExit
    except KeyError:
        pass

    return False

def try_ssh():
    debug('Trying ssh...')
    return bool(environ.get(SSH))

def try_x():
    debug('Trying X...')
    try:
        display = environ[DISPLAY]
        return ':' in display and len(display.split(':', 1)[0]) > 0
    except KeyError:
        return False

def try_dbus():
    debug('Trying dbus...')
    bus = SystemBus()
    logind = bus.get_object(*LOGIND)

    try:
        pid = getpid()
        session_path = logind.GetSessionByPID(pid, dbus_interface=MANAGER)
    except DBusException as e:
        if e.get_dbus_name() == SESSION_NOT_FOUND:
            return False
        else:
            raise

    session = bus.get_object(LOGIND[0], session_path)
    remote = session.Get(SESSION, REMOTE, dbus_interface=PROPERTIES)

    return bool(remote)

def main():
    global DEBUG

    if '-d' in argv or '--debug' in argv:
        DEBUG=1

    remote = try_loginctl() or try_ssh() or try_x() or try_dbus()
    print(remote and 'yes' or 'no')

main()

1voto

coderroggie Points 662

Veuillez garder à l'esprit que cette réponse est très.., très Spécifique à 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

Cela suppose une hypothèse clé : le processus de connexion ne disposera pas d'un TTY de contrôle ; vous voudrez probablement vérifier si vous ont un TTY de contrôle avant d'exécuter ce code (ce qui, en fonction de vos besoins, est probablement un pari sûr, de toute façon).

Le code itère vers le haut dans l'arbre des processus, jusqu'à ce qu'il trouve le processus qui n'a pas d'ATS de contrôle. $initiator_name sera le nom de ce processus ("sshd", par exemple).

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X