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

2024-10-01 13:36:50 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

但是,如果用户使用SUDO运行了我的程序(正如他们需要的那样),env$dooesn不会显示SSH\u连接。所以Python看不到它:

^{pr2}$

其目的是实现以下目标:

#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$中不存在时,如何检索SUDO下的SSH_CONNECTION环境变量?在

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

我不是一个天生的林纳斯式的人,所以对我温柔点。。。在

[编辑:]方法二:放弃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登录的详细信息。在python中:

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的精确距离在不同的情况下会有所不同,那么最好的解析方法是什么?在


Tags: 方法importipenvifosonconnection
2条回答

OpenSSH守护进程向/var/run/utmp写入一个条目,其中包含当前终端、IP和用户名。检查解析/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的列表!!很简单。在

它的sessions标记为“仍然登录”。通过这些过滤 然后按当前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

为了提高可读性,可跨多行:

^{pr2}$

相关问题 更多 >