it-swarm-ru.tech

Как я могу определить, управляется ли Shell из SSH?

Я хочу определить из сценария Shell (точнее, .zshrc), управляется ли он через SSH. Я пробовал переменную Host, но это всегда имя компьютера, на котором работает Shell. Могу ли я получить доступ к имени хоста, откуда идет сеанс SSH? Сравнение этих двух вопросов решило бы мою проблему.

Каждый раз, когда я вхожу, появляется сообщение с указанием времени последнего входа в систему и хоста:

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

Это означает, что сервер имеет эту информацию.

72
stribika

Вот критерии, которые я использую в своем ~/.profile:

  • Если одна из переменных SSH_CLIENT или SSH_TTY определено, это сессия ssh.
  • Если имя родительского процесса в оболочке входа в систему sshd, это сеанс 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

(Почему вы хотите проверить это в своей конфигурации Shell, а не при запуске сеанса?)

95
Gilles 'SO- stop being evil'

Вы должны быть в состоянии проверить через SSH_TTY, SSH_CONNECTION, или SSH_CLIENT переменные.

23
Cakemox

У меня просто была такая же проблема в Linux с использованием Bash. Сначала я использовал переменную окружения SSH_CONNECTION, но потом понял, что она не установлена, если вы su -.

Решение lastlog выше не работало ни после su, ни su -.

Наконец, я использую who am i, который показывает удаленный IP (или имя хоста) в конце, если это соединение SSH. Это также работает после su.

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

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

Если zsh не поддерживает регулярные выражения, то же самое может быть достигнуто разными способами с помощью grep, cut, sed или чего-либо еще.

Для любопытных, вот что я использую в root'е .bashrc:

    # 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

Альтернативой, которая также работает с su, будет рекурсивный поиск sshd через родительские процессы:

#!/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 $?

Если функция добавлена ​​в .bashrc, ее можно использовать как if is_ssh; then ...

10
mivk

Начните с изучения вашей среды и поиска правильного варианта

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

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

2
lfender6445