Como determinar se estou logado via SSH?


17

Atualmente, estou definindo uma configuração bash bastante complexa que deve ser usada em várias máquinas. 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 aliasing haltpara restartuma vez de 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é definida quando eu entrei no ssh. Infelizmente, essa variável é descartada quando inicio um shell de superusuário sudo -s. Eu também sei que posso passar um parâmetro para o sudo que instrui o sudo a copiar todas as minhas variáveis ​​de ambiente para o novo ambiente de shell, mas se eu não quiser fazer isso, existe outra maneira?

Respostas:


14

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


11
Faça palpites. Por exemplo, execute ps afxe o TTY do shell que não está sendo executado psserá o outro logon.
Warner

6
Use who am i.
Paul Tomblin

11
"uname -n" fornecerá o nome do host
Hubert Kario 5/10

11
A pergunta parece estar mais relacionada à sua extração who am i, para que você possa determinar a partir daí se está SSHing ou não. Isso funciona:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
blueyed

4
@PaulTomblin Na verdade, você pode usar whocom dois argumentos extras. who am ié o mesmo que who is meou who is awesomeou who potato potato. Um fato que achei um pouco interessante.
Kirkpatt

9

Aqui está uma ótima resposta que encontrei no unix.stackexchange :


  • Se uma das variáveis SSH_CLIENTou SSH_TTYfor 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

Não trabalho para sudo-s
Matt

6

Você pode adicionar SSH_*a env_keepno sudoersmodo que este pode ser detectado quando mudou para o outro usuário.


4

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

cat / proc / $ PPID / status | cabeça -1 | cut -f2

deve fornecer a você sshdou qualquer que seja o nome do processo pai do seu shell atual.


Não trabalho para sudo-s
Matt

ps -o cmd= $PPIDouawk '/^Name:/ {print $2}' /proc/$PPID/status
6/01/01

3

Eu acho que você quer repensar a maneira como está pensando no problema. A questão não é "Estou logado via SSH, porque quero desativar certos comandos". É "estou logado no console, porque habilitarei certos comandos".


3

Sim, como outros observaram, as informações estão 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

11
Também pode ser um nome de host.
blueyed

Não funciona se o nome do host contiver números.
YoYoYonnY

1

Eu vim com o seguinte, com base em dicas de outras pessoas aqui.

Ele usa uma variável para armazenamento em cache - eu 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_sshem https://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63 .


0

Procure o cmdline pai do seu shell e recorra. 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 fazê-lo realmente funcionar :)


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 teria que executar: sudo su - <userid> -s / bin / bash - l) , sua solução falha.

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

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 se uma estiver conectada remotamente.

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

0

Lembre-se de 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 importante: o processo de login não terá um TTY de controle; você provavelmente deseja verificar se possui um TTY de controle antes de executar este código (que, com base nos seus requisitos, provavelmente é uma aposta segura).

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.