it-swarm.it

Come posso rilevare se Shell è controllato da SSH?

Voglio rilevare da uno script Shell (in particolare .zshrc) se è controllato tramite SSH. Ho provato la variabile Host ma è sempre il nome del computer su cui è in esecuzione Shell. Posso accedere al nome host da cui proviene la sessione SSH? Il confronto tra i due risolverebbe il mio problema.

Ogni volta che eseguo l'accesso, viene visualizzato un messaggio che indica l'ora dell'ultimo accesso e Host:

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

Questo significa che il server ha queste informazioni.

72
stribika

Ecco i criteri che utilizzo nel mio ~/.profile:

  • Se una delle variabili SSH_CLIENT o SSH_TTY è definito, è una sessione ssh.
  • Se il nome del processo parent della shell di login è sshd, è una sessione 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

(Perché dovresti testarlo nella configurazione di Shell anziché nell'avvio della sessione?)

Dovresti essere in grado di controllare tramite il SSH_TTY, SSH_CONNECTION, o SSH_CLIENT variabili.

23
Cakemox

Ho avuto lo stesso problema in Linux, usando Bash. Per prima cosa ho usato la variabile di ambiente SSH_CONNECTION, ma poi ho capito che non è impostato se su -.

La soluzione lastlog sopra non ha funzionato dopo su o su -.

Infine, sto usando who am i, che mostra l'IP remoto (o il nome host) alla fine se si tratta di una connessione SSH. Funziona anche dopo su.

Usando le espressioni regolari di Bash, funziona:

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

Se zsh non supporta le espressioni regolari, lo stesso può essere ottenuto in molti modi diversi con grep, cut, sed o quant'altro.

Per i curiosi, di seguito è quello per cui lo uso, nel .bashrc di 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

Un'alternativa che funziona anche con su sarebbe quella di cercare ricorsivamente sshd attraverso i processi padre:

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

Se la funzione viene aggiunta a .bashrc, può essere utilizzata come if is_ssh; then ...

10
mivk

Inizia dando un'occhiata al tuo ambiente e trova l'opzione giusta

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

È possibile agganciare molte di queste variabili d'ambiente per attivare azioni specifiche in base alla loro presenza.

2
lfender6445