Доступ к IP-адресу SSH-клиента в сеансе экрана

Доступ к IP-адресу подключающегося SSH-клиента возможен через переменные среды (такие как SSH_CONNECTION), как описано в

Найдите IP-адрес клиента в SSH сеанс

Однако в сеансе экрана GNU эти переменные среды определяются тем, кто запустил экран с самого начала. Есть ли способ также получить информацию о соединении SSH для тех, кто позже входит в уже существующий сеанс экрана, например, с другого хоста?

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


person weiresr    schedule 27.05.2016    source источник
comment
Есть несколько ответов на связанный вопрос, некоторые из которых связаны с другими вещами, кроме переменных среды.   -  person n. 1.8e9-where's-my-share m.    schedule 29.05.2016
comment
Это вполне может быть, но я все еще задаюсь вопросом, есть ли способ выяснить, кто вызвал определенный скрипт в сеансе экрана, особенно. если сеанс экрана потенциально используется разными людьми.   -  person weiresr    schedule 29.05.2016
comment
Вы можете просмотреть PPID текущего процесса и просмотреть их переменные среды и стандартные дескрипторы (в Linux через /proc).   -  person n. 1.8e9-where's-my-share m.    schedule 29.05.2016
comment
@н.м. - Я до сих пор не понимаю, как это поможет мне разделить разных клиентов. Предположим, что два клиента (два пользователя) подключены по SSH с разных IP-адресов, скажем, как root, к машине. Если оба активны в данном сеансе экрана (экран -x) здесь, и один из них вызывает здесь скрипт - есть ли способ определить, кто из них (т.е. по IP-адресу SSH-клиента) действительно это сделал? В этом случае PPID будут одинаковыми.   -  person weiresr    schedule 30.05.2016
comment
Эм, нет, это невозможно. Это как позволить нескольким людям печатать на вашей клавиатуре, а затем пытаться определить, кто что напечатал. Один мог набрать l другой s и еще один нажал Enter, кто вызвал ls? То же самое и с screen.   -  person n. 1.8e9-where's-my-share m.    schedule 30.05.2016
comment
Ладно, этого я и опасался. Думал, может быть, есть обходной путь. Спасибо за вклад - не стесняйтесь помещать это в полный ответ, а не в комментарий, вознаграждение заработано :)   -  person weiresr    schedule 30.05.2016


Ответы (4)


Если сеанс screen запущен с правами root, вы можете это сделать, но это не будет абсолютно надежно

  1. Если два пользователя вводят текст в одно и то же экранное окно, они оба будут взаимодействовать в одной и той же оболочке. Можно написать команду. Другой может нажать клавишу <enter>.

  2. Вы должны получить доступ к переменной среды SSH_CONNECTION (или лучше SSH_CLIENT), что возможно только в том случае, если вы являетесь пользователем root или если вы используете одного и того же пользователя внутри сеанса экрана.

Предположим, что вы являетесь пользователем root в сеансе экрана, вы можете узнать последнего пользователя, активного в сеансе экрана, используя команду ps и найдя последний активный сеанс.

ps h -C screen katime -o pid,user

Используя pid и получив доступ к файлу /proc/<pid>/environ, вы можете получить переменную SSH_CLIENT.

sed -z '/SSH_CLIENT/p;d' /proc/`ps h -C screen katime -o pid |head -1`/environ

--> SSH_CLIENT=257.31.120.12

Все это предполагает, что ваш экран выполняется как root

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

ps eh -C screen kstime -o pid,atime | while read pid stime; do echo -n "$stime: ";\
    gawk -v 'RS=\0' -F= '$1=="SSH_CLIENT" {print $2}' /proc/$pid/environ; done

Result:
00:00:00: 257.31.120.12 61608 22
00:07:11: 258.1.2.3.4 49947 22

Обратите внимание, что вы также можете проанализировать результат команды ps eh -C screen kstime -o args, если вам так проще.

ИЗМЕНИТЬ:

Это рабочая команда Debian для подключения всех пользователей к одному и тому же экранному сеансу:

 find /var/run/screen/
     -name $(pstree -sp $$ |sed 's/.*screen(\([0-9]*\)).*/\1/;q').*
     -printf "%h\n"
      | cut -f2 -d-
person Adam    schedule 09.06.2016
comment
Спасибо за приложенные к этому усилия! Как вы сказали, это не работает в 100% случаев, но таким образом я могу достаточно хорошо охватить интересующие меня случаи. - person weiresr; 02.07.2016

