-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
customizable host key policy #2072
Conversation
Thanks to `_KaszpiR_` on IRC for the report!
One getattr and dozens of test/doc lines later...
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
fb0fc6b
to
d6fc866
Compare
i got as far as this for the unit tests, which is "not very": modified tests/connection.py
@@ -12,6 +12,7 @@
from mock import patch, Mock, call, ANY
from paramiko.client import SSHClient, AutoAddPolicy
from paramiko import SSHConfig
+from paramiko.ssh_exception import BadHostKeyException
import pytest # for mark
from pytest import skip, param
from pytest_relaxed import raises
@@ -1154,3 +1155,10 @@ def tunnel_errors_bubble_up(self):
def listener_errors_bubble_up(self):
skip()
+
+ class known_hosts:
+ @raises(BadHostKeyException)
+ def changed_host_key_fails(self):
+ c = Connection('localhost')
+ c.open()
+ |
the test suite fails, but that's because sphinx cannot reach pyinvoke.org, i doubt it's related to this patch:
https://travis-ci.org/github/fabric/fabric/jobs/664111778 ... not sure what's up with that, but it's true i'm having trouble reaching pyinvoke.org myself |
#2073 should fix that particular build issue. |
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
d6fc866
to
3c0ed28
Compare
rebased on top of #2073 because that actually fixes the test suite |
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
3c0ed28
to
33dc279
Compare
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
33dc279
to
f876b7f
Compare
It looks like http://pyinvoke.org/ does not respond. Assume the correct URL is www.pyinvoke.org instead, which does. And while we're here, switch all of those to HTTPS because we're in the future now and HTTPS just works.
This is essential in case we want Fabric library consumers and users to override the Paramiko host key policy. One, for example, might want to override the default to prompt users when a new key needs to be added (which is silently done by default right now).
This removes the Fabric-specific host key policy which is to automatically accept new keys. I don't see why Fabric would do anything different than the default here at this stage, especially since we don't seem to be *loading* any keys, let alone saving them. This is a stopgap measure to fix fabric#2071
This has the following consequences: 1. the AutoAddPolicy starts to work correctly, as the `load_host_keys` call signals that it should save new fingerprints to the known_hosts file 2. it will also correctly *fail* if the fingerprint on a host changes, which was *not* the case before, as the known_hosts file was never loaded 3. it will correctly load the right `UserKnownHostsFile` according to the rules defined in the ssh configuration Regarding the last point, that is essential in my setup because I have a config block like this: Host *.example.com UserKnownHostsFile ~/.ssh/known_hosts.example.com ... which allows me to "group" known_hosts file and synchronize them from remote servers.
This covers the following use case: Host *.example.org UserKnownHostsFile ~/.ssh/known_hosts ~/.ssh/known_hosts.example.org ... which is also valid.
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
f876b7f
to
8242052
Compare
this needs to be republished against the master branch, sorry for the noise. :( |
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
This makes it easier to monkeypatch to earlier versions. With this patch, I can copy-paste the setup_ssh_client() function into my code and monkeypatch older fabric versions with: # hack to fix Fabric key policy: # fabric#2071 def safe_open(self): SaferConnection.setup_ssh_client(self) Connection.open_orig(self) class SaferConnection(Connection): # this function is a copy-paste from fabric#2072 def setup_ssh_client(self): # [...] Connection.open_orig = Connection.open Connection.open = safe_open This is otherwise a noop.
The current Fabric code does not check or save SSH host keys at all. This PR fixes the problem by ensuring we properly call the Paramiko SSH keys loader when we create our connection object.
We also load the right UserKnownHosts file based on the ssh_config, which paramiko does not do out of the box.
We might want to push the latter into paramiko, but first it seems to me the default Fabric policy of "everything goes" should b fixed.
Note that this also allows callers to override the
AutoAddPolicy
that is currently in use.This should fix #2071