Reputation: 2308
I have previously written a program for a linux env which automatically runs the SSHFS binary as a user and inputs a stored ssh private key passphrase. (the public half is already on the remote server) I had this working with simple pexpect commands on one server. (Ubuntu server 14.04, ssh version 6.6, sshfs version 2.5) But this single piece of the program is proving to be an issue when the application has been moved to a redhat machine (RHEL6.5, ssh version 5.3, sshfs version 2.4) This simple step has been driving me crazy all day so now I turn to this community for support. My original code (simplified) looked like this:
proc = pexpect.spawn('sshfs %s@%s:%s...') #many options, unrelated
proc.expect([pexpect.EOF, 'Enter passphrase for key.*', pexpect.TIMEOUT], timeout=30)
if proc.match_index == 1:
proc.sendline('thepassphrase')
Which runs as expected on ubuntu but not rhel. I have also tried the fallback method of piping to subprocess without much success either.
proc = subprocess.Popen('sshfs %s@%s:%s...', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.stdin.write('thepassphrase'+'\n')
proc.stdin.flush()
Of course I have tried many slight variations of this without success, and of course the command runs fine when I run it manually.
Update 3/3: I have also today manually compiled and installed ssh 6.6 in rhel to see if that was causing the issue, but the issue persists even with the new ssh binary.
Update 3/9:
Today I have found one particular solution which works, but I am not happy with the fact that many other different solutions did not work, and I am still looking for the answer as to why. Here is the best I could do so far:
proc = subprocess.check_call("sudo -H -u %s ssh-keygen -p -P %s -N '' -f %s" % (user, userKey['passphrase'], userKey['path']), shell=True)
time.sleep(2)
proc = subprocess.Popen(cmd, shell=True)
proc.communicate()
time.sleep(1)
proc = subprocess.check_call("sudo -H -u %s ssh-keygen -p -P '' -N %s -f %s" % (user, userKey['passphrase'], userKey['path']), shell=True)
Removes the passphrase from the key, mounts the drive, and then re-adds the key. Obviously I don't like this solution, but it will have to do until I can get to the bottom of this.
Update 3/23:
Well due to my stupidity I did not see the immediate problem with this method until now and now I am back to the drawing board. While this workaround does work for the first time the connection is made, the -o reconnect obviously fails because sshfs does not know the passphrase to reconnect. This means that this solution is no longer viable, and I would really if anyone knows how to get the pexpect version working.
Upvotes: 3
Views: 3941
Reputation: 2308
After talking to the developer personally, I have determined that this is now a known bug and that there was not a proper method of running the command in the same style as specified in the question. However, the developer quickly came forward with an equally useful method which involved spawning another terminal process.
passphrase = 'some passphrase'
cmd = "sudo -H -u somebody sshfs somebody@somewhere:/somewhere-else /home/somebody/testmount -o StrictHostKeychecking=no -o nonempty -o reconnect -o workaround=all -o IdentityFile=/somekey -o follow_symlinks -o cache=no"
bash = pexpect.spawn('bash', echo=False)
bash.sendline('echo READY')
bash.expect_exact('READY')
bash.sendline(cmd)
bash.expect_exact('Enter passphrase for key')
bash.sendline(passphrase)
bash.sendline('echo COMPLETE')
bash.expect_exact('COMPLETE')
bash.sendline('exit')
bash.expect_exact(pexpect.EOF)
I have tested this solution and it has worked as a good workaround without very much extra overhead. You may view his full response here.
Upvotes: 1