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:
#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 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$ ?
Or more precisely: how can I detect if the current session is via SSH when sudo?
I’m not a natural at Linuxy-type things, so be gentle with me…
[EDIT:] METHOD 2: Giving up on env$, I’ve tried the following:
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:
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?
[EDIT] METHOD 3: /run/utmp contains details of SSH logins. In 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)
pts/10/10USERNAMEx9ex958Ymxb2x05x0 74x14pts/10s/10USERNAME192.168.1.1xbfx958Yxf8xa3rxc0xa88x01
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?
Advertisement
Answer
GOT IT AT LAST!!!
The “last” command has list of users and their IPs!! So simple.
It has “still logged in” marked against sessions. Filter by these And then filter by current pts ID
To get the IP for the current SSH session in Python, do this:
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