Find the IP address of the client in an SSH session
Asked Answered
U

20

224

I have a script that is to be run by a person that logs in to the server with SSH.

Is there a way to find out automatically what IP address the user is connecting from?

Of course, I could ask the user (it is a tool for programmers, so no problem with that), but it would be cooler if I just found out.

Ute answered 15/6, 2009 at 13:50 Comment(1)
propose moving to serverfault, still great question thoughRheumy
T
356

Check if there is an environment variable called:

$SSH_CLIENT

OR

$SSH_CONNECTION

(or any other environment variables) which gets set when the user logs in. Then process it using the user login script.

Extract the IP:

$ echo $SSH_CLIENT | awk '{ print $1}'
1.2.3.4
$ echo $SSH_CONNECTION | awk '{print $1}'
1.2.3.4
Transient answered 15/6, 2009 at 14:1 Comment(8)
@cwd i want to replace the ip in this command "iptables -A INPUT -s 93.203.118.251 -p tcp --destination-port 443 -j DROP" is that possible?Kalli
This was REMOTEHOST for me.Grippe
only works with non-sudoed users. e.g. if you have an ssh user and then escalate to root, a new shell is created and these variables are lost, unless you can trace back through the tree to find the original ssh pid and get the variables from /proc/$PID/environDiacritic
thanks to https://mcmap.net/q/14333/-extract-substring-in-bash this answer can be improved to simply ${SSH_CLIENT%% *}Verdha
@Diacritic look into sudo -EVerdha
Had to use echo $SSH_CONNECTION | awk '{print $3}'Shipshape
This is my go to for finding all env vars with a certain substring env | grep SSH | sortDolorous
Sometimes, it won't work if there was a network reconnection and IP address changed, but an actual SSH session stayed alive, for example. It may return a previous(old) IP address. Consider trying using who instead.Tirza
T
134

You could use the command:

server:~# pinky

that will give to you somehting like this:

Login      Name                 TTY    Idle   When                 Where 

root       root                 pts/0         2009-06-15 13:41     192.168.1.133
Tutelary answered 15/6, 2009 at 16:38 Comment(4)
That's awesome :-) Nerd humour ftw once again. According to pinky --help: A lightweight 'finger' program; print user information. The utmp file will be /var/run/utmp.Manualmanubrium
Why is it the my 'Where' in my output only shows the machine name and not the ip address?Yunyunfei
Probably you got the nameserver configurated in your machine.Tutelary
pinky will show all logged in users, not just yourselfDiacritic
E
41

Try the following to get just the IP address:

who am i|awk '{ print $5}'
Exacerbate answered 19/12, 2011 at 22:21 Comment(6)
pretty sure if you write whoami and you will get the name of the logged in user. there's no fifth thing or ip to print sorry. but whoami is a useful commandLawford
who am i != whoami on my Linux at least. There is a fifth thing, and it is the host name of the client.Wallen
For anyone else wondering about who am i: The manpage for who says: If ARG1 ARG2 given, -m presumed: 'am i' or 'mom likes' are usual.. So really anything with two words works, also things like who likes icecream.Paradigm
Building on this answer, I reduced it to who -m --ips|awk '{print $5}' so that I had only IP and no reverse-dns answer. Thanks for the help on who am i!Rumpus
Some output may look like admin pts/0 Sep 30 13:20 1.1.1.1, so this better be date-format-independentRitualism
Fails with tmux: who am i|awk '{ print $5}' (tmux(2445).%3)Metalwork
R
23

Just type the following command on your Linux machine:

who
Relative answered 30/9, 2014 at 9:40 Comment(0)
S
14
who | cut -d"(" -f2 |cut -d")" -f1
Swetiana answered 5/6, 2018 at 15:19 Comment(0)
G
6

Improving on a prior answer. Gives ip address instead of hostname. --ips not available on OS X.

who am i --ips|awk '{print $5}' #ubuntu 14

more universal, change $5 to $6 for OS X 10.11:

WORKSTATION=`who -m|awk '{print $5}'|sed 's/[()]//g'`
WORKSTATION_IP=`dig +short $WORKSTATION`
if [[ -z "$WORKSTATION_IP" ]]; then WORKSTATION_IP="$WORKSTATION"; fi
echo $WORKSTATION_IP
Gomar answered 24/10, 2015 at 18:9 Comment(0)
W
6

A simple command to get a list of recent users logged in to the machine is last. This is ordered most recent first, so last | head -n 1 will show the last login. This may not be the currently logged in user though.

Sample output:

root     pts/0        192.168.243.99   Mon Jun  7 15:07   still logged in   
admin    pts/0        192.168.243.17   Mon Jun  7 15:06 - 15:07  (00:00)    
root     pts/0        192.168.243.99   Mon Jun  7 15:02 - 15:06  (00:03)    
root     pts/0        192.168.243.99   Mon Jun  7 15:01 - 15:02  (00:00)    
root     pts/0        192.168.243.99   Mon Jun  7 13:45 - 14:12  (00:27)    
root     pts/0        192.168.243.99   Mon May 31 11:20 - 12:35  (01:15)    
...
Washrag answered 5/10, 2017 at 7:23 Comment(0)
A
5
who am i | awk '{print $5}' | sed 's/[()]//g' | cut -f1 -d "." | sed 's/-/./g'


export DISPLAY=`who am i | awk '{print $5}' | sed 's/[()]//g' | cut -f1 -d "." | sed 's/-/./g'`:0.0

I use this to determine my DISPLAY variable for the session when logging in via ssh and need to display remote X.

