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

Serge Hallyn serge.hallyn at canonical.com
Thu May 17 17:31:08 UTC 2012


Quoting Christian Seiler (christian at iwakd.de):
> 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.

I think it would be better to update lxc-attach to take '-s NET|MOUNT',
as lxc-unshare does, meaning "only attach to those namespaces".

> ---
>  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;
> +}
> -- 
> 1.7.2.5
> 
> 
> ------------------------------------------------------------------------------
> Live Security Virtual Conference
> Exclusive live event will cover all the ways today's security and 
> threat landscape has changed and how IT managers can respond. Discussions 
> will include endpoint security, mobile security and the latest in malware 
> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel




More information about the lxc-devel mailing list