web-dev-qa-db-fra.com

Comment puis-je détecter si le shell est contrôlé à partir de SSH?

Je veux détecter à partir d'un script Shell (plus spécifiquement .zshrc) s'il est contrôlé via SSH. J'ai essayé la variable Host mais c'est toujours le nom de l'ordinateur qui exécute le Shell. Puis-je accéder au nom d'hôte d'où provient la session SSH? Comparer les deux résoudrait mon problème.

Chaque fois que je me connecte, il y a un message indiquant la dernière heure de connexion et l'hôte:

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

Cela signifie que le serveur dispose de ces informations.

72
stribika

Voici les critères que j'utilise dans mon ~/.profile:

  • Si l'une des variables SSH_CLIENT ou SSH_TTY est défini, c'est une session ssh.
  • Si le nom du processus parent du shell de connexion est sshd, il s'agit d'une session 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

(Pourquoi voudriez-vous tester cela dans votre configuration Shell plutôt que dans le démarrage de votre session?)

Vous devriez pouvoir vérifier via le SSH_TTY, SSH_CONNECTION, ou SSH_CLIENT variables.

23
Cakemox

Je viens d'avoir le même problème sous Linux, en utilisant Bash. J'ai d'abord utilisé la variable d'environnement SSH_CONNECTION, mais je me suis ensuite rendu compte qu'elle n'était pas définie si vous su -.

La solution lastlog ci-dessus n'a pas fonctionné après su ou su -.

Enfin, j'utilise who am i, qui montre l'IP distant (ou le nom d'hôte) à la fin s'il s'agit d'une connexion SSH. Il fonctionne également après su.

En utilisant des expressions régulières Bash, cela fonctionne:

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

Si zsh ne prend pas en charge les expressions régulières, la même chose peut être obtenue de différentes manières avec grep, cut, sed ou autre.

Pour les curieux, voici pourquoi j'utilise ceci, dans le .bashrc de root:

    # 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

Une alternative qui fonctionne également avec su serait de rechercher récursivement sshd via les processus parents:

#!/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 $?

Si la fonction est ajoutée à .bashrc, elle peut être utilisée comme if is_ssh; then ...

10
mivk

Commencez par jeter un œil à votre environnement et trouvez la bonne option

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

Vous pouvez vous connecter à plusieurs de ces variables d'environnement pour déclencher des actions spécifiques en fonction de leur présence.

2
lfender6445