[lxc-devel] [PATCH] Add lxc-net tool
Christian Seiler
christian at iwakd.de
Thu May 17 16:26:41 UTC 2012
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;
+}
--
1.7.2.5
More information about the lxc-devel
mailing list