Como determinar se estou logado via SSH?

15

Atualmente, estou configurando uma configuração bash bastante complexa, que deve ser usada em várias máquinas. Eu tento descobrir se é possível determinar se estou logado via SSH ou em uma máquina local. Dessa forma, eu poderia, por exemplo, definir alguns aliases dependendo desse fato. Como o aliasing halt to restart desde que parar um servidor remoto pode não ser a melhor coisa a fazer.

O que eu sei até agora é que a variável de ambiente SSH_CLIENT está definida quando eu efetuei login via ssh. Infelizmente, essa variável é descartada quando eu inicio um shell de superusuário com sudo -s . Eu também sei que posso passar um parâmetro para o sudo que instrui o sudo a copiar todas as variáveis do meu ambiente para o novo ambiente do shell, mas se eu não quiser fazer isso, existe outra maneira?

    
por t6d 05.10.2010 / 15:02

10 respostas

13

Você pode usar a saída de comando "w" ou "who". Quando você se conecta ao ssh, eles mostram seu IP de origem.

    
por 05.10.2010 / 15:15
9

Esta é uma ótima resposta que encontrei em unix.stackexchange :

  • Se uma das variáveis SSH_CLIENT ou SSH_TTY for definida, é uma sessão ssh.
  • O processo pai do shell de login pode ser verificado com ps -o comm= -p $PPID . Se for sshd , é uma sessão 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
    
por 09.05.2013 / 07:40
6

Você pode adicionar SSH_* a env_keep em sudoers para que isso possa ser detectado enquanto alternado para o outro usuário.

    
por 05.10.2010 / 15:06
4

Se você quiser saber se o bash shell é diretamente um processo filho de sshd (não n > 1 camadas de profundidade), você pode

cat /proc/$PPID/status | head -1 | cut -f2

deve dar a você sshd ou qualquer que seja o nome do processo pai do seu shell atual.

    
por 26.11.2011 / 19:50
3

Acho que você quer repensar o modo como está pensando no problema. A questão não é "estou logado via SSH, porque eu quero desligar certos comandos." É "eu estou logado no console, porque então eu vou ativar certos comandos."

    
por 05.10.2010 / 16:12
3

Sim, como outros notaram, a informação está na presença do seu IP entre parênteses na saída de who am i .

Você pode usar expressões regulares do Bash para detectá-lo:

if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
    
por 06.05.2011 / 16:11
1

Eu fiz o seguinte, baseado em dicas de outras pessoas aqui.

Ele usa uma variável para armazenar em cache - estou usando no meu 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
}

Fonte: is_ssh em link .

    
por 08.04.2011 / 00:52
0

Procure pelo cmdline pai do seu shell e recurse. Talvez algo como o seguinte:

#!/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:)

    
por 05.10.2010 / 17:58
0

Todas as outras respostas funcionam se você estiver no primeiro nível de login. Mas se, após o login, você executar 'su' ou 'sudo' (no meu caso, para alternar para uma conta de usuário sem shell por motivos de segurança, eu tive que executar: sudo su - < userid > -s / bin / bash -l) , sua solução falha.

A seguir, uma solução universal; usando o pstree, você verifica o sshd como pai / mãe.

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

Aqui está a saída do egrep, quando --quiet é removido. Ele mostra toda a hierarquia que corresponde a uma conectada remotamente.

   |            |-sshd(18599)---sshd(18603)---bash(18604)---sudo(18823)---bash(18824)-+-egrep(22417)
    
por 29.04.2016 / 18:54
0

Por favor, tenha em mente que esta resposta é muito, muito específica do 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

Isso faz uma suposição chave: o processo de login não terá um TTY de controle; você provavelmente quer verificar se você tem um TTY de controle antes de executar este código (o que, baseado em suas necessidades, provavelmente é uma aposta segura, de qualquer forma).

O código itera para cima através da árvore de processos, até encontrar o processo que não possui TTY de controle. $initiator_name será o nome desse processo ("sshd", por exemplo).

    
por 03.05.2016 / 19:23

Tags