[lxc-devel] [PATCH] Add lxc-net tool

Stéphane Graber stgraber at ubuntu.com
Thu May 17 17:38:56 UTC 2012


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

On 05/17/2012 12:26 PM, Christian Seiler wrote:
> Add a tool that switches context to enter the network namespace and
> then execute an arbitrary command. Since we don't change mount /
> pid namespaces, this allows the user to use the host's networking
> tools such as iputils, iptables, netstat to query / configure the
> container from the outside. This may be especially useful for
> administrators who have dropped network configuration capabilities
> inside the container as a security measure.
> 
> Since network namespace switching via setns() was introduced in
> kernel 3.0, this tool will work with any newer vanilla kernel
> version. --- configure.ac        |    1 + doc/Makefile.am     |
> 1 + doc/lxc-net.sgml.in |  131
> +++++++++++++++++++++++++++++++++++++++++++++++++++ 
> src/lxc/Makefile.am |    4 +- src/lxc/attach.c    |   22 +++++++++ 
> src/lxc/attach.h    |    1 + src/lxc/lxc_net.c   |   92
> ++++++++++++++++++++++++++++++++++++ 7 files changed, 251
> insertions(+), 1 deletions(-) create mode 100644
> doc/lxc-net.sgml.in create mode 100644 src/lxc/lxc_net.c
> 
> diff --git a/configure.ac b/configure.ac index 0c8aa69..8605102
> 100644 --- a/configure.ac +++ b/configure.ac @@ -120,6 +120,7 @@
> AC_CONFIG_FILES([ doc/lxc-cgroup.sgml doc/lxc-kill.sgml 
> doc/lxc-attach.sgml +	doc/lxc-net.sgml doc/lxc.conf.sgml 
> doc/lxc.sgml doc/common_options.sgml diff --git a/doc/Makefile.am
> b/doc/Makefile.am index b18c5eb..fd1a58b 100644 ---
> a/doc/Makefile.am +++ b/doc/Makefile.am @@ -24,6 +24,7 @@ man_MANS
> = \ lxc-cgroup.1 \ lxc-kill.1 \ lxc-attach.1 \ +	lxc-net.1 \ \ 
> lxc.conf.5 \ \ diff --git a/doc/lxc-net.sgml.in
> b/doc/lxc-net.sgml.in new file mode 100644 index 0000000..b675b4f 
> --- /dev/null +++ b/doc/lxc-net.sgml.in @@ -0,0 +1,131 @@ +<!-- + 
> +lxc: linux Container library + +(C) Copyright IBM Corp. 2007,
> 2008 + +Authors: +Daniel Lezcano <dlezcano at fr.ibm.com> + +This
> library is free software; you can redistribute it and/or +modify it
> under the terms of the GNU Lesser General Public +License as
> published by the Free Software Foundation; either +version 2.1 of
> the License, or (at your option) any later version. + +This library
> is distributed in the hope that it will be useful, +but WITHOUT ANY
> WARRANTY; without even the implied warranty of +MERCHANTABILITY or
> FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +Lesser General
> Public License for more details. + +You should have received a copy
> of the GNU Lesser General Public +License along with this library;
> if not, write to the Free Software +Foundation, Inc., 59 Temple
> Place, Suite 330, Boston, MA 02111-1307 USA + +--> + +<!DOCTYPE
> refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [ + +<!ENTITY
> commonoptions SYSTEM "@builddir@/common_options.sgml"> +<!ENTITY
> seealso SYSTEM "@builddir@/see_also.sgml"> +]> + +<refentry> + +
> <docinfo><date>@LXC_GENERATE_DATE@</date></docinfo> + +  <refmeta> 
> +    <refentrytitle>lxc-net</refentrytitle> +
> <manvolnum>1</manvolnum> +  </refmeta> + +  <refnamediv> +
> <refname>lxc-net</refname> + +    <refpurpose> +      run a process
> in the network context of a container +    </refpurpose> +
> </refnamediv> + +  <refsynopsisdiv> +
> <cmdsynopsis><command>lxc-net <replaceable>-n +
> name</replaceable> -- command</command></cmdsynopsis> +
> </refsynopsisdiv> + +  <refsect1> +    <title>Description</title> 
> + +    <para> +      <command>lxc-net</command> runs the specified 
> +      <replaceable>command</replaceable> inside the network +
> namespace of the container specified by +
> <replaceable>name</replaceable>. The container +      has to be
> running already. +    </para> +    <para> +      This may be used
> to query or modify the network +      devices of a container from
> the outside. Note that +      the executable itself must reside
> outside of the +      container, since only the network namespace
> is +      changed; the command will still see the file system +
> and process ids of the outside container. +    </para> + +
> </refsect1> + +  &commonoptions; + +  <refsect1> +
> <title>Examples</title> +      <para> +        To show the ip
> addresses of the devices of a container, +        assuming iputils
> is installed outside, use +        <programlisting> +
> lxc-net -n container -- ip -4 addr show +        </programlisting> 
> +      </para> +      <para> +        To show the connections
> inside a container via netstat +        <programlisting> +
> lxc-net -n container -- netstat +        </programlisting> +
> </para> +      <para> +        To add an iptables filter rule +
> <programlisting> +          lxc-net -n container -- iptables -A
> INPUT -d someip -j DROP +        </programlisting> +      </para> +
> </refsect1> + +  <refsect1> +    <title>Notes</title> +    <para> +
> This requires kernel version 3.0 to work. +    </para> +
> </refsect1> + +  &seealso; + +  <refsect1> +
> <title>Author</title> +    <para>Daniel Lezcano
> <email>daniel.lezcano at free.fr</email></para> +  </refsect1> + 
> +</refentry> + +<!-- Keep this comment at the end of the file 
> +Local variables: +mode: sgml +sgml-omittag:t +sgml-shorttag:t 
> +sgml-minimize-attributes:nil +sgml-always-quote-attributes:t 
> +sgml-indent-step:2 +sgml-indent-data:t +sgml-parent-document:nil 
> +sgml-default-dtd-file:nil +sgml-exposed-tags:nil 
> +sgml-local-catalogs:nil +sgml-local-ecat-files:nil +End: +--> diff
> --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index
> 1c26952..7b6f795 100644 --- a/src/lxc/Makefile.am +++
> b/src/lxc/Makefile.am @@ -95,7 +95,8 @@ bin_PROGRAMS = \ 
> lxc-unfreeze \ lxc-checkpoint \ lxc-restart \ -	lxc-kill +	lxc-kill
> \ +	lxc-net
> 
> pkglibexec_PROGRAMS = \ lxc-init @@ -122,6 +123,7 @@
> lxc_unfreeze_SOURCES = lxc_unfreeze.c lxc_unshare_SOURCES =
> lxc_unshare.c lxc_wait_SOURCES = lxc_wait.c lxc_kill_SOURCES =
> lxc_kill.c +lxc_net_SOURCES = lxc_net.c
> 
> install-exec-local: install-soPROGRAMS mv
> $(DESTDIR)$(libdir)/liblxc.so
> $(DESTDIR)$(libdir)/liblxc.so.$(VERSION) diff --git
> a/src/lxc/attach.c b/src/lxc/attach.c index a95b3d3..45a3fd3
> 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -156,6
> +156,28 @@ int lxc_attach_to_ns(pid_t pid) return 0; }
> 
> +int lxc_attach_to_ns_type(pid_t pid, char *type) +{ +	char
> path[MAXPATHLEN]; +	int fd; + +	snprintf(path, MAXPATHLEN,
> "/proc/%d/ns/%s", pid, type); +	fd = open(path, O_RDONLY); +	if (fd
> < 0) { +		SYSERROR("failed to open '%s'", path); +		return -1; +	} 
> + +	if (setns(fd, 0)) { +		SYSERROR("failed to set namespace '%s'",
> type); +		return -1; +	} + +	close(fd); + +	return 0; +} + int
> lxc_attach_drop_privs(struct lxc_proc_context_info *ctx) { int
> last_cap = lxc_caps_last_cap(); diff --git a/src/lxc/attach.h
> b/src/lxc/attach.h index 2d46c83..0cfd6ae 100644 ---
> a/src/lxc/attach.h +++ b/src/lxc/attach.h @@ -34,6 +34,7 @@ struct
> lxc_proc_context_info { extern struct lxc_proc_context_info
> *lxc_proc_get_context_info(pid_t pid);
> 
> extern int lxc_attach_to_ns(pid_t other_pid); +extern int
> lxc_attach_to_ns_type(pid_t pid, char *type); extern int
> lxc_attach_drop_privs(struct lxc_proc_context_info *ctx);
> 
> #endif diff --git a/src/lxc/lxc_net.c b/src/lxc/lxc_net.c new file
> mode 100644 index 0000000..80f2ffd --- /dev/null +++
> b/src/lxc/lxc_net.c @@ -0,0 +1,92 @@ +/* + * lxc: linux Container
> library + * + * (C) Copyright IBM Corp. 2007, 2010 + * + *
> Authors: + * Daniel Lezcano <dlezcano at fr.ibm.com> + * + * This
> library is free software; you can redistribute it and/or + * modify
> it under the terms of the GNU Lesser General Public + * License as
> published by the Free Software Foundation; either + * version 2.1
> of the License, or (at your option) any later version. + * + * This
> library is distributed in the hope that it will be useful, + * but
> WITHOUT ANY WARRANTY; without even the implied warranty of + *
> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +
> * Lesser General Public License for more details. + * + * You
> should have received a copy of the GNU Lesser General Public + *
> License along with this library; if not, write to the Free
> Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#include <unistd.h> 
> +#include <errno.h> +#include <pwd.h> +#include <stdlib.h> 
> +#include <sys/param.h> +#include <sys/types.h> +#include
> <sys/wait.h> +#include <sys/personality.h> + +#include "attach.h" 
> +#include "commands.h" +#include "arguments.h" +#include
> "confile.h" +#include "log.h" + +lxc_log_define(lxc_net_ui, lxc); 
> + +static const struct option my_longopts[] = { +
> LXC_COMMON_OPTIONS +}; + +static struct lxc_arguments my_args = { +
> .progname = "lxc-net", +	.help     = "\ +--name=NAME\n\ +\n\ 
> +Execute the specified command - in the network namespace of
> container NAME\n\ +\n\ +Options :\n\ +  -n, --name=NAME   NAME for
> name of the container", +	.options  = my_longopts, +	.parser   =
> NULL, +	.checker  = NULL, +}; + +int main(int argc, char *argv[]) 
> +{ +	int ret; +	pid_t init_pid; + +	ret =
> lxc_arguments_parse(&my_args, argc, argv); +	if (ret) +		return
> ret; + +	if (!my_args.argc) { +		ERROR("usage: %s -n container --
> command", argv[0]); +		return -1; +	} + +	ret =
> lxc_log_init(my_args.log_file, my_args.log_priority, +
> my_args.progname, my_args.quiet); +	if (ret) +		return ret; + +
> init_pid = get_init_pid(my_args.name); +	if (init_pid < 0) { +
> ERROR("failed to get the init pid"); +		return -1; +	} + +	ret =
> lxc_attach_to_ns_type(init_pid, "net"); +	if (ret) +		return ret; 
> + +	execvp(my_args.argv[0], my_args.argv); +	SYSERROR("failed to
> exec '%s'", my_args.argv[0]); +	return -1; +}

We recently discussed during a session at the Ubuntu Developer Summit
that we should instead update lxc-attach to allow attaching to only a
subset of the namespaces. I believe this would also cover your use case.

I don't think having a separate command for each namespace we may want
to attach to is a good idea, if only because it'd make it even more
confusing for the user trying to figure out what
lxc-attach/lxc-execute/lxc-unshare/lxc-net/... all do.


Until lxc-attach is extended (Serge Hallyn took that action item), I
suggest using this very simple script to switch network namespaces:
http://paste.ubuntu.com/992744/

Then run something like:
sudo sh getip.sh my-container "ip -4 addr show"

- -- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBCgAGBQJPtTewAAoJEMY4l01keS1ntGUP/A37IaQa0mio6xodNAUP7oeO
nwP/nF+hrQMb3auwPzgLPLHykjLJ1JKVH5/rSbduIqaufpzMEBgece29xMMpueZ5
+gv6y46aZOkU9moAyhlrMcBlcWUILzkEXJY00in28mArcTKhLBw+bpPWmJiRRHlk
j3FNWoqeTUgdp0cEOps1QTPTC5Ex72TcSEz/I/Zust/nJftikH35D5Pad93zQed3
X1zqsD+aCOWAqy/vb9DQUkNlhjo2tmxm22sIHUHa9CkVGNt41tH3YIKDKMjFuyim
WTEucHaTIKlTVGtZ+LbiBA00RrAww+0RemgV6eXgW7jM45SeTTj5/ttKtMOoI+Kl
VIC27VrKjKIjMleDLA04zyitcjiElp4axbzQSqPV3hjsLX8n0k1HVpZyBYzLKYh6
QrynQSLCZPS25N/5G/As57JRNuucJucyHgYtauOd3OR4rzjuP4ZeGAXkqQWjXJqE
En0QCpCrQea7uE9BBwiRYfd0jICmeEu1RmmpMyROQwW019SxvcvQF2YY1zRCSxi7
A3440XXzOFkIb8R3ThGq0EZ92UoCPw4WYsscY5DwcewNDM34ehJQX315AMTuFw/L
bBtrZDp7ZC9r4i4M8bOSnwU3OJqTIPMNFF/wZWvR/pPrfsCPt73qK5pHjgAcRndr
mvqwpJGcxcialV22PvxF
=AFcG
-----END PGP SIGNATURE-----




More information about the lxc-devel mailing list