I have written a simple script that I want to run remotely to a Windows server using Python and Paramiko. The script should execute commands in the cmd on the remote Windows server and I want it to start up an .exe program for a starter. Here is what I have up to now:
import paramiko
hostname = "IP_of_server"
username = "username"
password = "password"
command = "start Full_Path_To_Application\Program.exe"
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password, look_for_keys=True, allow_agent=False)
print("Connected to %s" % hostname)
except paramiko.AuthenticationException:
print("Failed to connect to %s due to wrong username/password" %hostname)
exit(1)
try:
stdin, stdout, stderr = ssh.exec_command(command)
for line in stdout.readlines():
print(line)
print("Application has been started")
except:
exit(2)
What I get is:
Connected to IP_of_server
Application has been started
When I check on the server using the same username and password the application is not running. Running it manually starts it up.
I have confirmed that the command has been sent to the server by replacing it with "ipconfig" and I get the correct information.
Any idea why the application is not starting? Once it starts it should open a separate cmd with all the logs that I'm not seeing.
Thanks a lot.
I have executed commands on server using ssh. Now I have to do another ssh to different IP while keeping old ssh active.
This new IP is port forward which will then used to do SFTP.
Issue I am facing is both ssh connections are on same port so not able to do second ssh.
Which is failing the SFTP.
Any support for same will be helpful.
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip, username=username, password=password, port=22)
time.sleep(3)
#Invoke shell to open multiple channel with in one SSH
chan = ssh.invoke_shell()
chan.send(ip1+'\n')
time.sleep(5)
chan.send(pass1+'\n')
time.sleep(10)
chan.send("ssh "+ip2+'\n')
time.sleep(10)
chan.send(pass2+'\n')
time.sleep(5)
#Execute command
chan.send(cmd)
#connect to another ip to do sftp
ssh1 = paramiko.SSHClient()
ssh1.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("127.0.0.4", username=usr2, password=pass2, port=22)
sftp=ssh.open_sftp()
It looks like misunderstanding. Your code does not do any port forwarding.
For the correct code, see Nested SSH using Python Paramiko.
If you need SFTP, not shell, just do:
jhost.open_sftp()
instead of
jhost.exec_command(command)
Obligatory warning: Do not use AutoAddPolicy – You are losing a protection against MITM attacks by doing so. For a correct solution, see Paramiko "Unknown Server".
I am trying to use Paramiko to make an SSH communication between 2 servers on a private network. The client server is a web server and the host server is going to be a "worker" server. The idea was to not open up the worker server to HTTP connections. The only communication that needs to happen, is the web server needs to pass strings to a script on the worker server. For this I was hoping to use Paramiko and pass the information to the script via SSH.
I set up a new user and created a test script in Python 3, which works when I run it from the command line from my own user's SSH session. I put the same code into my Django web app, thinking that it should work, since it tests OK from the command line, and I get the following error:
Server 'worker-server' not found in known_hosts
Now, I think I understand this error. When performing the test script, I was using a certain user to access the server, and the known hosts information is saved to ~/.ssh/known_hosts even though the user is actually a 3rd party user created just for this one job. So the Django app is running under a different user who doesn't find the saved known hosts info because it doesn't have access to that folder. As far as I can tell the user which Apache uses to execute the Django scripts doesn't have a home directory.
Is there a way I can add this known host in a way that the Django process can see it?
Script:
import paramiko
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('worker-server', 22, 'workeruser', 'workerpass')
code = "123wfdv"
survey_id = 111
stdin, stdout, stderr =
client.exec_command('python3 /path/to/test_script/test.py %s %s' % ( code, survey_id ))
print( "ssh successful. Closing connection" )
stdout = stdout.readlines()
client.close()
print ( "Connection closed" )
output = ""
for line in stdout:
output = output + line
if output!="":
print ( output )
else:
print ( "There was no output for this command" )
You can hard-code the host key in your Python code, using HostKeys.add:
import paramiko
from base64 import decodebytes
keydata = b"""AAAAB3NzaC1yc2EAAAABIwAAAQEA0hV..."""
key = paramiko.RSAKey(data=decodebytes(keydata))
client = paramiko.SSHClient()
client.get_host_keys().add('example.com', 'ssh-rsa', key)
client.connect(...)
This is based on my answer to:
Paramiko "Unknown Server".
To see how to obtain the fingerprint for use in the code, see my answer to:
Verify host key with pysftp.
If using pysftp, instead of Paramiko directly, see:
PySFTP failing with "No hostkey for host X found" when deploying Django/Heroku
Or, as you are connecting within a private network, you can give up on verifying host key altogether, using AutoAddPolicy:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(...)
(This can be done only if you really do not need the connection to be secure)
So I have the following code which establishes a Telnet connection to a virtual machine on my local machine:
from telnetlib import Telnet
try:
tnet = Telnet('127.0.0.1', 2282, 3)
except Exception as e:
print('Failed!')
# The connection has been established!
print('Success!')
for i in range(0,5):
tnet.read_until(b"Password: ")
tnet.write(b'password' + b'\r\n')
tnet.write(b'v' + b'\n\r')
tnet.close()
break
The connection succeeds, but I need to be able to access the machine from code! I will replace the 'password' with a user's attempt, but I can't tell if the attempt has even worked and if it hasn't then how can I retry another attempt?
**EDIT: **
I tested the Telnet connection from my terminal on the host machine and the terminal output is like this:
telnet 127.0.0.1 2282
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Password:
Login incorrect
admin1-VirtualBox login: admin1
Password:
So if I check first for read_until(b'Password: ') and it fails, should I catch it and create a loop containg more read_until statements? Or is there a much neater way to do this.
A previous way I thought about doing this was attempting a whole new telnet connection every time it was wrong in a while loop
Thanks!
Using the python interactive shell and openssh running locally, I keep getting an "No existing session" exception using paramiko. My code is below.
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('localhost',username=name,password=pw)
Results in:
No handlers could be found for logger "paramiko.transport"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/paramiko-1.7.7.1-py2.6.egg/paramiko/client.py", line 332, in connect
self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
File "/usr/local/lib/python2.6/dist-packages/paramiko-1.7.7.1-py2.6.egg/paramiko/client.py", line 493, in _auth
raise saved_exception
paramiko.SSHException: No existing session
I was able to connect previously, but had been trying to adjust this to allow for key based authorization. That failed, and since then I have not been able to connect locally. I have tried restarting openssh, and have connected to another server successfully. After searching through here, all I have found are mentions of authorization exceptions, which does not appear to be the case here.
As you already have password you don't need to talk to agent or look for private keys stored on your machine. So try passing extra parameters allow_agent, look_for_keys:
ssh.connect('localhost',username=name,password=pw,allow_agent=False,look_for_keys=False)
I had a spare public key with a key pass phrase in my ssh-add list. Once I removed it, I was able to execute my paramiko based script properly.
To list:
ssh-add -l
To delete all:
ssh-add -D
To re-add:
ssh-add /FULL/PATH/TO/id_rsa
https://bugs.launchpad.net/paramiko/+bug/912123
Which OS are you using?
Maybe you can check your env variable:
SSH_AUTH_SOCK
for "connect", it will try to use ssh agent.
in agent.py
self.conn = None
self.keys = ()
if ('SSH_AUTH_SOCK' in os.environ) and (sys.platform != 'win32'):
conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
conn.connect(os.environ['SSH_AUTH_SOCK'])
except:
# probably a dangling env var: the ssh agent is gone
return
self.conn = conn
elif sys.platform == 'win32':
import win_pageant
if win_pageant.can_talk_to_agent():
self.conn = win_pageant.PageantConnection()
else:
return
Just got the same error ERROR:SSHException('No existing session',) but since it was in a clean docker container, there was no ssh-agent.
After some hours of debugging, I found a different solution: it can happen when there is a timeout during key exchange! In my case, the ssh server is a router over GSM link, which is very slow.
You can enable debug on paramiko with:
logging.getLogger("paramiko").setLevel(logging.DEBUG)
And if you see the exception between the Connected and the Switch to new keys ..., it means the timeout was during the key exchange. In this case, you have to set timeout to a bigger value! (documentation says timeout is only for TCP connect, but in fact, it is also for the whole negotiation before auth!)
In my case ,I have try use allow_agent=False,look_for_keys=False, but not work .
I ssh to a 2G device, so timeout=10 is Ok, timeout=3 get" Unable to establish SSH connection: No existing session". Not timeout except.
So try timeout= a long time,if connect to a not establish ssh.
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,22,username,passwd,timeout=10,allow_agent=True,look_for_keys=True)
print ('%s\tOK\n'%(ip) )
except socket.timeout:
print ("%s time out"%(ip))
except paramiko.AuthenticationException:
print("Authentication failed, please verify your credentials: %s"%(ip))
except paramiko.SSHException as sshException:
print("Unable to establish SSH connection: %s" %(sshException))
except paramiko.BadHostKeyException as badHostKeyException:
print("Unable to verify server's host key: %s" %(badHostKeyException))
finally:
ssh.close()
Replace 'localhost' by '127.0.0.1'.