簡體   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