I am new to python and if the question is very nooby i apologize. Simply put i need to write a script that connects to remote via ssh then telnets to localhost and execute a command on a shell there.
I am using Python 2.4.3. I have read alot of similar questions here , and alot of people suggest to use modules such as Paramiko, Pexpect etc. However this is out of question - i am supposed to use only "native" 2.4.3 libraries. I have tried messing around with subprocess module and i have managed to connect to remote shell (however i need to provide a password - and i would like to avoid that by providing a password in script for example) - but still i need to do a telnet to localhost and execute few commands on a different shell.
Could someone be so kind and give me some hints? Thanks in advance.
TL;DR I am looking for python alternative to this bash command :
./sshpass -p password ssh username#$ip -t "(sleep 1;echo "command" ; sleep 1) | telnet localhost $port;exit;bash" >> testing.txt
after a simple search:
telnet:
link
import getpass
import sys
import telnetlib
HOST = "hostname"
user = raw_input("Enter your remote account: ")
password = getpass.getpass()
tn = telnetlib.Telnet(HOST)
tn.read_until("login: ")
tn.write(user + "\n")
if password:
tn.read_until("Password: ")
tn.write(password + "\n")
tn.write("ls\n")
tn.write("exit\n")
print tn.read_all()
ssh:
link
import pxssh
import getpass
try:
s = pxssh.pxssh()
hostname = raw_input('hostname: ')
username = raw_input('username: ')
password = getpass.getpass('password: ')
s.login (hostname, username, password)
s.sendline ('uptime') # run a command
s.prompt() # match the prompt
print s.before # print everything before the prompt.
s.sendline ('ls -l')
s.prompt()
print s.before
s.sendline ('df')
s.prompt()
print s.before
s.logout()
except pxssh.ExceptionPxssh, e:
print "pxssh failed on login."
print str(e)
Related
I need to check a lot of servers if they have chef installed (Don't ask) I was trying to automate it instead of doing it manually. I have never used python before and I can't really test this until I go in tomorrow so was looking for some feed back if I am on the right track.I figure I dump all the IP address's into a text file, loop through it and save the ones that need to have chef installed.
import pxssh
import getpass
CheckIT = str("command not found")
for line in open('ServerList.txt','r').readlines():
try:
s = pxssh.pxssh()
hostname = raw_input('line ')
username = raw_input('username ')
password = getpass.getpass('password: ')
s.login (hostname, username, password)
s.sendline ('sudo su -') # run a command
s.prompt() # match the prompt
s.sendline ('chef-client')
s.prompt()
if CheckIT == readline(self,size=-1)
with open("ServersToUpdate.txt", "a") as myfile:
myfile.write(hostname)
except pxssh.ExceptionPxssh, e:
print "pxssh failed on login."
print str(e)
Okay, so you probably won't want to actually run Chef as part of this. Also never ever use sudo su -, to correct way to write that for the past 15 years has been sudo -i, but you don't need even that. Just run chef-client --version and if that fails, assume Chef isn't installed.
I am writing a simple python script to test connectivity to multiple linux hosts running centos on them. For this I am thinking of using pexpect module and ssh . pexpect will send the password stored in a variable when prompted for. The problem is that how to check if the password was accepted successfully or not. Is there a way to do so. The code is given below. Please add you expert comments.
This example has code written to ssh to localhost only.So a for loop is not yet included.
import pexpect
from getpass import getpass
import sys
# Defining Global Variables
log_file = '/tmp/AccessValidation'
# Getting password from user and storing in a variable
passs = getpass("Please enter your password: ")
# Connect to server using ssh connection and run a command to verify access.
child = pexpect.spawn("ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no 127.0.0.1 'uptime'")
child.expect('Password:')
child.sendline(passs)
One of the things you could do is to have an expect for the command prompt. So if your prompt is: someuser#host$ you could do child.expect(".*\$").
Another thing you could do is to have multiple expects and then check those against the ones you want. For example:
i = child.expect([".*\$", "Password Incorrect"])
if i != 0:
print "Incorrect credentials"
else:
print "Command executed correctly"
You can view some examples within Pexpect's readthedocs page. Pexpect also has the pxssh class that is specialized to handle ssh connections and may be of some use also. I personally haven't used it but the syntax seems the same, just with more options relating to ssh.
Thanks Cory Shay for helping me figure out the correct way to solve my problem . Below is the code I have written and this works.
import pexpect
from getpass import getpass
import sys
# Defining Global Variables
log_file = '/tmp/AccessValidation'
# Getting password from user and storing in a variable
passs = getpass("Please enter your password: ")
# Connect to server using ssh connection and run a command to verify access.
child = pexpect.spawn("ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no 127.0.0.1 'hostname' ")
child.expect('Password:')
child.sendline(passs)
result = child.expect(['Password:', pexpect.EOF])
if result == 0:
print "Access Denied"
elif result == 1:
print "Access Granted"
I'm trying to connect to a server using ssh via the pxssh python library.
Here's my code:
import pxssh
import getpass
try:
s = pxssh.pxssh()
s.force_password = True
hostname = 'myserverip'
username = 'username'
password = 'password'
s.login (hostname, username, password)
s.sendline ('get system number') # run a command
s.prompt() # match the prompt
print s.before # print everything before the prompt.
s.logout()
except pxssh.ExceptionPxssh, e:
print "pxssh failed on login."
print str(e)
Here is the response I am getting:
pxssh failed on login.
could not set shell prompt
unset PROMPT_COMMAND
error,09
$ PS1='[PEXPECT]\$ '
error,09
$ set prompt='[PEXPECT]\$ '
error,09
$
Pretty old question but just for posterity. (For the one's who would bump in to this like me :) )
from pexpect import pxssh
import getpass
try:
s = pxssh.pxssh()
hostname = raw_input('hostname: ')
username = raw_input('username: ')
password = getpass.getpass('password: ')
s.login(hostname, username, password)
s.sendline('uptime') # run a command
s.prompt() # match the prompt
print(s.before) # print everything before the prompt.
s.sendline('ls -l')
s.prompt()
print(s.before)
s.sendline('df')
s.prompt()
print(s.before)
s.logout()
except pxssh.ExceptionPxssh as e:
print("pxssh failed on login.")
print(e)
which I just yanked from http://pexpect.readthedocs.io/en/latest/api/pxssh.html#pexpect.pxssh.pxssh
Did you verify the login credentials?
The logs indicate that your script didnt clear the first step necessary to get the shell.
s.login(hostname, username, password)
BTW, you are hardcoding all these arguments.
Your first problem here is that there is no hostname as 'hostname' which you can logon to on any system, unless alias of 'localhost' or some website/url.
Note: Use your head before blatantly copying examples.
I am using this code to add server to the known_hosts:
subprocess.Popen(['sshpass', '-p', password, 'ssh', '-o', 'StrictHostKeyChecking=no', add_key], stdout=subprocess.PIPE).communicate()[0]
This adds hostname to the known_hosts but the server hangs as it tries to enter into the host. I just want add hostname to the known_hosts and continue with my other codes. How can I do that? Thanks
This should do the job. This solution use the pexpect library which is a great way to automate commands. You basically call add_known_hosts with the host, user, password that you want added. it will try to ssh to that host and either enters the password or responds to the add to known hosts connection with a yes and then enters the password. Finally it cleanly exits the connection by sending the exit command. You can modify this and not require a username and password and just answer yes to the continue connecting question and then end the ssh process instead of continuing with the password prompt.
import pexpect, time
def add_known_hosts(host, user, password):
child = pexpect.spawn('ssh %s#%s' % (user, host))
i = child.expect(['.* password:', '.* continue connecting (yes/no)?'])
if i == 1:
child.sendline('yes')
child.expect('.* password:')
child.sendline(password)
child.expect('%s#%s' % (user, host))
time.sleep(1)
child.sendline('exit')
add_known_hosts('myhost', 'myusername', 'mypassword')
debugging
from the comments below it seems you are facing issues using pexpect on your system. A good way to just to do a simple test to confirm pexpect is working correctly with ssh is to run the code below. Fill in host, user with your appropriate settings and then run the code, you should be able to interact with the ssh session. At this point you can build up from here and see exactly what text you are expecting to get from ssh and what text you want to send in response.
import pexpect
host, user = 'myhost', 'myusername'
child = pexpect.spawn('ssh %s#%s' % (user, host))
child.interact()
Never mind, Solved it myself. Here's what I did:
test = subprocess.Popen(['sshpass', '-p', password, 'ssh', '-o', 'StrictHostKeyChecking=no', add_key])
time.sleep(5.0)
test.kill()
Thanks!
I'm using the following code to log into a server and go to a particular directory (where the logfile I want to search for a string resides). I have accomplished this with the Paramiko module (ssh), fairly straightforward. But the telnetlib module does not have many functions that I see to accomplish this. Does anyone know how I would open the file and search through it for a particular string (The server in question only allows Telnet logins - no ssh) ... Thanks:
import sys
import telnetlib
HOST = "10.28.46.14"
user = raw_input("Enter your username: ")
password = ""
tn = telnetlib.Telnet(HOST)
tn.read_until("login: ")
tn.write(user + "\n")
if password == "":
tn.read_until("Password: ")
tn.write(password + "\n")
#print "Login successful!"
else:
print "Your password is incorrect."
tn.write("cd /var/opt/mylog/log\n")
tn.write("ls\n")
tn.read_until("\n")
#tn.write("exit\n")
my_ls = tn.read_until("my.log")
print my_ls
Did you check with the owner of the machine about ssh vs telnet? There aren't many operating systems that ship with telnet out of the box anymore, because telnet is subject to replay attacks.
What if you tell tn to do a grep? You might append an "echo $?" after the grep, to get an exit code - 0 means there was one or more matches, anything else means there weren't any.