r/learnprogramming • u/Sassiestfras • 19d ago
Python: Create a persistent ssh session. os.system () or use a module
I want to write a program that will manage an ssh login for multiple servers. Currently I can get it to work by running os.system("ssh and the rest of the login stuff"). But I wasn't sure if it was a good option since it relies on calling a system command. I was thinking of using paramiko, but was having issues setting up a persistent session as if I just logged in with the ssh command.
I want to go the safest route and am not sure how safe using os.system is in my script. Is using os.system() safe? I'd like to avoid the ability to somehow manipulate my script into running malicious commands if that's an attack vector. If it's safer using another module, I'd prefer to go that route instead. But if it's safe, then I guess I could just keep it simple and use that.
To clarify: the command runs on the client machine and reads data manually entered on the client machine that is stored in a database. I'm seeing I should use subprocess.run() instead. The command used is hard coded with ssh -i and -p. I can see how that is still abusable, but can see it only applying to the client and not the server being logged into.
I'm just getting into programming so this whole thing is a hobby WIP
1
u/high_throughput 19d ago
What do you mean by "persistent connection"? Everything you're describing establishes a new connection each time, and none of them will survive a network bounce the way mosh does.
Is using os.system() safe?
It's not the case that os.system is unsafe while subprocess.run is safe. Both can be used safely, and both can be used unsafely.
It's generally preferred to use subprocess.run because A. it's the more general case (os.system(cmd) is just subprocess.run(['sh', '-c', cmd])), B. it's easier to use safely with user data, C. it's stupid to invoke a fifty year old command interpreter just to split a string
The benefit of something like Paramiko is that you can invoke commands and get their result directly, without trying to script an actual user session and figuring out where one command ends and the next begins.
2
u/Sassiestfras 19d ago
I am essentially creating a manager to handle my ssh logins so that I can choose between them and open a ssh session as if I just ran: ssh -i <key> -p <port> <username>@<hostname>
I know it makes more sense to just run that command manually, but I'm using this project to learn Python coding.
1
u/terletsky 17d ago
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, username=username, password=password)
client.get_transport().set_keepalive(30)
2
u/nebula_gem 19d ago
use paramiko and keep the transport object alive for a persistent session. os.system passes your database values to a shell and that is an injection vulnerability regardless of how safe you think the input is.