Como posso detectar se o shell é controlado pelo SSH?

56

Eu quero detectar de um script de shell (mais especificamente .zshrc) se ele é controlado por meio do SSH. Eu tentei a variável HOST, mas é sempre o nome do computador que está executando o shell. Posso acessar o nome do host de onde a sessão SSH está vindo? Comparar os dois resolveria o meu problema.

Sempre que faço login, há uma mensagem informando o último horário de login e o 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

Isso significa que o servidor tem essa informação.

    
por stribika 18.03.2011 / 23:19

5 respostas

76

Aqui estão os critérios que eu uso no meu ~/.profile :

  • Se uma das variáveis SSH_CLIENT ou SSH_TTY for definida, é uma sessão ssh.
  • Se o nome do processo pai do shell de login for sshd , é uma sessão 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

(Por que você gostaria de testar isso na sua configuração de shell, em vez de sua inicialização de sessão?)

    
por 18.03.2011 / 23:29
17

Você deve poder verificar pelas variáveis SSH_TTY , SSH_CONNECTION ou SSH_CLIENT .

    
por 18.03.2011 / 23:28
8

Acabei de ter o mesmo problema no Linux, usando o Bash. Eu usei pela primeira vez a variável de ambiente SSH_CONNECTION, mas percebi que ela não está definida se você su - .

A solução lastlog acima não funcionou depois de su ou su - .

Finalmente, estou usando who am i , que mostra o IP remoto (ou o nome do host) no final, se for uma conexão SSH. Também funciona depois do su.

Usando expressões regulares Bash, isso funciona:

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

Se o zsh não suporta expressões regulares, o mesmo pode ser alcançado de muitas maneiras diferentes com grep, cut, sed ou qualquer outra coisa.

Para os curiosos, abaixo está o que eu uso para isso, no .bashrc do 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

Uma alternativa que também funciona com su seria pesquisar recursivamente sshd por meio dos processos pai:

#!/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 a função for adicionada ao .bashrc, ela pode ser usada como if is_ssh; then ...

    
por 06.05.2011 / 20:19
7

Eu acho que as respostas de Gilles e Cakemox são boas, mas apenas por completude ...

Last login: Fri Mar 18 23:07:28 CET 2011 from max on pts/1

vem de pam_lastlog 1 .

Você pode imprimir pam_lastlog information usando o comando lastlog 2 , por exemplo

$ lastlog -u mikel  
Username         Port     From             Latest
mikel            tty1                      Fri Jan 28 10:58:10 +1100 2011

para um login local, comparado a

Username         Port     From             Latest
mikel            pts/9    mikel-laptop     Sat Mar 19 11:11:58 +1100 2011

para um login SSH.

No meu sistema, isso funciona para extraí-lo

$ lastlog -u mikel | sed -ne '2{p;q}' | cut -c 27-42
mikel-laptop 

last e w também podem ser úteis, por exemplo

$ TTY=$(tty)
$ last -n 1 ${TTY#/dev/} | sed -ne '1{p;q}'
mikel    pts/12       :0.0             Sat Mar 19 11:29   still logged in 

1 Linux / Documentação do FreeBSD para pam_lastlog .
2 Linux / FreeBSD lastlog(8) man pages.     
por 19.03.2011 / 01:14
0

Comece dando uma olhada no seu ambiente e encontre a opção certa

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

Você pode conectar-se a muitas dessas variáveis de ambiente para acionar ações específicas com base em sua presença.

    
por 27.03.2015 / 13:37