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

时间:2021-08-27 23:50:51

I want to detect if the user is connected over SSH. In a term, the "env" command shows SSH_CONNECTION line. Accessed in Python in one of two ways:

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

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

But, if the user has ran my program using SUDO (as they will need to), env$ dooesn't show SSH_CONNECTION. So Python can't see it:

但是,如果用户使用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

The aim is to achieve the following:

目的是实现以下目标:

#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

How do I retrieve SSH_CONNECTION environment variable under SUDO, when its not present in env$ ?

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

Or more precisely: how can I detect if the current session is via SSH when sudo?

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

I'm not a natural at Linuxy-type things, so be gentle with me...

我不擅长linux类的东西,所以对我要温柔……

[EDIT:] METHOD 2: Giving up on env$, I've tried the following:

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

pstree -ps $$ | grep "sshd("

If it returns anything then it means that the SSH daemon sits above the session. Ergo, it's a SSH connection. And the results are showing me the PIDs of the SSH daemons. Results of the pstree cmd:

如果返回任何内容,则意味着SSH守护进程位于会话之上。Ergo,它是SSH连接。结果显示了SSH守护进程的PIDs。pstree cmd结果:

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

But I'm struggling to get a src IP from the PID. Any ideas on this avenue?

但是我很难从PID那里得到一个src IP。对这条路有什么想法吗?

[EDIT] METHOD 3: /run/utmp contains details of SSH logins. In python:

方法3:/运行/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:]

So far, so good. This gives the following results (I've changed the IP and username to USERNAME)

到目前为止还好。结果如下(我将IP和用户名改为用户名)

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

So, when it comes to extracting the IP from the file, there's some bumf inbetween the occurances of pts/10 and the IP. What's the best way to parse it, given that (I reckon) the precise distance from the match to the IP will be different under different circumstances?

因此,当从文件中提取IP时,在pts/10和IP之间出现了一些bumf。考虑到(我认为)匹配到IP的精确距离在不同的情况下是不同的,那么最好的解析方法是什么?

2 个解决方案

#1


2  

The OpenSSH daemon writes an entry to /var/run/utmp with the current terminal, the IP and the name of the user. Check the output of the w or who commands that parse /var/run/utmp.

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

It's just a question of getting the current terminal (similar to the tty command) and extracting the information you want.

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

Use pyutmp like this:

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

Then filter by using ut_pid field to parse the /proc/ut_pid/cmdline file which should contain:

然后使用ut_pid字段对/proc/ pid/cmdline文件进行筛选,该文件应该包含:

sshd: ut_user [priv]

sshd:ut_user[priv]

#2


0  

GOT IT AT LAST!!!

终于找到了! ! !

The "last" command has list of users and their IPs!! So simple.

“最后”命令有用户和他们的ip列表!那么简单。

It has "still logged in" marked against sessions. Filter by these And then filter by current pts ID

它“仍然登录”,标记为会话。通过这些过滤器,然后通过当前pts ID过滤器

To get the IP for the current SSH session in Python, do this:

要获取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

For readability, across multiple lines:

对于可读性,跨多行:

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

#1


2  

The OpenSSH daemon writes an entry to /var/run/utmp with the current terminal, the IP and the name of the user. Check the output of the w or who commands that parse /var/run/utmp.

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

It's just a question of getting the current terminal (similar to the tty command) and extracting the information you want.

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

Use pyutmp like this:

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

Then filter by using ut_pid field to parse the /proc/ut_pid/cmdline file which should contain:

然后使用ut_pid字段对/proc/ pid/cmdline文件进行筛选,该文件应该包含:

sshd: ut_user [priv]

sshd:ut_user[priv]

#2


0  

GOT IT AT LAST!!!

终于找到了! ! !

The "last" command has list of users and their IPs!! So simple.

“最后”命令有用户和他们的ip列表!那么简单。

It has "still logged in" marked against sessions. Filter by these And then filter by current pts ID

它“仍然登录”,标记为会话。通过这些过滤器,然后通过当前pts ID过滤器

To get the IP for the current SSH session in Python, do this:

要获取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

For readability, across multiple lines:

对于可读性,跨多行:

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