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

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

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

但是,如果用户使用SUDO运行我的程序(因为他们将需要),env $ dooesn不显示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 

如何在SUDO下检索SSH_CONNECTION环境variables,当它不在env $中?

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

我不是在Linuxytypes的东西,所以要温柔我…

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

 pstree -ps $$ | grep "sshd(" 

如果它返回任何东西,那么这意味着SSH守护进程位于会话之上。 Ergo,这是一个SSH连接。 结果显示了SSH守护进程的PID。 pstree cmd的结果:

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

但是我正努力从PID获得一个src IP。 这条街上的任何想法?

[编辑]方法3:/ run / utmp包含SSHlogin的详细信息。 在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之间会出现一些乱码。 考虑到(我认为)从比赛到知识产权的确切距离在不同情况下会有所不同,最好的parsing方法是什么?

OpenSSH守护进程使用当前终端,IP和用户名写入一个到/ var / run / utmp的条目。 检查w的输出或解析/ var / run / utmp的命令。

这只是获取当前终端(类似于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]

把它放在最后!

“最后一个”命令有用户和他们的IP列表! 很简单。

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