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é

Reply via email to