Question:
How do I automate this process, and include all of the password prompts?
Machine 1> ssh user2@machine2password:
Machine 2> lxc-attach -n 0x1000
Container> ssh user3@machine3password:
Machine 3> get_temperature.shtemperature is 65C
Background:
I am running some automated scripts on a computer (Machine 1) with several other test systems cascaded from this one. Only the first computer has internet access and stable state. Anything can be installed here and the automation is mostly python.
The other test systems are not connected to the internet, are shutdown unexpectedly, and have their memory wiped often. Because of this, any settings I change or ssh keys I load outside of this automated script are not retained. I am just testing the hardware; none of this will be in production anywhere, and I don't have any way to change the state it is reset to.
Attempt:
I have tried to solve this running paramiko on Machine 1. I can connect to Machine 2, but I have no way to answer the password prompt when connecting to Machine 3 from the Machine 2. This is what I have tried:
import paramikossh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect('192.168.2.2', port=22, username='user2', password='pass2')
print("connect to machine 2")channel = ssh.invoke_shell()
channel_data = ''
go = 1while True: if channel.recv_ready():channel_data = str(channel.recv(9999))print('Channel Data: ', channel_data)else:continueif channel_data.endswith("~ >'"):if go == 1:channel.send('lxc-attach -n 0x1000')channel.send('\n')go += 1else: channel.send('ssh [email protected]')print("sending ssh command")elif 'assword:' in channel_data:channel.send('pass3')channel.send('\n')print("put the pass")breakstdin, stdout, stderr = ssh.exec_command('pwd')
print(stdout)
Next I tried using fabric to jump from one host to another. If I try to open a connection to Machine 3 or 4 with gateway settings, this exits with the error: ChannelException(2, 'Connect failed')
. If I try to run the lxc-attach command first, it just hangs forever.
import fabricmachine2 = fabric.Connection('192.168.2.2', user='user2', connect_kwargs={"password": "pass2"})
result = machine2.run('hostname')
print('machine2 hostname', result)
result = machine2.run('lxc-attach -n 0x1000')
print('machine2 lxc ', result)machine3 = fabric.Connection('192.168.3.2', user='user3', gateway=machine2, connect_kwargs={"password": "pass3"})
machine4 = fabric.Connection('192.168.4.2', user='user4', gateway=machine3, connect_kwargs={"password": "pass4"})result = machine3.run('hostname')
print('machine3 hostname', result)
Meta:
These similar questions about automating password entries:
- Shell script to automate SSH login using password
- Automate SSH login under windows
Are answered with "dont".
Martin pointed me toward jump hosting, but I haven't gotten it to work. For this topic, most questions seem to point back to this one:
- Nested SSH using Python Paramiko
I believe that my problem is trying to jump host through the container. It seems the lxc-attach command opens a raw shell that doesn't get passed back.
Is there a way to spawn a shell that acts more like it's interactive counterparts? I tried pexpect
, but Machine 1 is Windows, so it doesn't work. The commands on the Pexpect Windows Documentation exit with module 'pexpect' has no attribute 'popen_spawn'
.