7

I am trying to find out the current ssh session's originating IP address. I found the following to be useful, but it requires sudo:

$ sudo netstat -tapen | grep ssh | awk '{ print $5}' | sed '/0.0.0.0\|::/d'
192.168.1.1:60119
99.xxx.xxx.xxx:1213

Is there a way to get the 99.xxx.xxx.xxx information without a call to sudo?

(Answered! Question #1: How is it that piping to grep returns only the error?)

Question #2: Are there workarounds for getting WAN information with netstat? or...

Question #3: Are there better options for my goal?

2
  • 1
    conky gets it with ${tcp_portmon 22 22 rip 0} if that is any help. I have conky set up to display the # of SSH connections and their ip addresses. Apr 14, 2015 at 1:32
  • Do you want to see information about all currently existing SSH sessions on the machine, or do you want to see information about just the SSH session that you are using to run the command? May 11, 2015 at 0:04

4 Answers 4

16

You can use the SSH_CONNECTION and SSH_CLIENT variables:

$ echo $SSH_CONNECTION 
10.0.0.1 42276 10.0.0.2 22
$ echo $SSH_CLIENT    
10.0.0.1 42276 22
$ SSH_IP=${SSH_CONNECTION%% *}
$ echo $SSH_IP
10.0.0.1

From man 1 ssh:

 SSH_CONNECTION        Identifies the client and server ends of the
                       connection.  The variable contains four space-
                       separated values: client IP address, client port
                       number, server IP address, and server port number.

You can access each entry in SSH_CONNECTION more easily if you split it into a bash array:

ssh_details=($SSH_CONNECTION)

Then you can get each entry using its index:

$ echo $SSH_CONNECTION 
127.0.0.1 55719 127.0.0.1 22
$ ssh_details=($SSH_CONNECTION)
$ echo ${ssh_details[0]}
127.0.0.1
$ echo ${ssh_details[1]}
55719
$ printf "You are logging in from host IP %s from port # %d\n" ${ssh_details[0]} ${ssh_details[1]}
You are logging in from host IP 127.0.0.1 from port # 55719

For some reason, SSH_CLIENT is not documented in the English manpages.

6
  • Can I please ask for a bit of your time explaining to me how I can print You are logging in from host IP 111.111.111.111 from port # 49999 out of echo $SSH_CONNECTION results...?
    – Tfb9
    May 10, 2015 at 21:34
  • 1
    @Tfb9 see update.
    – muru
    May 10, 2015 at 21:46
  • This is great - I was expecting to deal with a sed command of some sort and I have now learned about a new way to do arrays, and some other grouping mecanism I'll now have to look into. Thank you, really!
    – Tfb9
    May 10, 2015 at 21:52
  • If I may, a comment to your update/example. I do not think there is any way that echo ${ssh_details[0]} answers verbatim, specifically, 127.0.0.1... I get a null string from a local terminal.
    – Tfb9
    May 10, 2015 at 22:28
  • @Tfb9 it may or may not be 127.0.0.1. My example was from ssh localhost. Obviously your own maybe something else.
    – muru
    May 10, 2015 at 23:03
8

Answer to 1 & 2:

The warning is from netstat, not from grep and its about the PID/Program name column of the netstat output:

$ netstat -tapen
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name

Using sudo:

$ sudo netstat -tapen
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name

The alert is self explanatory, you have to be root to view the process IDs and program names owned by other (all) users, otherwise you will only get the PID/names of programs owned by you although you will get the open socket listings for those processes.

The distinction is basically summed up by the following, from man netstat:

   PID/Program name
       Slash-separated pair of the process id (PID) and process name of
the process that owns the socket.  --program causes this column  to
be  included. You will also need superuser privileges to see this  
information on sockets you don't own. This identification information is  
not yet available for IPX sockets.

In you case, the program sshd is owned by root, so without using sudo all the socket info will appear in the output, not the program name and PID. As a result while using grep on the result of netstat -taepn you are getting the warning.

On the other hand if you use sudo, the PID/program name will appear in the netstat -taepn output and you can use grep to find the output.

The following will make you more clear (check the last column(PID/Program name)):

$ netstat -tapen
                                                        PID/Program name
tcp  0  0 0.0.0.0:22  0.0.0.0:* LISTEN  0   11088       -               

$sudo netstat -taepn
tcp  0  0 0.0.0.0:22  0.0.0.0:* LISTEN  0   11088       1002/sshd       

If you are running this from a client machine then you can just ignore it as the process in that case will be ssh (not sshd) and will be owned by you.

Answer to 3:

There are so many ways. I will add a few:

$ sudo netstat -taepn | grep "ssh" | tr -s ' ' | cut -d' ' -f4 | head -1
192.168.5.3:22

$ sudo netstat -taepn | grep -Po "\b(\d|\.)+:22(?= .*ssh)"
192.168.5.3:22

$ sudo netstat -taepn | sed -nr '/ssh/s/.* ([^:]+:22) .*/\1/p'
192.168.5.3:22

EDIT: Without sudo:

$ netstat -taepn 2>/dev/null | grep ":22 " | tr -s ' ' | cut -d' ' -f4 | head -1
192.168.5.3:22

$ netstat -taepn 2>/dev/null | grep -Po "\b(\d|\.)+:22\b"
192.168.5.3:22

$ netstat -taepn 2>/dev/null | sed -nr '/:22 /s/.* ([^:]+:22) .*/\1/p'
192.168.5.3:22

EDIT 2:

If you want to get the remote IP address connected to port 22 (ssh) of the server without using sudo, your best best would be to read the socket statistics via ss command and get the desired output from that.

$ ss -ant | grep -Po "(\d|\.)+:22\s+\K[^:]+"
192.168.6.4

$ ss -ant | sed -nr 's/.*([0-9]|\.)+:22 +([^:]+).*/\2/p'
192.168.6.4

$ ss -ant | grep -e "ESTAB" | grep ":22" | tr -s ' ' | cut -d' ' -f5 | cut -d':' -f1
192.168.6.4

We have run the above commands in the server and 192.168.6.4 is the IP address of the remote computer connected to the server via ssh on port 22.

10
  • My system appears to behave different than yours. 'netstat -tapen', without sudo, returns 20 lines worth of results (from a fresh terminal); I can see the information without being superuser. Only if I pipe to 'grep' do I get the error.
    – Tfb9
    Apr 13, 2015 at 23:12
  • Its about the PID/Program name column of the output..without sudo sshd program name will not appear there hence the warning..check my edits
    – heemayl
    Apr 13, 2015 at 23:16
  • Oh, I see - thanks. Totally missed the warning and concentrated on the results. It is now dawning on me that the message was a stderr (or whatever) output from netstat, and that grep results are null when calling netstat without sudo. That takes care of Question #1!
    – Tfb9
    Apr 13, 2015 at 23:23
  • Thanks for your answers but regarding #3, the calls you show all go through sudo. I edited to ask 'without a call to sudo', and do not know if that is even possible now.
    – Tfb9
    Apr 14, 2015 at 0:05
  • 1
    @Tfb9: Check my Edit 2
    – heemayl
    Apr 14, 2015 at 10:59
0

The line is bellogs to error output, i.e. sterr. You could get rid of it with

netstat -tapen 2> /dev/null | grep ssh

For reference check this

enter image description here

As properly noted by heemayl , without sudo, netstat won't report that connection is established by the ssh server, only if it's established by ssh client.

Of course, you can still determine it by port number or using who -a utility, which will show logins and address, but it's not a guarantee somebody isn't logged in via telnet or remote desktop application.

5
  • Note, that the output has nothing at all to do with grep Apr 13, 2015 at 23:33
  • This is wrong..without sudo the program name sshd will not be printed..
    – heemayl
    Apr 13, 2015 at 23:41
  • @heemayl look at my screenshot there. I have ssh connection open. cat /etc/shadow proves that at that moment i dont have sudo working, on next line I have netstat -tapen 2> /dev/null | grep ssh and it shows. So . . . I guess it does work, doesn't it ? Apr 13, 2015 at 23:45
  • Thats your ssh client, not ssh daemon..
    – heemayl
    Apr 13, 2015 at 23:47
  • Sigh . . . true that. OK, I'll edit my answer . . . The user can still see it by port number though, right ? Apr 14, 2015 at 2:03
0

Before reading on to read the SSH_CLIENT answer (it was that simple you know), you could also do:

pid=$(ps -xh -o pid,cmd | grep [s]shd | awk '{print $1}' | head -1) 
cat /proc/$pid/net/tcp | while read a b c d e; do echo $b $c $d; done |
    tail -n +2 | grep " 01" | while read a b c; do echo $b; done |
    cut -d: -f1 | sed "s/../& /g" | while read d c b a; do
    printf "%d.%d.%d.%d\n" 0x$a 0x$b 0x$c 0x$d; done

Actually the process contains the connections for all clients, not just your own. It is basically the main SSHD process. I don't know why it runs under your user.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .