reproman
reproman copied to clipboard
Make possible to establish ssh sessions via password authentication
- [x] if Fabric could ask for credentials (currently we just blow with
PasswordRequiredException) or we would need to catch/ask/provide - [ ] establish the controlpath for repeated relogins without authentication
here is the helper we have in DataLad https://github.com/datalad/datalad/blob/master/datalad/support/sshconnector.py#L67
- [ ] try Mux-transport-for-client branch of radssh which is now submitted as a PR https://github.com/paramiko/paramiko/pull/1341/files so we could pass
controlpath
The first go around with using the Mux-transport-for-client paramiko branch showed that the new code only connects to existing ControlMaster proxy connections and does not create them.
It was also found that the code depends on a ControlMaster running at least OpenSSH v7.4. Here is the exception raised when trying to connect to my locally setup control master using the ssh command line tool which has a version of OpenSSH_7.2p2:
Unable to connect to ControlPath '/home/matt/.ssh/ssh-root@localhost:32768' - Mux proxy
request rejected (Requires OpenSSH 7.4 or greater) - got unexpected reply: 0x80000003
paramiko.Message('\x00\x00\x00\x02\x00\x00\x00\x13unsupported request')
Was able to connect without a password via the ControlMaster process after setting up a openssh-client version >= v7.4 using the multiplexer branch of paramiko
so, that PR relies on this new version in 7.4: https://www.openssh.com/txt/release-7.4
* ssh(1): Add a proxy multiplexing mode to ssh(1) inspired by the
version in PuTTY by Simon Tatham. This allows a multiplexing
client to communicate with the master process using a subset of
the SSH packet and channels protocol over a Unix-domain socket,
with the main process acting as a proxy that translates channel
IDs, etc. This allows multiplexing mode to run on systems that
lack file- descriptor passing (used by current multiplexing
code) and potentially, in conjunction with Unix-domain socket
forwarding, with the client and multiplexing master process on
different machines. Multiplexing proxy mode may be invoked using
"ssh -O proxy ..."
from reading which it suggests that it was added primarily for "systems that lack file- descriptor passing (used by current multiplexing code) "... I wonder which systems those are? ;) anyways -- I think we could be hopeful and look forward. I.e. assume that this support will come in and enable it only in the cases where there is a recent enough openssh. Otherwise - keys/agents and retyping password.
On the call yesterday there was mention of keeping the password in memory with something like
diff --git a/reproman/resource/ssh.py b/reproman/resource/ssh.py
index cff875e2a..49134bad5 100644
--- a/reproman/resource/ssh.py
+++ b/reproman/resource/ssh.py
@@ -57,6 +57,8 @@ class SSH(Resource):
status = attrib()
_connection = attrib()
+ _password = None
+
def _connection_open(self):
try:
self.status = "CONNECTING"
@@ -84,6 +86,9 @@ def connect(self, password=None):
if self.key_filename:
key_filename = [self.key_filename]
+ if password is None:
+ password = self._password
+
self._connection = Connection(
self.host,
user=self.user,
@@ -117,6 +122,7 @@ def connect(self, password=None):
connect_kwargs={'password': password}
)
self._connection_open()
+ self._password = password
def create(self):
"""
But playing around with that, I don't think that's a viable approach (at least my simple-minded version above) because you still get hit with repeated password prompts from paramiko.
Observation: self._password binds to instance (which come and go), what if keep in a dict at class level with hosts as keys?
@yarikoptic:
Observation: self._password binds to instance (which come and go), what if keep in a dict at class level with hosts as keys?
My conclusion is based on instrumenting .connect(), and I get prompted (from paramiko, not our code, as I mentioned above) before entering .connect() a second time, so I don't think it matters. But I could of course be missing something, so please feel free to play around with that patch.