Вы можете проверить выходные данные команды last, в которой будет список всех IP addresses или hostnames всех подключений, если sshd — единственный способ подключения к серверу.

ec2-user]# last
ec2-user pts/0        115.250.185.183  Sun May 29 13:49   still logged in
ec2-user pts/0        115.250.140.241  Sat May 28 07:26 - 10:15  (02:48)
root     pts/4        113.21.68.105    Tue May  3 10:15 - 10:15  (00:00)

В качестве альтернативы (в Linux) вы можете проверить /var/log/secure, где sshd обычно регистрирует всю информацию обо всех установленных соединениях, даже если они не приводят к успешному входу в систему.

person Amar Pratap    schedule 29.05.2016
comment
Это пока не очень помогает мне в моей проблеме. У меня есть несколько сценариев на машине, которые могут вызываться разными людьми с доступом по SSH (с разных клиентских IP-адресов). При вызове эти сценарии регистрируют, кто (например, IP-адрес клиента) вызывал их и когда. Чтобы определить здесь IP-адрес клиента, я использую информацию SSH_CONNECTION — работает нормально, если не используются экранные сеансы (особенно общие). Я хотел бы знать, есть ли надежный способ узнать, кто вызвал сценарий, из сеанса экрана (с потенциально несколькими людьми, входящими в систему в данный момент времени). - person weiresr; 29.05.2016
comment
@weiresr Интересный вопрос, но по замыслу это невозможно. Когда вы прикрепляете сеанс экрана, вы выдаете себя за пользователя, который запустил сеанс (или, лучше сказать, за программу(ы) в сеансе) со всеми вытекающими последствиями. - person hek2mgl; 05.06.2016
comment
@hek2mgl hek2mgl Недавно я увидел, что вы можете получить хотя бы список подключенных дисплеев на экране (C-a :displays). Что-то вроде этого могло бы несколько помочь в том направлении, в котором я шел, но я не знаю, возможен ли скриптовый доступ к этой информации, и даже тогда он не может сказать мне (по замыслу), какой из них вызвал определенную команду , если в настоящее время подключено несколько дисплеев. - person weiresr; 05.06.2016
comment
@weiresr Я отредактировал свой собственный ответ, чтобы добавить пример того, как этого можно добиться, используя каталог /var/run/screen - person Adam; 15.06.2016

Если вы пытаетесь поддерживать режим нескольких дисплеев («экран -x»), то, как кто-то сказал выше, вам, вероятно, не повезло.

С другой стороны, если бы вы могли принять однопользовательский режим, вы могли бы создать оболочку/псевдоним для команды экрана, которая переносит переменную среды на экран (см. 'экран -X материал...'); в этом случае вы просто передаете SSH_CLIENT, который будет иметь соответствующее значение.

Если вы можете предположить, что данное имя пользователя происходит из одного места (или, если из нескольких мест, просто выберите самое последнее), то вы можете выполнить команду grep/sed при выводе команды «последняя».

client_ip=`last -ai | grep "still logged in" | grep "$USER " | grep -v '0.0.0.0' | tail -n 1 | sed 's/.* //g'`
echo "Hello $client_ip"
person Alireza    schedule 02.06.2016
comment
Спасибо за ввод, но на экране SSH_TTY (точно так же, как SSH_CONNECTION) дает мне значение того, кто начал экран с самого начала. Поэтому, если я снова войду в существующий экран из другого сеанса SSH, я, похоже, не смогу получить доступ к TTY, с которым я в настоящее время связан, ни одним из этих способов. - person weiresr; 03.06.2016
comment
Ты прав. Я не уверен, как обращаться с многоэкранным случаем, но я высказал некоторые мысли об однопользовательском режиме на случай, если он каким-то образом применим для вас. - person Alireza; 03.06.2016
comment
Меня больше всего интересовал сценарий screen -x в целом, поскольку у нас часто есть несколько человек на одном экране одновременно. Все еще интересно узнать еще некоторые варианты здесь, спасибо :) - person weiresr; 05.06.2016

Если ваш экран обычно запускается в автономном режиме, то в вашем .screenrc добавьте следующее:

shell -$SHELL

Тогда на вашем экране будут все переменные. Для текущих запущенных экранов, с которыми вы застряли, просто запустите.

source ~/.bash_profile

Замените путь и имя файла в соответствии с вашей средой.

person R J    schedule 02.01.2018