Как определить, залогинен ли я через SSH?

17

В настоящее время я настраиваю довольно сложную конфигурацию bash, которая будет использоваться на нескольких машинах. Я пытаюсь выяснить, возможно ли определить, вошел ли я через SSH или на локальный компьютер. Таким образом, я мог бы, например, установить псевдонимы в зависимости от этого факта. Как альясинг haltк restartтак остановить удаленный сервер не может быть лучше всего сделать.

До сих пор я знаю, что переменная окружения SSH_CLIENTустанавливается, когда я захожу через ssh. К сожалению, эта переменная отбрасывается, когда я запускаю оболочку суперпользователя sudo -s. Я также знаю, что могу передать в sudo параметр, который инструктирует sudo скопировать все мои переменные среды в новую среду оболочки, но если я не хочу этого делать, есть ли другой способ?

t6d
источник

Ответы:

14

Вы можете использовать вывод команды «w» или «who». Когда вы подключитесь через ssh, они покажут ваш исходный IP.

Facha
источник
1
Делайте обоснованные догадки. Например, запустите, ps afxи TTY для неработающей оболочки psбудет другим логином.
Уорнер
6
Использование who am i.
Пол Томблин
1
"uname -n" даст вам имя хоста
Hubert Kario
1
Похоже, что вопрос больше связан с его извлечением who am i, так что вы можете оттуда определить, являетесь ли вы SSHing или нет. Это работает:hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:)
синеватый
4
@PaulTomblin На самом деле, вы можете использовать whoлюбые два дополнительных аргумента. who am iтакой же как who is meили who is awesomeили или who potato potato. Факт, который я нашел немного интересным.
kirkpatt
9

Вот отличный ответ, который я нашел на unix.stackexchange :


  • Если одна из переменных SSH_CLIENTили SSH_TTYопределена, это ssh-сессия.
  • Родительский процесс оболочки входа можно проверить с помощью ps -o comm= -p $PPID. Если это так sshd, это сессия 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
Николь
источник
Не работает для sudo -s
Мэтт
6

Вы можете добавить SSH_*к env_keepв , sudoersтак что это может быть обнаружено во время переключился на другой пользователь.

Игнасио Васкес-Абрамс
источник
4

Если вы хотите узнать, является ли ваша оболочка bash напрямую дочерним процессом sshd (не n> 1 уровня), вы можете

cat / proc / $ PPID / status | голова -1 | cut -f2

он должен дать вам sshdили как называется имя родительского процесса вашей текущей оболочки.

rhlee
источник
Не работает для sudo -s
Мэтт
ps -o cmd= $PPIDилиawk '/^Name:/ {print $2}' /proc/$PPID/status
шесть
3

Я думаю, что вы хотите переосмыслить то, как вы думаете о проблеме. Вопрос не в том, «вошел ли я через SSH, потому что хочу отключить определенные команды». Это «Я вошел в систему с консоли, потому что тогда я включу определенные команды».

Энди Лестер
источник
3

Да, как отмечали другие, информация указана в скобках при выводе вашего IP who am i.

Вы можете использовать регулярные выражения Bash, чтобы обнаружить это:

if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
mivk
источник
1
Это также может быть имя хоста.
синеватый
Не работает, если имя хоста содержит числа.
YoYoYonnY
1

Я придумал следующее, основываясь на советах других здесь.

Он использует переменную для кэширования - я использую ее в своей теме оболочки.

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
}

Источник: is_sshв https://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63 .

blueyed
источник
0

Найдите родительский cmdline вашей оболочки и введите его. Может быть что-то вроде следующего:

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

Отредактировано, чтобы заставить это фактически работать :)

Джастин
источник
0

Все остальные ответы работают, если вы находитесь на первом уровне входа в систему. Но если после входа в систему вы запускаете 'su' или 'sudo' (в моем случае, чтобы переключиться на учетную запись пользователя без оболочки по соображениям безопасности, мне нужно было выполнить: sudo su - <userid> -s / bin / bash - л) , их решение не удалось.

Следующее является универсальным решением; используя pstree, вы проверяете sshd как родитель.

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

Вот вывод egrep, когда --quiet удален. Он показывает всю иерархию, которая соответствует, если один подключен удаленно.

   |            |-sshd(18599)---sshd(18603)---bash(18604)---sudo(18823)---bash(18824)-+-egrep(22417)
Ханс Дерагон
источник
0

Пожалуйста, имейте в виду, что этот ответ очень специфичен для 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

Это делает ключевое предположение: у процесса входа в систему не будет контрольного TTY; Вы , вероятно , хотите , чтобы проверить , если у вас есть контрольный TTY перед запуском этого кода (который, основываясь на ваши требования, вероятно , является безопасным выбором, так или иначе).

Код выполняет итерацию вверх по дереву процессов, пока не найдет процесс, который не имеет управляющего TTY. $initiator_nameбудет именем этого процесса (например, "sshd").

Кристиан Генри
источник