Commit 70d9e3d8 authored by Iustin Pop's avatar Iustin Pop
Browse files

Replace more ssh paths with proper constants

The node's ssh keys filenames are now provided as constants; this should
allow easier customization.

Also, the user's ssh key computing has been abstracted into ssh.py

Reviewed-by: imsnah
parent 2f8598a5
...@@ -88,28 +88,24 @@ def AddNode(dsa, dsapub, rsa, rsapub, sshkey, sshpub): ...@@ -88,28 +88,24 @@ def AddNode(dsa, dsapub, rsa, rsapub, sshkey, sshpub):
- adds the ssh public key to the users' authorized_keys file - adds the ssh public key to the users' authorized_keys file
""" """
user_dir = utils.GetHomeDir(constants.GANETI_RUNAS) sshd_keys = [(constants.SSH_HOST_RSA_PRIV, rsa, 0600),
if not user_dir: (constants.SSH_HOST_RSA_PUB, rsapub, 0644),
logger.Error("Cannot find home of run-as user %s" % constants.GANETI_RUNAS) (constants.SSH_HOST_DSA_PRIV, dsa, 0600),
return False (constants.SSH_HOST_DSA_PUB, dsapub, 0644)]
sshd_keys = [("ssh_host_rsa_key", rsa, 0600),
("ssh_host_rsa_key.pub", rsapub, 0644),
("ssh_host_dsa_key", dsa, 0600),
("ssh_host_dsa_key.pub", dsapub, 0644)]
for name, content, mode in sshd_keys: for name, content, mode in sshd_keys:
utils.WriteFile(os.path.join(constants.SSH_CONFIG_DIR, name), utils.WriteFile(name, data=content, mode=mode)
data=content, mode=mode)
user_ssh_dir = os.path.join(user_dir, ".ssh")
if not os.path.isdir(user_ssh_dir): try:
os.mkdir(user_ssh_dir) priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS,
mkdir=True)
except errors.OpExecError, err:
logger.Error("Error while processing user ssh files: %s" % err)
return False
for name, content in [("id_dsa", sshkey), ("id_dsa.pub", sshpub)]: for name, content in [(priv_key, sshkey), (pub_key, sshpub)]:
utils.WriteFile(os.path.join(user_ssh_dir, name), data=content, mode=0600) utils.WriteFile(name, data=content, mode=0600)
utils.AddAuthorizedKey(os.path.join(user_ssh_dir, "authorized_keys"), sshpub) utils.AddAuthorizedKey(auth_keys, sshpub)
utils.RunCmd([constants.SSH_INITD_SCRIPT, "restart"]) utils.RunCmd([constants.SSH_INITD_SCRIPT, "restart"])
...@@ -126,27 +122,21 @@ def LeaveCluster(): ...@@ -126,27 +122,21 @@ def LeaveCluster():
if os.path.isfile(full_name) and not os.path.islink(full_name): if os.path.isfile(full_name) and not os.path.islink(full_name):
utils.RemoveFile(full_name) utils.RemoveFile(full_name)
user_dir = utils.GetHomeDir(constants.GANETI_RUNAS)
if not user_dir:
logger.Error("Cannot find home of run-as user %s" % constants.GANETI_RUNAS)
return
user_ssh_dir = os.path.join(user_dir, ".ssh")
if not os.path.isdir(user_ssh_dir): try:
logger.Error("User's ssh dir '%s' does not exist?!" % user_ssh_dir) priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS)
except errors.OpExecError, err:
logger.Error("Error while processing ssh files: %s" % err)
return return
f = open(os.path.join(user_ssh_dir, "id_dsa.pub"), 'r') f = open(pub_key, 'r')
try: try:
utils.RemoveAuthorizedKey(os.path.join(user_ssh_dir, "authorized_keys"), utils.RemoveAuthorizedKey(auth_keys, f.read(8192))
f.read(8192))
finally: finally:
f.close() f.close()
utils.RemoveFile(priv_key)
utils.RemoveFile(os.path.join(user_ssh_dir, "id_dsa")) utils.RemoveFile(pub_key)
utils.RemoveFile(os.path.join(user_ssh_dir, "id_dsa.pub"))
def GetNodeInfo(vgname): def GetNodeInfo(vgname):
......
...@@ -476,24 +476,23 @@ def _InitSSHSetup(node): ...@@ -476,24 +476,23 @@ def _InitSSHSetup(node):
node: the name of this host as a fqdn node: the name of this host as a fqdn
""" """
if os.path.exists('/root/.ssh/id_dsa'): priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS)
utils.CreateBackup('/root/.ssh/id_dsa')
if os.path.exists('/root/.ssh/id_dsa.pub'):
utils.CreateBackup('/root/.ssh/id_dsa.pub')
utils.RemoveFile('/root/.ssh/id_dsa') for name in priv_key, pub_key:
utils.RemoveFile('/root/.ssh/id_dsa.pub') if os.path.exists(name):
utils.CreateBackup(name)
utils.RemoveFile(name)
result = utils.RunCmd(["ssh-keygen", "-t", "dsa", result = utils.RunCmd(["ssh-keygen", "-t", "dsa",
"-f", "/root/.ssh/id_dsa", "-f", priv_key,
"-q", "-N", ""]) "-q", "-N", ""])
if result.failed: if result.failed:
raise errors.OpExecError("Could not generate ssh keypair, error %s" % raise errors.OpExecError("Could not generate ssh keypair, error %s" %
result.output) result.output)
f = open('/root/.ssh/id_dsa.pub', 'r') f = open(pub_key, 'r')
try: try:
utils.AddAuthorizedKey('/root/.ssh/authorized_keys', f.read(8192)) utils.AddAuthorizedKey(auth_keys, f.read(8192))
finally: finally:
f.close() f.close()
...@@ -627,7 +626,7 @@ class LUInitCluster(LogicalUnit): ...@@ -627,7 +626,7 @@ class LUInitCluster(LogicalUnit):
rpc.call_node_start_master(hostname.name) rpc.call_node_start_master(hostname.name)
# set up ssh config and /etc/hosts # set up ssh config and /etc/hosts
f = open('/etc/ssh/ssh_host_rsa_key.pub', 'r') f = open(constants.SSH_HOST_RSA_PUB, 'r')
try: try:
sshline = f.read() sshline = f.read()
finally: finally:
...@@ -676,8 +675,9 @@ class LUDestroyCluster(NoHooksLU): ...@@ -676,8 +675,9 @@ class LUDestroyCluster(NoHooksLU):
"""Destroys the cluster. """Destroys the cluster.
""" """
utils.CreateBackup('/root/.ssh/id_dsa') priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS)
utils.CreateBackup('/root/.ssh/id_dsa.pub') utils.CreateBackup(priv_key)
utils.CreateBackup(pub_key)
rpc.call_node_leave_cluster(self.sstore.GetMasterNode()) rpc.call_node_leave_cluster(self.sstore.GetMasterNode())
...@@ -1508,10 +1508,11 @@ class LUAddNode(LogicalUnit): ...@@ -1508,10 +1508,11 @@ class LUAddNode(LogicalUnit):
# setup ssh on node # setup ssh on node
logger.Info("copy ssh key to node %s" % node) logger.Info("copy ssh key to node %s" % node)
priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS)
keyarray = [] keyarray = []
keyfiles = ["/etc/ssh/ssh_host_dsa_key", "/etc/ssh/ssh_host_dsa_key.pub", keyfiles = [constants.SSH_HOST_DSA_PRIV, constants.SSH_HOST_DSA_PUB,
"/etc/ssh/ssh_host_rsa_key", "/etc/ssh/ssh_host_rsa_key.pub", constants.SSH_HOST_RSA_PRIV, constants.SSH_HOST_RSA_PUB,
"/root/.ssh/id_dsa", "/root/.ssh/id_dsa.pub"] priv_key, pub_key]
for i in keyfiles: for i in keyfiles:
f = open(i, 'r') f = open(i, 'r')
......
...@@ -110,6 +110,10 @@ LOCALHOST_IP_ADDRESS="127.0.0.1" ...@@ -110,6 +110,10 @@ LOCALHOST_IP_ADDRESS="127.0.0.1"
TCP_PING_TIMEOUT = 10 TCP_PING_TIMEOUT = 10
GANETI_RUNAS = "root" GANETI_RUNAS = "root"
# external utilities # ssh constants
SSH_INITD_SCRIPT = _autoconf.SSH_INITD_SCRIPT SSH_INITD_SCRIPT = _autoconf.SSH_INITD_SCRIPT
SSH_CONFIG_DIR = "/etc/ssh" SSH_CONFIG_DIR = "/etc/ssh/"
SSH_HOST_DSA_PRIV = SSH_CONFIG_DIR + "ssh_host_dsa_key"
SSH_HOST_DSA_PUB = SSH_HOST_DSA_PRIV + ".pub"
SSH_HOST_RSA_PRIV = SSH_CONFIG_DIR + "ssh_host_rsa_key"
SSH_HOST_RSA_PUB = SSH_HOST_RSA_PRIV + ".pub"
...@@ -55,6 +55,41 @@ ASK_KEY_OPTS = [ ...@@ -55,6 +55,41 @@ ASK_KEY_OPTS = [
] ]
def GetUserFiles(user, mkdir=False):
"""Return the paths of a user's ssh files.
The function will return a triplet (priv_key_path, pub_key_path,
auth_key_path) that are used for ssh authentication. Currently, the
keys used are DSA keys, so this function will return:
(~user/.ssh/id_dsa, ~user/.ssh/id_dsa.pub,
~user/.ssh/authorized_keys).
If the optional parameter mkdir is True, the ssh directory will be
created if it doesn't exist.
Regardless of the mkdir parameters, the script will raise an error
if ~user/.ssh is not a directory.
"""
user_dir = utils.GetHomeDir(user)
if not user_dir:
raise errors.OpExecError("Cannot resolve home of user %s" % user)
ssh_dir = os.path.join(user_dir, ".ssh")
if not os.path.lexists(ssh_dir):
if mkdir:
try:
os.mkdir(ssh_dir, 0700)
except EnvironmentError, err:
raise errors.OpExecError("Can't create .ssh dir for user %s: %s" %
(user, str(err)))
elif not os.path.isdir(ssh_dir):
raise errors.OpExecError("path ~%s/.ssh is not a directory" % user)
return [os.path.join(ssh_dir, base)
for base in ["id_dsa", "id_dsa.pub", "authorized_keys"]]
def BuildSSHCmd(hostname, user, command, batch=True, ask_key=False): def BuildSSHCmd(hostname, user, command, batch=True, ask_key=False):
"""Build an ssh string to execute a command on a remote node. """Build an ssh string to execute a command on a remote node.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment