lxc-attach: Add -s option to select namespaces to attach to

This patch allows the user to select any list of namespaces (network, pid,
mount, uts, ipc, user) that lxc-attach should use when attaching to the
container; all other namespaces will not be attached to.

This allows the user to for example attach to just the network namespace and
use the host's (and not the container's) network tools to reconfigure the
network of the container.

Signed-off-by: Christian Seiler <christian@iwakd.de>
Cc: Daniel Lezcano <daniel.lezcano@free.fr>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
This commit is contained in:
Christian Seiler 2012-08-22 00:03:15 +02:00 committed by Stéphane Graber
parent 39a5d5feee
commit e13eeea2db
2 changed files with 111 additions and 5 deletions

View File

@ -52,6 +52,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<arg choice="req">-n <replaceable>name</replaceable></arg> <arg choice="req">-n <replaceable>name</replaceable></arg>
<arg choice="opt">-a <replaceable>arch</replaceable></arg> <arg choice="opt">-a <replaceable>arch</replaceable></arg>
<arg choice="opt">-e</arg> <arg choice="opt">-e</arg>
<arg choice="opt">-s <replaceable>namespaces</replaceable></arg>
<arg choice="opt">-- <replaceable>command</replaceable></arg> <arg choice="opt">-- <replaceable>command</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -125,6 +126,29 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>-s, --namespaces <replaceable>namespaces</replaceable></option>
</term>
<listitem>
<para>
Specify the namespaces to attach to, as a pipe-separated liste,
e.g. <replaceable>NETWORK|IPC</replaceable>. Allowed values are
<replaceable>MOUNT</replaceable>, <replaceable>PID</replaceable>,
<replaceable>UTSNAME</replaceable>, <replaceable>IPC</replaceable>,
<replaceable>USER </replaceable> and
<replaceable>NETWORK</replaceable>. This allows one to change
the context of the process to e.g. the network namespace of the
container while retaining the other namespaces as those of the
host.
</para>
<para>
<emphasis>Important:</emphasis> This option implies
<option>-e</option>.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@ -147,19 +171,83 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</para> </para>
<para> <para>
To deactivate the network link eth1 of a running container that To deactivate the network link eth1 of a running container that
does not have the NET_ADMIN capability, use the <option>-e</option> does not have the NET_ADMIN capability, use either the
option to use increased capabilities: <option>-e</option> option to use increased capabilities,
assuming the <command>ip</command> tool is installed:
<programlisting> <programlisting>
lxc-attach -n container -e -- /sbin/ip link delete eth1 lxc-attach -n container -e -- /sbin/ip link delete eth1
</programlisting> </programlisting>
Or, alternatively, use the <option>-s</option> to use the
tools installed on the host outside the container:
<programlisting>
lxc-attach -n container -s NETWORK -- /sbin/ip link delete eth1
</programlisting>
</para> </para>
</refsect1> </refsect1>
<refsect1>
<title>Compatibility</title>
<para>
Attaching completely (including the pid and mount namespaces) to a
container requires a patched kernel, please see the lxc website for
details. <command>lxc-attach</command> will fail in that case if
used with an unpatched kernel.
</para>
<para>
Nevertheless, it will succeed on an unpatched kernel of version 3.0
or higher if the <option>-s</option> option is used to restrict the
namespaces that the process is to be attached to to one or more of
<replaceable>NETWORK</replaceable>, <replaceable>IPC</replaceable>
and <replaceable>UTSNAME</replaceable>.
</para>
<para>
Attaching to user namespaces is currently completely unsupported
by the kernel. <command>lxc-attach</command> should however be able
to do this once once future kernel versions implement this.
</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
The Linux <replaceable>/proc</replaceable> and
<replaceable>/sys</replaceable> filesystems contain information
about some quantities that are affected by namespaces, such as
the directories named after process ids in
<replaceable>/proc</replaceable> or the network interface infromation
in <replaceable>/sys/class/net</replaceable>. The namespace of the
process mounting the pseudo-filesystems determines what information
is shown, <emphasis>not</emphasis> the namespace of the process
accessing <replaceable>/proc</replaceable> or
<replaceable>/sys</replaceable>.
</para>
<para>
If one uses the <option>-s</option> option to only attach to
the pid namespace of a container, but not its mount namespace
(which will contain the <replaceable>/proc</replaceable> of the
container and not the host), the contents of <option>/proc</option>
will reflect that of the host and not the container. Analogously,
the same issue occurs when reading the contents of
<replaceable>/sys/class/net</replaceable> and attaching to just
the network namespace.
</para>
<para>
A workaround is to use <command>lxc-unshare</command> to unshare
the mount namespace after using <command>lxc-attach</command> with
<replaceable>-s PID</replaceable> and/or <replaceable>-s
NETWORK</replaceable> and then unmount and then mount again both
pseudo-filesystems within that new mount namespace, before
executing a program/script that relies on this information to be
correct.
</para>
</refsect1>
<refsect1> <refsect1>
<title>Security</title> <title>Security</title>
<para> <para>
The <option>-e</option> should be used with care, as it may break The <option>-e</option> and <option>-s</option> options should
the isolation of the containers if used improperly. be used with care, as it may break the isolation of the containers
if used improperly.
</para> </para>
</refsect1> </refsect1>

View File

@ -40,12 +40,14 @@
#include "start.h" #include "start.h"
#include "sync.h" #include "sync.h"
#include "log.h" #include "log.h"
#include "namespace.h"
lxc_log_define(lxc_attach_ui, lxc); lxc_log_define(lxc_attach_ui, lxc);
static const struct option my_longopts[] = { static const struct option my_longopts[] = {
{"elevated-privileges", no_argument, 0, 'e'}, {"elevated-privileges", no_argument, 0, 'e'},
{"arch", required_argument, 0, 'a'}, {"arch", required_argument, 0, 'a'},
{"namespaces", required_argument, 0, 's'},
LXC_COMMON_OPTIONS LXC_COMMON_OPTIONS
}; };
@ -55,6 +57,8 @@ static int namespace_flags = -1;
static int my_parser(struct lxc_arguments* args, int c, char* arg) static int my_parser(struct lxc_arguments* args, int c, char* arg)
{ {
int ret;
switch (c) { switch (c) {
case 'e': elevated_privileges = 1; break; case 'e': elevated_privileges = 1; break;
case 'a': case 'a':
@ -64,6 +68,14 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
return -1; return -1;
} }
break; break;
case 's':
namespace_flags = 0;
ret = lxc_fill_namespace_flags(arg, &namespace_flags);
if (ret)
return -1;
/* -s implies -e */
elevated_privileges = 1;
break;
} }
return 0; return 0;
@ -84,7 +96,13 @@ Options :\n\
WARNING: This may leak privleges into the container.\n\ WARNING: This may leak privleges into the container.\n\
Use with care.\n\ Use with care.\n\
-a, --arch=ARCH Use ARCH for program instead of container's own\n\ -a, --arch=ARCH Use ARCH for program instead of container's own\n\
architecture.\n", architecture.\n\
-s, --namespaces=FLAGS\n\
Don't attach to all the namespaces of the container\n\
but just to the following OR'd list of flags:\n\
MOUNT, PID, UTSNAME, IPC, USER or NETWORK\n\
WARNING: Using -s implies -e, it may therefore\n\
leak privileges into the container. Use with care.\n",
.options = my_longopts, .options = my_longopts,
.parser = my_parser, .parser = my_parser,
.checker = NULL, .checker = NULL,