无需超级用户身份即可获取当前 ssh 会话的原始 IP

无需超级用户身份即可获取当前 ssh 会话的原始 IP

我正在尝试找出当前 ssh 会话的原始 IP 地址。我发现以下内容很有用,但它需要 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

有没有办法无需调用 sudo 即可获取 99.xxx.xxx.xxx 信息?

(已回答!问题 1:为什么管道传输到 grep 只返回错误?)

问题 #2:有没有使用 netstat 获取 WAN 信息的解决方法?或者......

问题#3:有没有更好的选择来实现我的目标?

答案1

您可以使用SSH_CONNECTIONSSH_CLIENT变量:

$ 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

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.

SSH_CONNECTION如果将其拆分成 bash 数组,则可以更轻松地访问每个条目:

ssh_details=($SSH_CONNECTION)

然后您可以使用其索引获取每个条目:

$ 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

由于某种原因,SSH_CLIENT在英文手册页中没有记录。

答案2

回答 1 和 2:

警告来自netstatgrep而不是来自,它与输出PID/Program name的列有关netstat

$ 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

使用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

警报是不言自明的,您必须root查看其他(所有)用户拥有的进程 ID 和程序名称,否则您将只获得您拥有的程序的 PID/名称,尽管您将获得这些进程的打开套接字列表。

其区别基本上可以概括如下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.

在您的例子中,该程序sshd归 拥有root,因此如果不使用,sudo所有套接字信息都会出现在输出中,而不是程序名称和 PID。因此,在使用 时,grepnetstat -taepn会收到警告。

另一方面,如果您使用sudo,PID/程序名称将出现在netstat -taepn输出中,您可以使用它grep来查找输出。

以下内容将使您更加清楚(检查最后一列(PID /程序名称)):

$ 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       

如果您从客户端计算机运行它,那么您可以忽略它,因为在这种情况下该进程将是ssh(不是sshd)并且将由您拥有。

回答3:

方法有很多,我来补充几种:

$ 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

编辑:没有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

编辑2:

如果您想ssh在不使用的情况下获取连接到服务器端口 22()的远程 IP 地址sudo,最好的方法是通过ss命令读取套接字统计信息并从中获取所需的输出。

$ 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

我们已经在服务器中运行上述命令,并且是通过端口 22192.168.6.4连接到服务器的远程计算机的 IP 地址。ssh

答案3

该行用于错误输出,即sterr。你可以用以下命令删除它

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

以供参考检查一下

在此处输入图片描述

正如 heemayl 所指出的,如果没有sudo,netstat 将不会报告 ssh 服务器是否建立了连接,只有 ssh 客户端建立连接时才会报告。

当然,您仍然可以通过端口号或使用who -a实用程序来确定它,它将显示登录信息和地址,但不能保证某人没有通过 telnet 或远程桌面应用程序登录。

答案4

在继续阅读 SSH_CLIENT 答案之前(您知道它就这么简单),您还可以执行以下操作:

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

实际上,该进程包含所有客户端的连接,而不仅仅是您自己的客户端。它基本上是主要的 SSHD 进程。我不知道为什么它会在您的用户下运行。

相关内容