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


17

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 certains alias en fonction de ce fait. Comme aliasing haltà restartdepuis l' arrêt d' un serveur distant pourrait ne pas être la meilleure chose à faire.

Ce que je sais jusqu'à présent, c'est que la variable d'environnement SSH_CLIENTest définie lorsque je me suis connecté via ssh. Malheureusement, cette variable est ignorée lorsque je démarre un shell super utilisateur avec sudo -s. Je sais également que je peux transmettre à sudo un paramètre qui demande à sudo de copier toutes mes variables d'environnement dans le nouvel environnement shell, mais si je ne veux pas le faire, y a-t-il une autre façon?

Réponses:


14

Vous pouvez utiliser la sortie de commande "w" ou "who". Lorsque vous vous connectez via ssh, ils afficheront votre IP source.


1
Faites des suppositions éclairées. Par exemple, exécutez ps afxet le TTY pour le shell qui ne fonctionne pas pssera l'autre connexion.
Warner

6
Utilisez who am i.
Paul Tomblin

1
"uname -n" vous donnera le nom d'hôte
Hubert Kario

1
La question semble être plus liée à son extraction who am i, afin que vous puissiez déterminer à partir de là si vous êtes SSHing ou non. Cela fonctionne:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
blueyed

4
@PaulTomblin En fait, vous pouvez utiliser whoavec deux arguments supplémentaires. who am iest identique à who is meou who is awesomeou who potato potato. Un fait que j'ai trouvé un peu intéressant.
kirkpatt

9

Voici une excellente réponse que j'ai trouvée sur unix.stackexchange :


  • Si l'une des variables SSH_CLIENTou SSH_TTYest définie, c'est une session ssh.
  • Le processus parent du shell de connexion peut être vérifié avec ps -o comm= -p $PPID. Si c'est le cas sshd, c'est une session 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

Ne fonctionne pas pour sudo -s
Matt

6

Vous pouvez ajouter SSH_*à env_keepen sudoerssorte que cela peut être détecté lors commuté à l'autre utilisateur.


4

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

cat / proc / $ PPID / status | tête -1 | coupe -f2

il doit vous donner sshdou quel que soit le nom du processus parent de votre shell actuel.


Ne fonctionne pas pour sudo -s
Matt

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

3

Je pense que vous voulez repenser la façon dont vous envisagez le problème. La question n'est pas "suis-je connecté via SSH, car je veux désactiver certaines commandes." C'est "suis-je connecté à la console, car alors j'activerai certaines commandes."


3

Oui, comme d'autres l'ont noté, les informations sont en présence de votre IP entre parenthèses dans la sortie de who am i.

Vous pouvez utiliser des expressions régulières Bash pour le détecter:

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

1
Il peut également s'agir d'un nom d'hôte.
blueyed

Ne fonctionne pas si le nom d'hôte contient des nombres.
YoYoYonnY

1

J'ai trouvé ce qui suit, basé sur les conseils des autres 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
}

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


0

Recherchez la ligne de commande parent de votre shell et recurse. Peut-être quelque chose comme ceci:

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

Modifié pour que cela fonctionne réellement :)


0

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 basculer vers un compte utilisateur sans shell pour des raisons de sécurité, je devais exécuter: sudo su - <userid> -s / bin / bash - l) , leur solution échoue.

Voici une solution universelle; en utilisant pstree, vous vérifiez sshd en tant que 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, lorsque --quiet est supprimé. Il montre toute la hiérarchie qui correspond si l'on est connecté à distance.

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

0

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 fait une hypothèse clé: le processus de connexion n'aura pas de TTY de contrôle; vous voulez probablement vérifier si vous avez un ATS de contrôle avant d'exécuter ce code (qui, selon vos besoins, est probablement une valeur sûre, de toute façon).

Le code itère vers le haut dans l'arborescence des processus, jusqu'à ce qu'il trouve le processus qui n'a pas de téléscripteur de contrôle. $initiator_namesera le nom de ce processus ("sshd", par exemple).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.