This is approximately the first half of the implemenation of the SSH related part of 'design-node-security.rst'. The goal of this patch series was to switch from one SSH key for all nodes to the following situation: - Every node now gets an individual SSH key. - SSH key distribution is only done via SSH itself, relying as little as possible on RPC security. - 'authorized_keys' files of all nodes contain only their own public key and the public keys of the master candidates. This way, SSH (and therefore root) access is limited to master candidates only. - SSH key distribution and removal is done properly for adding/removing/promotion/demotion of nodes. - Additional verification steps are added to check the SSH key setup.
Note a few things: - This patch series as a whole complies our QA. However, it was impossible to ensure that after every single patch. - This does not cover the complete SSH part of the design doc yet. The biggest part yet to come is the implemenation of RAPI security wrt to the SSH keys. Whoever will review this might wonder what 'potential master candidates' are. Those are nodes that are not master candidates yet, but which could be made master candidates using the respective RAPI command. As this patch series does not fully implement the RAPI part yet, the potential master candidates in this patch series are all normal nodes. Helga Velroyen (24): Removing unused imports from watcher Move InitSSH from bootstrap.py to ssh.py Ssh related code to ssh.py Infrastructure to manage public key file Init public key file and transfer authorized keys on node join Retrieve public SSH key from new node ssh.py: clear + overide pubkey + query all Introducing the 'ssh_update' tool Config: retrieve SSH ports and potential master candidates Key handling when adding a node Key removal in ssh.py and ssh_update.py Handling SSH keys on node removal Removing old SSH key when readding a node Generate individual SSH keys Verify SSH setup Handle SSH keys on node promotion and demotion Reduce number of statements in ClusterVerifyGroup Add key parameter to renew crypto opcode Unit test for InitSSHSetup Add option to "InitSSHSetup" to create additional keys Move function to fetch public keys to ssh Move GenerateRootSshKeys to tools/common Renew SSH keys and upgrade Mention SSH changes in NEWS file .gitignore | 1 + Makefile.am | 13 +- NEWS | 17 + UPGRADE | 21 + lib/backend.py | 464 +++++++++++++++- lib/bootstrap.py | 130 +---- lib/cli.py | 24 + lib/client/gnt_cluster.py | 72 ++- lib/client/gnt_node.py | 32 +- lib/cmdlib/cluster.py | 159 +++++- lib/cmdlib/node.py | 95 +++- lib/config.py | 62 ++- lib/errors.py | 6 + lib/pathutils.py | 2 + lib/rpc_defs.py | 32 ++ lib/server/noded.py | 38 ++ lib/ssh.py | 600 ++++++++++++++++++++- lib/tools/common.py | 108 ++++ lib/tools/prepare_node_join.py | 101 +--- lib/tools/ssh_update.py | 219 ++++++++ lib/utils/io.py | 89 --- lib/watcher/__init__.py | 2 - qa/qa_cluster.py | 7 +- src/Ganeti/Constants.hs | 34 ++ src/Ganeti/OpCodes.hs | 4 +- src/Ganeti/OpParams.hs | 14 + test/hs/Test/Ganeti/OpCodes.hs | 3 +- test/py/cmdlib/cluster_unittest.py | 67 ++- test/py/ganeti.backend_unittest.py | 447 +++++++++++++++ test/py/ganeti.client.gnt_cluster_unittest.py | 108 ++++ test/py/ganeti.mcpu_unittest.py | 1 - test/py/ganeti.ssh_unittest.py | 257 +++++++++ test/py/ganeti.tools.prepare_node_join_unittest.py | 75 +-- test/py/ganeti.tools.ssh_update_unittest.py | 163 ++++++ test/py/ganeti.utils.io_unittest.py | 68 --- test/py/testutils.py | 15 + tools/post-upgrade | 8 + 37 files changed, 3085 insertions(+), 473 deletions(-) create mode 100644 lib/tools/common.py create mode 100644 lib/tools/ssh_update.py create mode 100755 test/py/ganeti.tools.ssh_update_unittest.py -- 2.0.0.526.g5318336