Come determinare se ho effettuato l'accesso tramite SSH?


17

Attualmente sto impostando una configurazione bash abbastanza complessa che deve essere utilizzata su più macchine. Provo a scoprire se è possibile determinare se ho effettuato l'accesso tramite SSH o su un computer locale. In questo modo, ad esempio, potrei impostare alcuni alias a seconda di quel fatto. Come aliasing haltper restartquanto l'arresto di un server remoto potrebbe non essere la cosa migliore da fare.

Quello che so finora è che la variabile d'ambiente SSH_CLIENTè impostata quando ho effettuato l'accesso tramite ssh. Sfortunatamente, questa variabile viene scartata quando avvio una shell super user con sudo -s. So anche che posso passare un parametro su sudo che indica a sudo di copiare tutte le mie variabili di ambiente nel nuovo ambiente di shell, ma se non voglio farlo, c'è un altro modo?

Risposte:


14

È possibile utilizzare l'output del comando "w" o "who". Quando ti connetti tramite ssh, mostreranno il tuo IP di origine.


1
Fai ipotesi colte. Ad esempio, esegui ps afxe il TTY per la shell non in esecuzione pssarà l'altro login.
Warner,

6
Usa who am i.
Paul Tomblin,

1
"uname -n" ti darà il nome host
Hubert Kario,

1
La domanda sembra essere più correlata per estrarla who am i, in modo che tu possa determinare da lì se stai SSHing o meno. Funziona così:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
blueyed

4
@PaulTomblin In realtà, puoi usarlo whocon due argomenti aggiuntivi. who am iè uguale a who is meo who is awesomeo who potato potato. Un fatto che ho trovato un po 'interessante.
Kirkpatt,

9

Ecco un'ottima risposta che ho trovato su unix.stackexchange :


  • Se una delle variabili SSH_CLIENTo SSH_TTYè definita, è una sessione ssh.
  • È possibile verificare il processo padre della shell di accesso ps -o comm= -p $PPID. Se lo è sshd, è una sessione 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

Non funziona per sudo -s
Matt

6

È possibile aggiungere SSH_*in env_keepin sudoersmodo che questo possa essere rilevato mentre si passa all'altro utente.


4

Se vuoi sapere se la tua shell bash è direttamente un processo figlio di sshd (non profondo n> 1 strati) puoi

cat / proc / $ PPID / status | testa -1 | taglia -f2

dovrebbe darti sshdo qualunque sia il nome del processo genitore della tua shell corrente.


Non funziona per sudo -s
Matt

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

3

Penso che tu voglia ripensare il modo in cui stai pensando al problema. La domanda non è "ho effettuato l'accesso tramite SSH, perché desidero disattivare determinati comandi". È "Sono collegato alla console, perché abiliterò determinati comandi".


3

Sì, come altri hanno notato, le informazioni sono in presenza del tuo IP tra parentesi nell'output di who am i.

Puoi usare le espressioni regolari di Bash per rilevarlo:

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

1
Può anche essere un nome host.
bluastra

Non funziona se il nome host contiene numeri.
YoYoYonnY,

1

Ho pensato a quanto segue, basandomi sui suggerimenti degli altri qui.

Usa una variabile per la memorizzazione nella cache: la sto usando nel mio tema 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
}

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


0

Cerca il cmdline principale della shell e il recurse. Forse qualcosa di simile al seguente:

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

Modificato per farlo funzionare davvero :)


0

Tutte le altre risposte funzionano se sei al primo livello di accesso. Ma se, una volta effettuato l'accesso, esegui 'su' o 'sudo' (nel mio caso, per passare a un account utente senza shell per motivi di sicurezza, ho dovuto eseguire: sudo su - <userid> -s / bin / bash - l) , la loro soluzione fallisce.

Di seguito è una soluzione universale; usando pstree, controlli sshd come genitore.

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

Ecco l'output di egrep, quando --quiet viene rimosso. Mostra l'intera gerarchia che corrisponde se si è connessi in remoto.

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

0

Tieni presente che questa risposta è molto, molto specifica per 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

Questo presuppone una chiave: il processo di accesso non avrà un TTY di controllo; probabilmente si desidera controllare se si dispone di un terminale di controllo prima di eseguire questo codice (che, in base alle tue esigenze, probabilmente è una scommessa sicura, in ogni caso).

Il codice scorre verso l'alto attraverso l'albero dei processi, finché non trova il processo che non ha TTY di controllo. $initiator_namesarà il nome di questo processo ("sshd", per esempio).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.