Arela answered 6/12, 2013 at 6:5 Comment(1)
Useful one liner to add my IP to .htaccess files. Thank you. I've made a modification for FreeBSD: who am i | awk '{print $6}' | sed 's/[()]//g' | sed 's/\./\\./g' The last part escapes the dots.Nonego
P
4
netstat -tapen | grep ssh | awk '{ print $4}'
Parody answered 3/9, 2013 at 7:19 Comment(3)
doesn't work on CentOS 6.9 (net-tools 1.60 netstat 1.42) (No info could be read for "-p": geteuid()=507 but you should be root.)Verdha
@Verdha does sudo ss -tapen | grep ssh | awk '{ print $4}'|grep -v ':22$' work?Metalwork
That doesn't quite work for me, had to use netstat -tapen | grep -F :22 | grep ESTABLISHEDFaithfaithful
W
2

You can get it in a programmatic way via an SSH library (https://code.google.com/p/sshxcute)

public static String getIpAddress() throws TaskExecFailException{
    ConnBean cb = new ConnBean(host, username, password);
    SSHExec ssh = SSHExec.getInstance(cb);
    ssh.connect();
    CustomTask sampleTask = new ExecCommand("echo \"${SSH_CLIENT%% *}\"");
    String Result = ssh.exec(sampleTask).sysout;
    ssh.disconnect();   
    return Result;
}
Wane answered 28/6, 2014 at 5:27 Comment(0)
D
2

an older thread with a lot of answers, but none are quite what i was looking for, so i'm contributing mine:

sshpid=$$
sshloop=0
while [ "$sshloop" = "0" ]; do
        if [ "$(strings /proc/${sshpid}/environ | grep ^SSH_CLIENT)" ];
then
                read sshClientIP sshClientSport sshClientDport <<< $(strings /proc/${sshpid}/environ | grep ^SSH_CLIENT | cut -d= -f2)
                sshloop=1
        else
                sshpid=$(cat /proc/${sshpid}/status | grep PPid | awk '{print $2}')
                [ "$sshpid" = "0" ] && sshClientIP="localhost" && sshloop=1
        fi
done

this method is compatible with direct ssh, sudoed users, and screen sessions. it will trail up through the process tree until it finds a pid with the SSH_CLIENT variable, then record its IP as $sshClientIP. if it gets too far up the tree, it will record the IP as 'localhost' and leave the loop.

Diacritic answered 1/6, 2017 at 16:28 Comment(0)
O
2

I'm getting the following output from who -m --ips on Debian 10:

root pts/0 Dec 4 06:45 123.123.123.123

Looks like a new column was added, so {print $5} or "take 5th column" attempts don't work anymore.

Try this:

who -m --ips | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'

Source:

Outstay answered 4/12, 2019 at 11:50 Comment(0)
L
1
netstat -tapen | grep ssh | awk '{ print $10}'

Output:

two # in my experiment

netstat -tapen | grep ssh | awk '{ print $4}' 

gives the IP address.

Output:

127.0.0.1:22 # in my experiment

But the results are mixed with other users and stuff. It needs more work.

Lawford answered 4/11, 2013 at 16:15 Comment(1)
my netstat only gives a truncated address for IPv6 and "127.0.0.1:22" is the server rather than the client, (which was specified in the question.)Metalwork
L
0

Assuming he opens an interactive session (that is, allocates a pseudo terminal) and you have access to stdin, you can call an ioctl on that device to get the device number (/dev/pts/4711) and try to find that one in /var/run/utmp (where there will also be the username and the IP address the connection originated from).

Luanneluanni answered 15/6, 2009 at 14:2 Comment(0)
N
0

There could be a race condition, but this solution works as an ssh command. All the other solutions shown here require an ssh login.

$ ssh {host} last -1 | head -1 | awk '{print $3}'

Notochord answered 14/11, 2023 at 15:40 Comment(0)
B
-1

Usually there is a log entry in /var/log/messages (or similar, depending on your OS) which you could grep with the username.

Buzzer answered 15/6, 2009 at 13:56 Comment(0)
P
-1

netstat will work (at the top something like this) tcp 0 0 10.x.xx.xx:ssh someipaddress.or.domainame:9379 ESTABLISHED

Pickett answered 12/12, 2011 at 20:0 Comment(2)
Thank you SO much for this answer, I ended up doing 'netstat | grep ssh'.Thou
For security reasons this is bad because anybody could be connected to that port, not just you.Hypoderma
S
-1

Linux: who am i | awk '{print $5}' | sed 's/[()]//g'

AIX: who am i | awk '{print $6}' | sed 's/[()]//g'

Soredium answered 31/5, 2013 at 10:55 Comment(0)
S
-1

Search for SSH connections for "myusername" account;

Take first result string;

Take 5th column;

Split by ":" and return 1st part (port number don't needed, we want just IP):

netstat -tapen | grep "sshd: myusername" | head -n1 | awk '{split($5, a, ":"); print a[1]}'


Another way:

who am i | awk '{l = length($5) - 2; print substr($5, 2, l)}'

Supervise answered 14/8, 2014 at 5:17 Comment(1)
sudo ss -tapen | grep "sshd: $(whoami)"|head -n1|awk '{split($5, a, ":"); print a[1]}' says my ssh client is from 2a02 and your "Another way:" says tmux(2445).%3Metalwork
A
-1

One thumb up for @Nikhil Katre's answer :

Simplest command to get the last 10 users logged in to the machine is last|head.

To get all the users simply use last command

The one using who or pinky did what is basically asked. But But But they don't give historical sessions info.

Which might also be interesting if you want to know someone who has just logged in and logged out already when you start this checking.

if it is a multiuser system. I recommand add the user account you are looking for:

last | grep $USER | head

EDIT:

In my case, both $SSH_CLIENT and $SSH_CONNECTION do not exist.

Ansermet answered 28/8, 2018 at 21:19 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.