【问题标题】:Find the IP address of the client in an SSH session在 SSH 会话中查找客户端的 IP 地址
【发布时间】:2010-11-03 00:46:26
【问题描述】:

我有一个脚本,由使用SSH 登录服务器的人运行。

有没有办法自动找出用户连接的 IP 地址?

当然,我可以问用户(它是程序员的工具,所以没问题),但如果我刚刚发现会更酷。

【问题讨论】:

  • 建议迁移到 serverfault,不过问题仍然很大

标签: linux networking ssh ip-address


【解决方案1】:

获取最近登录到机器的用户列表的简单命令是last。这是最近订购的,因此last | head -n 1 将显示最后一次登录。不过,这可能不是当前登录的用户。

样本输出:

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)    
...

【讨论】:

    【解决方案2】:

    我在 Debian 10 上从 who -m --ips 获得以下输出:

    root pts/0 Dec 4 06:45 123.123.123.123

    似乎添加了一个新列,因此 {print $5} 或“获取第 5 列”尝试不再起作用。

    试试这个:

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

    来源:

    【讨论】:

      【解决方案3】:

      为@Nikhil Katre 的回答竖起大拇指:

      让最后 10 个用户登录机器的最简单命令是last|head

      要获取所有用户,只需使用last 命令

      使用whopinky 的人做了基本上要求的事情。 But But 但是他们不提供历史会话信息。

      如果您想认识刚刚登录的人,这也可能很有趣 开始此检查时已注销。

      如果是多用户系统。我建议添加您要查找的用户帐户:

      last | grep $USER | head
      

      编辑:

      在我的例子中,$SSH_CLIENT 和 $SSH_CONNECTION 都不存在。

      【讨论】:

        【解决方案4】:
         who | cut -d"(" -f2 |cut -d")" -f1
        

        【讨论】:

          【解决方案5】:

          一个有很多答案的旧帖子,但没有一个是我想要的,所以我贡献了我的:

          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
          

          此方法与直接 ssh、sudoed 用户和屏幕会话兼容。它将通过进程树跟踪,直到找到带有 SSH_CLIENT 变量的 pid,然后将其 IP 记录为 $sshClientIP。如果它离树太远,它会将 IP 记录为 'localhost' 并离开循环。

          【讨论】:

            【解决方案6】:

            检查是否有环境变量调用:

            $SSH_CLIENT 
            

            $SSH_CONNECTION
            

            (或任何其他环境变量)在用户登录时设置。然后使用用户登录脚本对其进行处理。

            提取IP:

            $ echo $SSH_CLIENT | awk '{ print $1}'
            1.2.3.4
            $ echo $SSH_CONNECTION | awk '{print $1}'
            1.2.3.4
            

            【讨论】:

            • @cwd 我想替换这个命令中的ip "iptables -A INPUT -s 93.203.118.251 -p tcp --destination-port 443 -j DROP" 可以吗?
            • 这对我来说是远程主机。
            • 仅适用于非 sudoed 用户。例如如果您有一个 ssh 用户,然后升级为 root,则会创建一个新的 shell 并且这些变量会丢失,除非您可以通过树回溯以找到原始 ssh pid 并从 /proc/$PID/environ
            • 感谢stackoverflow.com/questions/428109/extract-substring-in-bash 这个答案可以简单地改进为${SSH_CLIENT%% *}
            • @Andrej 查看sudo -E
            【解决方案7】:

            改进先前的答案。给出 IP 地址而不是主机名。 --ips 在 OS X 上不可用。

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

            更通用,将 OS X 10.11 的 $5 更改为 $6:

            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
            

            【讨论】:

              【解决方案8】:

              只需在您的 Linux 机器上输入以下命令:

              who
              

              【讨论】:

                【解决方案9】:

                您可以通过 SSH 库 (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;
                }
                

                【讨论】:

                  【解决方案10】:
                  netstat -tapen | grep ssh | awk '{ print $10}'
                  

                  输出:

                  我的实验中有两个#

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

                  给出 IP 地址。

                  输出:

                  127.0.0.1:22 # in my experiment
                  

                  但结果与其他用户和东西混在一起。它需要更多的工作。

                  【讨论】:

                  • 我的 netstat 只提供 IPv6 的截断地址,“127.0.0.1:22”是服务器而不是客户端,(在问题中指定。)
                  【解决方案11】:

                  尝试以下方法仅获取 IP 地址:

                  who am i|awk '{ print $5}'
                  

                  【讨论】:

                  • 很确定如果你写 whoami 你会得到登录用户的名字。没有第五件事或 ip 打印抱歉。但是 whoami 是一个有用的命令
                  • who am i != whoami 至少在我的 Linux 上。还有第五件事,就是客户端的主机名。
                  • 对于其他想知道who am i 的人:who 的联机帮助页说:If ARG1 ARG2 given, -m presumed: 'am i' or 'mom likes' are usual.。所以真的任何有两个词的东西都有效,还有像who likes icecream这样的东西。
                  • 在此答案的基础上,我将其缩减为 who -m --ips|awk '{print $5}',因此我只有 IP 而没有反向 DNS 答案。感谢who am i 的帮助!
                  • tmux 失败:who am i|awk '{ print $5}'(tmux(2445).%3)
                  【解决方案12】:

                  假设他打开一个交互式会话(即分配一个pseudo terminal)并且您可以访问stdin,您可以call an ioctl on that device 获取设备号(/dev/pts/4711)并尝试找到那个在/var/run/utmp 中(其中还有用户名和发起连接的 IP 地址)。

                  【讨论】:

                    【解决方案13】:

                    搜索“myusername”帐户的 SSH 连接;

                    取第一个结果字符串;

                    取第 5 列;

                    用“:”分割并返回第一部分(不需要端口号,我们只需要 IP):

                    netstat -tapen | grep "sshd: 我的用户名" |头-n1 | awk '{split($5, a, ":");打印 [1]}'


                    另一种方式:

                    我是谁 | awk '{l = 长度($5) - 2;打印 substr($5, 2, l)}'

                    【讨论】:

                    • sudo ss -tapen | grep "sshd: $(whoami)"|head -n1|awk '{split($5, a, ":"); print a[1]}' 说我的 ssh 客户端来自2a02 而你的“另一种方式:”说tmux(2445).%3
                    【解决方案14】:
                    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
                    

                    当我通过 ssh 登录并需要显示远程 X 时,我使用它来确定会话的 DISPLAY 变量。

                    【讨论】:

                    • 有用的一行代码将我的 IP 添加到 .htaccess 文件中。谢谢你。我对 FreeBSD 做了一个修改:who am i | awk '{print $6}' | sed 's/[()]//g' | sed 's/\./\\./g' 最后一部分省略了点。
                    【解决方案15】:
                    netstat -tapen | grep ssh | awk '{ print $4}'
                    

                    【讨论】:

                    • 不适用于 CentOS 6.9 (net-tools 1.60 netstat 1.42) (No info could be read for "-p": geteuid()=507 but you should be root.)
                    • @Jeff sudo ss -tapen | grep ssh | awk '{ print $4}'|grep -v ':22$' 工作吗?
                    • 这对我来说不太适用,必须使用netstat -tapen | grep -F :22 | grep ESTABLISHED
                    【解决方案16】:

                    Linux:我是谁 | awk '{打印 $5}' | sed 's/[()]//g'

                    AIX:我是谁 | awk '{打印 $6}' | sed 's/[()]//g'

                    【讨论】:

                      【解决方案17】:

                      netstat 会起作用(在顶部是这样的) tcp 0 0 10.x.xx.xx:ssh someipaddress.or.domainame:9379 已建立

                      【讨论】:

                      • 非常感谢你的回答,我最终做了'netstat | grep ssh'。
                      • 出于安全原因,这很糟糕,因为任何人都可以连接到该端口,而不仅仅是您。
                      【解决方案18】:

                      你可以使用命令:

                      server:~# pinky
                      

                      这会给你一些像这样的东西:

                      Login      Name                 TTY    Idle   When                 Where 
                      
                      root       root                 pts/0         2009-06-15 13:41     192.168.1.133
                      

                      【讨论】:

                      • 太棒了 :-) 书呆子幽默又一次。根据pinky --helpA lightweight 'finger' program; print user information. The utmp file will be /var/run/utmp.
                      • 为什么我的输出中我的'Where'只显示机器名而不显示IP地址?
                      • 可能你的机器上配置了域名服务器。
                      • pinky 将显示所有登录用户,而不仅仅是您自己
                      【解决方案19】:

                      通常在 /var/log/messages(或类似的,取决于您的操作系统)中有一个日志条目,您可以使用用户名进行 grep。

                      【讨论】:

                        猜你喜欢
                        • 2016-09-25
                        • 1970-01-01
                        • 2015-09-07
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-10-04
                        • 1970-01-01
                        • 2013-04-20
                        • 2020-03-10
                        相关资源
                        最近更新 更多