繁体   English   中英

在 Python 中,如果用户通过 SSH 连接,我如何获取用户的远程 IP(他们的最后一跳)?

[英]In Python, how do I get user's remote IP (their last hop) if they're connected over SSH?

我想检测用户是否通过 SSH 连接。 总而言之,“env”命令显示 SSH_CONNECTION 行。 通过以下两种方式之一在 Python 中访问:

#python:
import os
print os.getenv("SSH_CONNECTION")       #works
print os.environ.get("SSH_CONNECTION")  #works

但是,如果用户使用 SUDO 运行了我的程序(因为他们需要),env$ 不会显示 SSH_CONNECTION。 所以Python看不到它:

#sudo python:
import os
print os.getenv("SSH_CONNECTION")       #not set
print os.environ.get("SSH_CONNECTION")  #not set

目标是实现以下目标:

#Detect if user is over remote IP
lRemoteIP=""                                     #Is set if user on SSH
lStr=os.environ.get("SSH_CONNECTION")            #Temp var
if lStr: lRemoteIP=lStr.split()[0].split("=")[1] #Store user's lasthop IP

#Later on in the code, for multiple purposes:
if lRemoteIP: pass #Do stuff (or not) depending on if they're on SSH

当 env$ 中不存在 SSH_CONNECTION 环境变量时,如何在 SUDO 下检索 SSH_CONNECTION 环境变量?

或者更准确地说:如何在 sudo 时检测当前会话是否通过 SSH?

我不擅长 Linux 类型的东西,所以对我温柔一点......

[编辑:] 方法 2:放弃 env$,我尝试了以下方法:

pstree -ps $$ | grep "sshd("

如果它返回任何内容,则意味着 SSH 守护进程位于会话之上。 因此,这是一个 SSH 连接。 结果向我展示了 SSH 守护进程的 PID。 pstree cmd 的结果:

init(1)---sshd(xxx)---sshd(xxx)---sshd(xxx)---bash(xxx)-+-grep(xxx)

但是我正在努力从 PID 中获取 src IP。 关于这条路的任何想法?

[编辑] 方法 3:/run/utmp 包含 SSH 登录的详细信息。 在蟒蛇中:

import os
import sys

lStr=open("/var/run/utmp").read().replace('\x00','') #Remove all those null values which make things hard to read

#Get the pseudo-session ID (pts) minus the /dev/ that it starts with:
lCurSess=os.ttyname(sys.stdout.fileno()).replace('/dev/','')
#Answer is like pts/10  (pseudo-term session number 10)
#Search lStr for pts/10
lInt=lStr.find(lCurSess.replace('/dev/',''))
#Print /var/utmp starting with where it first mentions current pts:
print lStr[lInt:]

到目前为止,很好。 这给出了以下结果(我已将 IP 和用户名更改为 USERNAME)

pts/10/10USERNAME\x9e\x958Ym\xb2\x05\x0 74\x14pts/10s/10USERNAME192.168.1.1\xbf\x958Y\xf8\xa3\r\xc0\xa88\x01

因此,在从文件中提取 IP 时,在 pts/10 和 IP 之间存在一些问题。 考虑到(我认为)从匹配到 IP 的精确距离在不同情况下会有所不同,解析它的最佳方法是什么?

OpenSSH 守护进程使用当前终端、IP 和用户名将条目写入 /var/run/utmp。 检查解析 /var/run/utmp 的wwho命令的输出。

这只是获取当前终端(类似于tty命令)并提取您想要的信息的问题。

像这样使用pyutmp

from pyutmp import UtmpFile
import os
import sys

for utmp in UtmpFile():
    if os.ttyname(sys.stdout.fileno()) == utmp.ut_line:
        print '%s logged from %s on tty %s' % (utmp.ut_user, utmp.ut_host, utmp.ut_line)

然后使用ut_pid字段进行过滤以解析 /proc/ ut_pid /cmdline 文件,该文件应包含:

sshd: ut_user [priv]

终于搞定了!!!

“last”命令包含用户及其 IP 的列表!! 如此简单。

它针对会话标记了“仍然登录”。 按这些过滤然后按当前pts ID过滤

要在 Python 中获取当前 SSH 会话的 IP,请执行以下操作:

import os,sys,subprocess
(out, err) = subprocess.Popen(['last | grep "still logged in" | grep "' + os.ttyname(sys.stdout.fileno()).replace('/dev/','') + '"'], stdout=subprocess.PIPE, shell=True).communicate()
RemoteIP=out.split()[2].replace(":0.0","") #Returns "" if not SSH

为了可读性,跨多行:

import os,sys,subprocess
pseudoTermID = os.ttyname(sys.stdout.fileno()).replace('/dev/','')
cmdStr       = 'last | grep "still logged in" | grep "'+pseudoTermID+'"'
sp           = subprocess.Popen([cmdStr], stdout=subprocess.PIPE, shell=True)
(out, err)   = sp.communicate()
RemoteIP     = out.split()[2].replace(":0.0","")   #Returns "" if not SSH

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM