Hello Bevo, Thanks for you effort in Ganeti :)
On Fri, Sep 24, 2010 at 6:49 AM, Bevo <[email protected]> wrote: > I've created a patch to allow you to use a non root user for ssh > communication and allow you to specify a privilege escalation command > (sudo) We are doing efforts in privilege separation which is coming in Ganeti 2.3. The daemons will be fully separated except for ganeti-noded which needs still root privileges to do its job. Also the SSH code has been separated out of Ganeti core into setup-ssh which you find in the tools directory of your Ganeti (>=2.1) installation. This was needed to privilege separate the code as otherwise we would touch paths (mainly /etc/ssh and ~/.ssh) outside of Ganetis territory. > this basically sets 2 constants and removes the user argument from > sshrunner. > > Note: it would be nice to also have an argument to flag if the command > NEEDS privilege escalation so it can prefix the escalation command as > needed > > Comment and criticisms welcome As we postponed the efforts on further privilege separation for ganeti-noded until end of year you're welcome to do your own research and efforts in regard to that and spread them back to the community :). If you do so I would consider the master branch of our git repo to make sure you always have the latest updates. > Since google groups wont allow me to attached a file ill paste the > small patch inline: > <<EOF > diff -ub ../ganeti-orig/bootstrap.py ./bootstrap.py > --- ../ganeti-orig/bootstrap.py 2010-09-24 10:12:58.000000000 +1000 > +++ ./bootstrap.py 2010-09-24 11:59:52.000000000 +1000 > @@ -491,7 +491,7 @@ > constants.CONFD_HMAC_KEY, > constants.DAEMON_UTIL, constants.NODED)) > > - result = sshrunner.Run(node, 'root', mycommand, batch=False, > + result = sshrunner.Run(node, mycommand, batch=False, > ask_key=ssh_key_check, > use_cluster_key=False, > strict_host_check=ssh_key_check) > diff -ub ../ganeti-orig/cli.py ./cli.py > --- ../ganeti-orig/cli.py 2010-09-24 10:12:58.000000000 +1000 > +++ ./cli.py 2010-09-24 14:20:19.000000000 +1000 > @@ -1863,7 +1863,7 @@ > # No need to use SSH > result = utils.RunCmd(cmd) > else: > - result = self.ssh.Run(node_name, "root", > utils.ShellQuoteArgs(cmd)) > + result = self.ssh.Run(node_name, utils.ShellQuoteArgs(cmd)) > > if result.failed: > errmsg = ["Failed to run command %s" % result.cmd] > diff -ub ../ganeti-orig/cmdlib.py ./cmdlib.py > --- ../ganeti-orig/cmdlib.py 2010-09-24 10:12:58.000000000 +1000 > +++ ./cmdlib.py 2010-09-24 14:22:00.000000000 +1000 > @@ -6934,7 +6934,7 @@ > console_cmd = hyper.GetShellCommandForConsole(instance, hvparams, > beparams) > > # build ssh cmdline > - return self.ssh.BuildCmd(node, "root", console_cmd, batch=True, > tty=True) > + return self.ssh.BuildCmd(node, console_cmd, batch=True, tty=True) > > > class LUReplaceDisks(LogicalUnit): > Common subdirectories: ../ganeti-orig/confd and ./confd > diff -ub ../ganeti-orig/constants.py ./constants.py > --- ../ganeti-orig/constants.py 2010-09-24 10:12:58.000000000 +1000 > +++ ./constants.py 2010-09-24 11:46:18.000000000 +1000 > @@ -118,6 +118,10 @@ > TOOLSDIR = _autoconf.TOOLSDIR > CONF_DIR = SYSCONFDIR + "/ganeti" > > +# remote command setup > +REMOTE_SSH_USER = 'ganeti' We actually have already a similar constant called GANETI_RUNAS and which we already use in setup-ssh to setup the SSH environment. By default it's set to root, though not sure if you can reuse here. > +REMOTE_CMD_ESCALATION = '/usr/bin/sudo' This should be probably determined on configure time. Not every system has its sudo installed at the exact same spot. > + > ALL_CERT_FILES = frozenset([NODED_CERT_FILE, RAPI_CERT_FILE]) > > MASTER_SOCKET = SOCKET_DIR + "/ganeti-master" > Common subdirectories: ../ganeti-orig/http and ./http > Common subdirectories: ../ganeti-orig/hypervisor and ./hypervisor > Common subdirectories: ../ganeti-orig/rapi and ./rapi > diff -ub ../ganeti-orig/ssh.py ./ssh.py > --- ../ganeti-orig/ssh.py 2010-09-24 10:12:58.000000000 +1000 > +++ ./ssh.py 2010-09-24 14:33:43.000000000 +1000 > @@ -130,7 +130,7 @@ > > return options > > - def BuildCmd(self, hostname, user, command, batch=True, > ask_key=False, > + def BuildCmd(self, user, priv_escalation, hostname, command, > batch=True, ask_key=False, > tty=False, use_cluster_key=True, > strict_host_check=True, > private_key=None, quiet=True): > """Build an ssh command to execute a command on a remote node. > @@ -155,6 +155,9 @@ > argv.extend(self._BuildSshOptions(batch, ask_key, > use_cluster_key, > strict_host_check, private_key, > quiet=quiet)) > + > + command = priv_escalation + ' ' + command > + > if tty: > argv.extend(["-t", "-t"]) > argv.extend(["%...@%s" % (user, hostname), command]) > @@ -172,7 +175,7 @@ > @return: the result as from L{utils.RunCmd()} > > """ > - return utils.RunCmd(self.BuildCmd(*args, **kwargs)) > + return utils.RunCmd(self.BuildCmd(constants.REMOTE_SSH_USER, > constants.REMOTE_CMD_ESCALATION, *args, **kwargs)) > > def CopyFileToNode(self, node, filename): > """Copy a file to another node with scp. > @@ -225,7 +228,7 @@ > - detail: string with details > > """ > - retval = self.Run(node, 'root', 'hostname --fqdn') > + retval = self.Run(node, 'hostname --fqdn') > > if retval.failed: > msg = "ssh problem" > EOF > Thanks, René
