4

Accessing the IP address of a connecting SSH client is possible via environment variables (such as SSH_CONNECTION), as described in

Find the IP address of the client in an SSH session

In a GNU screen session though, those environment variables are defined by whoever started the screen to begin with. Is there any way to also get hold of the SSH connection information, for someone who enters an already-existing screen session later, like from another host?

I can't think of a way to determine this, but this can be useful in cases where screen sessions are shared between different people, for example.

Community
  • 1
  • 1
weiresr
  • 650
  • 8
  • 13
  • There are several answers to the linked question, some involve things other than environment variables. – n. m. could be an AI May 29 '16 at 17:53
  • That may well be, but still leaves me wondering if there is a way to figure out who called a certain script in a screen session, esp. if the screen session is potentially shared by different people. – weiresr May 29 '16 at 18:24
  • You can traverse PPIDs of the current process up and look at their environment variables and standard handles (on Linux via `/proc`). – n. m. could be an AI May 29 '16 at 18:30
  • @n.m. - I still don't see how that would help me separate different clients. Let's assume that two clients (two users) are connected via SSH from different IPs, let's say as root, to the machine. If both are active in a given screen session (screen -x) here, and one of them invokes a script here - is there any way to tell which of them (i.e. by SSH client IP) actually did so? The PPIDs would be the same in that case. – weiresr May 29 '16 at 22:04
  • 2
    Um, no, that's not possible. It's like letting several people type on your keyboard, and then trying to determine who typed what. One could have typed `l` the other `s` and yet another one pressed enter, who has invoked `ls`? It's exactly the same with `screen`. – n. m. could be an AI May 29 '16 at 22:12
  • Alright, that's what I feared. Thought there might be a way around perhaps. Thanks for the input - feel free to put that into a full answer rather than a comment though, bounty earned :) – weiresr May 30 '16 at 13:50

5 Answers5

1

If the screen session is launched as root, you can but it won't be perfectly reliable

  1. If two users type in the same screen window, they will both interact within the same shell. One can write a command. The other can press the <enter> key.

  2. You have to get access to the environment variable SSH_CONNECTION (or better SSH_CLIENT) which is only possible if you are root, or if you use the same user inside the screen session.

Supposing you are root inside the screen session, you can know the last user active in a screen session by using the ps command and finding the last active session.

ps h -C screen katime -o pid,user

By using the pid, and accessing the /proc/<pid>/environ file, you can get the SSH_CLIENT variable.

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

--> SSH_CLIENT=257.31.120.12

All of this suppose that your screen is executed as root

You can also chose to log all the active connections. For such need, I would suggest you to store both the full list of connections and their last activity.

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

Note that you can also parse the result of the ps eh -C screen kstime -o args command if you find it easier.

EDIT:

This is a working Debian command to get all users currently connected to the same screen session:

 find /var/run/screen/
     -name $(pstree -sp $$ |sed 's/.*screen(\([0-9]*\)).*/\1/;q').*
     -printf "%h\n"
      | cut -f2 -d-
Adam
  • 17,838
  • 32
  • 54
  • Thanks for the effort put into this! As you said not working for 100% of the cases, but this way I can cover it well enough for the cases I'm interested in. – weiresr Jul 02 '16 at 12:46
0

You can check the output of the last command that would list of all IP addresses or hostnames of all connection made if sshd is the only way to connect to server.

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)

Alternatively (on Linux), you can check /var/log/secure where sshd will usually log all details of all the connections made even if they don't result in successful logins.

Amar Pratap
  • 1,000
  • 7
  • 20
  • This doesn't help me much for my problem so far. I have some scripts on the machine, that can be called by different people with SSH access (from different client IPs). When invoked, those scripts are logging who (as in: client IP) called them and when. To determine the client IP here, I'm using the information of SSH_CONNECTION - works fine unless screen sessions (esp. shared ones) are used. I'd like to know if there is a reliable way to know who called a script, from within a screen session (with potentially multiple people being logged in to it at a given time). – weiresr May 29 '16 at 18:30
  • @weiresr Interesting question but imo that's by design not possible. When you attach a screen session, you impersonate as the user who started the session (or better said, the program(s) in the session) - with all consequences. – hek2mgl Jun 05 '16 at 12:01
  • 1
    @hek2mgl Well one thing I saw recently is that you can get at least get a list of the attached displays in a screen (C-a :displays). Something like this could help somewhat in the direction that I was going for - but I don't know if scripted access to that information would be possible, and even then it can't tell me (by design) which one triggered a certain command, if multiple displays are currently attached. – weiresr Jun 05 '16 at 13:01
  • 1
    @weiresr I edited my own answer to add an example of how it could be achieved using `/var/run/screen` directory – Adam Jun 15 '16 at 19:24
0

If you're trying to support the multi-display mode ('screen -x'), then as someone said above you are likely out of luck.

One the other hand, if you could assume single-user mode, then you could create a wrapper/alias for the screen command that carries along an environment variable into screen (see 'screen -X stuff ...'); in this case you are just passing along SSH_CLIENT that will have the appropriate value.

If you can assume a given username comes from a single location (or, if more than one location, then simply choose most recent), then you can do some grep/sed on output of 'last' command.

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"
Alireza
  • 166
  • 7
  • Thanks for the input, but within a screen SSH_TTY (just like SSH_CONNECTION) gives me the value of whoever started the screen to begin with. So if I enter an existing screen from another SSH session again, I don't seem to get hold of the TTY I'm currently connected with either this way. – weiresr Jun 02 '16 at 21:37
  • You are correct. I'm not sure how to handle the multi-display case, but I put some thoughts on single-user mode in case it is applicable for you somehow. – Alireza Jun 03 '16 at 06:08
  • I was mostly interested in the screen -x scenario in general, since we often have multiple people in a given screen at the same time. Still interesting to get to know some more options here, thanks :) – weiresr Jun 05 '16 at 12:53
0

Check out SSHLog: https://github.com/sshlog/agent/

It's a daemon that monitors SSH logins as well as user activity. You can get a list of logged in users, which IP they're connecting from, log their commands, you can even jump into their session and share the terminal withthem.

Derrick Johnson
  • 377
  • 5
  • 9
-1

If your screen is starting usually in detached mode, then in your .screenrc, add the the following:

shell -$SHELL

Then your screen will have all the the variables. For currently running screens that you are stuck with, simply run.

source ~/.bash_profile

Replace the path and the file name to match your environment.

R J
  • 1,906
  • 1
  • 17
  • 15