¿Cómo determinar si estoy conectado a través de SSH?

17

Actualmente estoy configurando una configuración bash bastante compleja que se utilizará en varias máquinas. Intento averiguar si es posible determinar si he iniciado sesión a través de SSH o en una máquina local. De esta manera podría, por ejemplo, establecer algunos alias dependiendo de ese hecho. Al igual que el aliasing halta restartdesde que detuvo a un servidor remoto podría no ser la mejor cosa que hacer.

Lo que sé hasta ahora es que la variable de entorno SSH_CLIENTse establece cuando inicié sesión a través de ssh. Desafortunadamente, esta variable se descarta cuando inicio un shell de superusuario con sudo -s. También sé que puedo pasar un parámetro a sudo que le indica a sudo que copie todas mis variables de entorno al nuevo entorno de shell, pero si no quiero hacer esto, ¿hay alguna otra manera?

t6d
fuente

Respuestas:

14

Puede usar la salida de comando "w" o "who". Cuando te conectas a través de ssh, mostrarán tu IP de origen.

facha
fuente
1
Hacer conjeturas educadas. Por ejemplo, ejecutar ps afxy el TTY para el shell que no se ejecuta psserá el otro inicio de sesión.
Warner
66
Uso who am i.
Paul Tomblin,
1
"uname -n" le dará el nombre de host
Hubert Kario
1
La pregunta parece estar más relacionada con extraerlo who am i, para que pueda determinar a partir de ahí si está SSHing o no. Esto funciona:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
azulado
44
@PaulTomblin En realidad, puedes usarlo whocon dos argumentos adicionales. who am ies lo mismo que who is meor who is awesomeo who potato potato. Un hecho que me pareció un poco interesante.
kirkpatt
9

Aquí hay una gran respuesta que encontré en unix.stackexchange :


  • Si se define una de las variables SSH_CLIENTo SSH_TTY, es una sesión ssh.
  • El proceso principal del shell de inicio de sesión se puede verificar con ps -o comm= -p $PPID. Si es así sshd, es una sesión 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
fuente
No funciona para sudo -s
Matt
6

Se podría añadir SSH_*que env_keepen el sudoersmodo que esto puede ser detectado mientras se cambia a otro usuario.

Ignacio Vazquez-Abrams
fuente
4

Si desea saber si bash shell es directamente un proceso secundario de sshd (no n> 1 capas de profundidad) puede

cat / proc / $ PPID / estado | cabeza -1 | corte -f2

debería darte sshdo lo que sea el nombre del proceso padre de tu shell actual.

rhlee
fuente
No funciona para sudo -s
Matt
ps -o cmd= $PPIDoawk '/^Name:/ {print $2}' /proc/$PPID/status
Seis
3

Creo que quieres repensar la forma en que piensas el problema. La pregunta no es "¿He iniciado sesión a través de SSH, porque quiero desactivar ciertos comandos". Es "estoy conectado en la consola, porque entonces habilitaré ciertos comandos".

Andy Lester
fuente
3

Sí, como otros señalaron, la información está en presencia de su IP entre paréntesis en la salida de who am i.

Puede usar expresiones regulares de Bash para detectarlo:

if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
mivk
fuente
1
También puede ser un nombre de host.
azulado
No funciona si el nombre de host contiene números.
YoYoYonnY
1

Se me ocurrió lo siguiente, basado en consejos de otros aquí.

Utiliza una variable para el almacenamiento en caché: lo estoy usando en mi tema de 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_sshen https://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63 .

azulado
fuente
0

Busque el cmdline primario y la recurse de su shell. Tal vez algo como lo siguiente:

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

Editado para que realmente funcione :)

Justin
fuente
0

Todas las otras respuestas funcionan si está en el primer nivel de inicio de sesión. Pero si, una vez que inicias sesión, ejecutas 'su' o 'sudo' (en mi caso, para cambiar a una cuenta de usuario sin shell por razones de seguridad, tengo que ejecutar: sudo su - <userid> -s / bin / bash - l) , su solución falla.

Lo siguiente es una solución universal; usando pstree, verificas sshd como padre.

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

Aquí está la salida del egrep, cuando --quiet se elimina. Muestra toda la jerarquía que coincide si uno está conectado de forma remota.

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

Tenga en cuenta que esta respuesta es muy, muy específica de 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

Esto supone una suposición clave: el proceso de inicio de sesión no tendrá un TTY de control; probablemente desee comprobar si tiene un TTY de control antes de ejecutar este código (que, según sus requisitos, de todos modos es una apuesta segura).

El código itera hacia arriba a través del árbol de procesos, hasta que encuentra el proceso que no tiene TTY de control. $initiator_nameserá el nombre de este proceso ("sshd", por ejemplo).

Christian Henry
fuente