Close paramiko connections explicitly
We have observed at least one case in the wild where an unreadable ssh private key file results in thousands of connections being made to Gerrit over a relatively short period of time. We expect this is due to newer paramiko behavior that requires you explicitly close connections (even when they fail). Fix this by adding explicit client closes. Change-Id: I713cb704ac24db5d38cd9c0c2d60962dca647f75 Story: 2000923
This commit is contained in:
parent
773651ad7b
commit
12d9aa67e6
|
@ -192,13 +192,16 @@ class GerritWatcher(threading.Thread):
|
|||
stdout.channel.close()
|
||||
ret = stdout.channel.recv_exit_status()
|
||||
self.log.debug("SSH exit status: %s" % ret)
|
||||
client.close()
|
||||
|
||||
if ret and ret not in [-1, 130]:
|
||||
raise Exception("Gerrit error executing stream-events")
|
||||
except:
|
||||
self.log.exception("Exception on ssh event stream:")
|
||||
time.sleep(5)
|
||||
finally:
|
||||
# If we don't close on exceptions to connect we can leak the
|
||||
# connection and DoS Gerrit.
|
||||
client.close()
|
||||
|
||||
def run(self):
|
||||
while not self._stopped:
|
||||
|
@ -353,16 +356,25 @@ class GerritConnection(BaseConnection):
|
|||
return alldata
|
||||
|
||||
def _open(self):
|
||||
client = paramiko.SSHClient()
|
||||
client.load_system_host_keys()
|
||||
client.set_missing_host_key_policy(paramiko.WarningPolicy())
|
||||
client.connect(self.server,
|
||||
username=self.user,
|
||||
port=self.port,
|
||||
key_filename=self.keyfile)
|
||||
transport = client.get_transport()
|
||||
transport.set_keepalive(self.keepalive)
|
||||
self.client = client
|
||||
if self.client:
|
||||
# Paramiko needs explicit closes, its possible we will open even
|
||||
# with an unclosed client so explicitly close here.
|
||||
self.client.close()
|
||||
try:
|
||||
client = paramiko.SSHClient()
|
||||
client.load_system_host_keys()
|
||||
client.set_missing_host_key_policy(paramiko.WarningPolicy())
|
||||
client.connect(self.server,
|
||||
username=self.user,
|
||||
port=self.port,
|
||||
key_filename=self.keyfile)
|
||||
transport = client.get_transport()
|
||||
transport.set_keepalive(self.keepalive)
|
||||
self.client = client
|
||||
except Exception:
|
||||
client.close()
|
||||
self.client = None
|
||||
raise
|
||||
|
||||
def _ssh(self, command, stdin_data=None):
|
||||
if not self.client:
|
||||
|
|
Loading…
Reference in New Issue