I'm trying to automate getting the status of 500 servers.
I can ssh into the server bmc console which brings up a smash clp terminal using a valid username and password and run the command: chassis --get power status and this returns on screen: The host status is on
I have done pssh to the server but in the case of the server being off I would like to pssh through the BMC console and run the same command to check if the server is available. When I use the same method for pssh on the console that I do on the server nothing happens. There is no return no error it sits there executing the script until I force it to stop.
How can I pssh to the smash clp?
My simple test script:
from pssh.clients import ParallelSSHClient
hosts = ['server-con']
username='uname'
password='password'
client = ParallelSSHClient(hosts, username, password)
output = client.run_command('chassis --get power status')
for host, host_output in output.items():
for line in host_output.stdout:
print(line)
I don't know BMC console or chassis, but from my understanding, you are trying to wrap in python ssh command to run remotely and having a problem with that.
My suggestion is to simply use subprocess and run it
output = subprocess.run("ssh foo chassis --get power status", shell=True, stdout=subprocess.PIPE)
Related
I'm new to Paramiko and have tried a variety of methods for doing what is a pretty basic task. At this point, all I'm trying to do is execute a command on an APC UPS. In my testing, I discovered I can successfully execute a command, as long as the length of the command is 20 characters or less.
Here is my code -
import paramiko
from paramiko_expect import SSHClientInteraction
host = "xxx.xxx.xxx.xxx" # UPS
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username='e164468', password='********', banner_timeout=60)
chan = SSHClientInteraction(ssh, timeout=2, display=True)
prompt = 'apc>'
command = 'cipher -rsake disable'
chan.expect(prompt)
chan.send(command)
chan.expect(prompt)
output_raw = chan.current_output_clean
chan.close()
ssh.close()
print ("Here is your output - ")
print(output_raw)
The command I need to remotely execute is 'cipher -rsake disable'. What I get in the terminal when I run this is -
apc>cipher -rsake disablEXCESS TIME RECV_READY TIMEOUT, did you expect() before a send()
If I drop the disable parameter from the command, it works as expected. No matter what I've tried, I get this behavior whenever the command is over 20 characters.
I'm not sure how valid of a test it is but I manually ssh to the UPS and can type in whatever command I need and it works.
Any help would be greatly appreciated!
Currently I cannot import any 3rd party libraries such as paramiko which is used to handle SSH things.
I cannot handle one scenario while testing ssh connection.
Having code:
import subprocess
result = subprocess.check_output(["ssh", "user#server1", "echo", "123"])
I'm successfully retrieving output from this command because I have setup the ssh keys.
While trying connect to unknown server I receive "non-zero exit status 255" and I know how to handle this.
The problem is where I did not setup ssh keys and the server is known.
import subprocess
result = subprocess.check_output(["ssh", "user#server2", "echo", "123"])
I receive shell output:
user#server2's password:
Like I would normally try to connect through ssh without ssh key.
I've tried:
result = subprocess.check_output(["ssh", "user#server2", "echo", "123"], input=b"123")
result = subprocess.check_output(["ssh", "user#server2", "echo", "123"], stdin=b"123")
and only solution to this is make ssh command force to not ask for password
result = subprocess.check_output(["ssh", "obatchmode=yes", "user#server2", "echo", "123"])
But I would like to know how to handle subprocess.check_output/run command in such cases where I cannot configure command not to ask for password. Like this code of block:
if subprocess.check_output IS ASKING FOR INPUT:
DONT_WORRY_GO_AHEAD
I am new to python. I need to login to a server daily (Desktop -> 1.32 -> 0.20 -> 3.26). For this I need to open putty and using ssh connection i am logging in. To do all this I want to write a script using python.
By using google I thought subprocess.Popen will do that. But Its not working fine.
1st trail:
import subprocess
pid = subprocess.Popen("putty.exe user#xxx.xx.x.32 -pw password").pid
Its working fine (Opening window logging into .32). But cant able to give input. I came to know that to give input for the same process we need to use pipes.
2nd trail:
from subprocess import Popen, PIPE, STDOUT
p = Popen("putty.exe user#xxx.xx.x.32 -pw password", stdout=PIPE, stdin=PIPE, stderr=STDOUT)
grep_stdout = p.communicate(input=b'ssh xx.xx.x.20\n')[0]
print(grep_stdout.decode())
by using this i cant login for the first server also. After logging in to all servers I need the terminal as alive. how to do this???
Edit
I need to do this in a new putty window. After logging in dont close the window. I have some manual work to do.
use powershell to call putty in order to open a new window
from subprocess import Popen
Popen("powershell putty.exe user#host -pw mypassword")
Use paramiko library python
Establish a SSH connection using -
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname,username, password)
Check the status if connection is alive using -
status = ssh.get_transport().is_active()
#returns True if connection is alive/active
ssh.exec_command() is basically a single session. Use exec_command(command1;command2) to execute multiple commands in one session
Also, you can use this to execute multiple commands in single session
channel = ssh.invoke_shell()
stdin = channel.makefile('wb')
stdout = channel.makefile('rb')
stdin.write('''
Command 1
Command 2
''')
print stdout.read()
There is a SSHv2 protocol implementation for python: http://www.paramiko.org/. You can easily install it with pip:
pip install paramiko
Then you can create ssh client, connect to your host and execute commands:
import paramiko
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect('hostname', username='login', password='pwd')
stdin, stdout, stderr = ssh_client.exec_command('command')
I created a bat file on windows, which references putty and putty session-specific info. This bat file can run by itself on windows. To call from python, I used the subprocess.run() -- python 3.5+.
Example of bat file named putty.bat:
start c:\app\PuTTy\putty.exe -load 192.168.1.230-node1-logs -l <logon user> -pw <logon user password for putty session>
Breaking down the bat file:
It begins with window's command "start".
c:\app\PuTTy\putty.exe --> is the putty directory on Windows containing putty.exe.
-load --> tells putty to load a putty profile. The profile is the name you see on the putty client, under "Saved Sessions".
192.168.1.230-node1-logs --> my putty session specific profile.
-l for logon --> followed by the putty logon user.
-pw is the logon password --> followed by the putty logon password.
That concludes the contents of "putty.bat".
From within python, is used the subprocess.run() command.
Example:
import subprocess
...
...
try:
process = subprocess.run(["putty.bat"], check=True, stdout=subprocess.PIPE, universal_newlines=True)
print(process.stdout)
except Exception as e:
print("subprocess call error in open putty command")
print(str(e))
I hope you find this helpful
I'm trying to write a script that will ssh into a box for me. I'm using Python and leveraging the paramiko library. I can successfully ssh on the box, but as soon as the script terminates, the ssh connection also terminates. I want to keep the connection open after the script has completed running.
Python:
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(host, username=self.username, password=self.password)
stdout = execute(self.ssh, 'pwd') # test command for now to verify i'm on box
print stdout
sys.exit()
Console:
$ ssh.py
[u'/home/myuser\n']
myuser#xxxx ~
$
I haven't been able to find similar examples online, so any help would be appreciated.
Try this:
import subprocess
subprocess.call(["ssh", "myuser#myserver"])
Goal
I'm trying to automate a fortigate configuration change for a couple dozen routers and am not winning. Have tried Python's paramiko library, Python fabric and Perl's expect and Rex interfaces/libraries.
Other info
* Routers: Fortigate 60D
* Firmware: v5.0,build0252 (GA Patch 5)
* SSH enabled: True
I can log in over SSH and run these commands manually!
I used the perl expect library with Fortigate 60B's in the past but it no longer works. Before I share the code I want to ask:
Is there some new feature in Fortigate's that prevents this type of automation?
A simple and harmless command to test [ list current dhcp leases ]:
execute dhcp lease-list wifi
Code
Perl/Expect:
my $timeout = 10;
$ssh->expect($timeout, [ qr/password: /i ]);
$ssh->send("$passwd\r\n");
$ssh->expect($timeout, [ qr/#/i ]);
$ssh->send("execute dhcp lease-list wifi\r");
$ssh->expect($timeout, [ qr/#/i ]);
$ssh->send("exit\r");
$ssh->soft_close();
Output: none
Perl/Rex:
desc "List all dhcp leases";
task "leases", group => "forti", sub {
my $output = run "execute dhcp lease-list wifi";
say $output;
};
Output:
[2014-02-11 13:14:48] (30011) - INFO - Running task: leases
[2014-02-11 13:14:48] (30022) - INFO - Connecting to 10.10.10.2 (admin)
[2014-02-11 13:14:49] (30022) - INFO - Connected to 10.10.10.2, trying to authenticate.
Fortigate # Unknown action 0
Fortigate #
Python/paramiko:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('10.10.10.2',username='fake_root',password='fake_pass')
stdin, stdout, stderr=ssh.exec_command("execute dhcp lease-list wifi")
stdout.readlines()
ssh.close()
Output: none
Python/Fabric:
def view_dhcp_leases():
print("Viewing dhcp leases")
run("execute dhcp lease-list wifi")
Output:
[10.10.10.2] Executing task 'view_dhcp_leases'
Viewing dhcp leases
[10.10.10.2] run: execute dhcp lease-list wifi
[10.10.10.2] out: Fortigate # Unknown action 0
[10.10.10.2] out:
[10.10.10.2] out: Fortigate #
Done.
Disconnecting from 10.10.10.2 ... done.
Conclusions ...so far
Unknown action 0 means, "I don't know this command [ in this context ]". This command can be run manually at the first prompt. Also, as you can see in the fabric and rex examples: it does authenticate and connect! I conclude that this is by design for security reasons ...and more likely to sell their proprietary management crap.
This works for me on a FortiNet Mail Appliance.
from Exscript.util.interact import Account
from Exscript.protocols import SSH2
account = Account('USERNAME', 'PASSWORD')
conn = SSH2()
conn.connect('IP')
conn.login(account)
conn.execute('COMMAND')
conn.send('exit \r')
conn.close()
https://github.com/knipknap/exscript
The following script worked for me against a FortiGate (5.2.4) with Python/Paramiko:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('1.1.1.254',username='admin',password='password')
stdin, stdout, stderr=ssh.exec_command("get system status")
type(stdin)
stdout.readlines()
Andy
I have 60B.
Please try to run this command from linux terminal.
If you don't have sshpass - you can install it.
sshpass -p 'adminpassword' ssh ip_of_fw -l admin execute dhcp lease-list
If you want to use fabric to run commands on fortigates you need to disable the shell wrapping used by fabric when connecting via SSH:
from fabric.api import run
def get_sys():
run("get sys status",shell=False)
Youc can upgrade an OS version and then use API with P