Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
a38fa3d1
Unverified
Commit
a38fa3d1
authored
Apr 05, 2019
by
Stéphane Graber
Committed by
GitHub
Apr 05, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2924 from brauner/2019-04-05/lxc_user_nice_update
lxc-user-nic: update
parents
4f34c6f9
ff63fd78
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
117 additions
and
64 deletions
+117
-64
lxc-user-nic.sgml.in
doc/lxc-user-nic.sgml.in
+59
-6
lxc_user_nic.c
src/lxc/cmd/lxc_user_nic.c
+58
-58
No files found.
doc/lxc-user-nic.sgml.in
View file @
a38fa3d1
...
...
@@ -42,17 +42,31 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<refname>lxc-user-nic</refname>
<refpurpose>
Create and attach a nic to another network namespace.
Manage nics in another network namespace
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-user-nic</command>
<command>create</command>
<arg choice="req"><replaceable>lxcpath</replaceable></arg>
<arg choice="req"><replaceable>name</replaceable></arg>
<arg choice="req"><replaceable>pid</replaceable></arg>
<arg choice="req"><replaceable>type</replaceable></arg>
<arg choice="req"><replaceable>bridge</replaceable></arg>
<arg choice="opt"><replaceable>nicname</replaceable></arg>
<arg choice="req"><replaceable>container nicname</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>lxc-user-nic</command>
<command>delete</command>
<arg choice="req"><replaceable>lxcpath</replaceable></arg>
<arg choice="req"><replaceable>name</replaceable></arg>
<arg choice="req"><replaceable>path to network namespace</replaceable></arg>
<arg choice="req"><replaceable>type</replaceable></arg>
<arg choice="req"><replaceable>bridge</replaceable></arg>
<arg choice="req"><replaceable>container nicname</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
...
...
@@ -61,7 +75,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<para>
<command>lxc-user-nic</command> is a setuid-root program with which
unprivileged users may create network interfaces for use by a lxc container.
unprivileged users may manage network interfaces for use by a
lxc container.
</para>
<para>
It will consult the configuration file <filename>@LXC_USERNIC_CONF@</filename>
...
...
@@ -71,6 +86,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<filename>@LXC_USERNIC_DB@</filename>. It ensures that the calling
user is privileged over the network namespace to which the interface
will be attached.
<command>lxc-user-nic</command> also allows to delete network devices.
Currently only ovs ports can be deleted.
</para>
</refsect1>
...
...
@@ -80,6 +97,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option><replaceable>lxcpath</replaceable></option>
</term>
<listitem>
<para>
The path of the container. This is currently not used.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><replaceable>name</replaceable></option>
</term>
<listitem>
<para>
The name of the container. This is currently not used.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
...
...
@@ -99,7 +137,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</term>
<listitem>
<para>
The network interface type to attach.
Currently only veth is
The network interface type to attach. Currently only veth is
supported. With this type, two interfaces representing each
tunnel endpoint are created. One endpoint will be attached
to the specified bridge, while the other will be passed into
...
...
@@ -122,16 +160,29 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<varlistentry>
<term>
<option><replaceable>nicname</replaceable></option>
<option><replaceable>
container
nicname</replaceable></option>
</term>
<listitem>
<para>
The desired interface name in the container.
This will be
The desired interface name in the container. This will be
<filename>eth0</filename> if unspecified.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><replaceable>path to network namespace</replaceable></option>
</term>
<listitem>
<para>
A path to open to get a file descriptor for the target
network namespace.
This is only relevant when an veth device is deleted.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
...
...
@@ -159,6 +210,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<refsect1>
<title>Author</title>
<para>Christian Brauner <email>christian@brauner.io</email></para>
<para>Serge Hallyn <email>serge@hallyn.com</email></para>
<para>Daniel Lezcano <email>daniel.lezcano@free.fr</email></para>
</refsect1>
...
...
src/lxc/cmd/lxc_user_nic.c
View file @
a38fa3d1
...
...
@@ -47,6 +47,7 @@
#include <sys/types.h>
#include <unistd.h>
#include "compiler.h"
#include "config.h"
#include "log.h"
#include "memory_utils.h"
...
...
@@ -69,13 +70,17 @@
#define usernic_error(format, ...) usernic_debug_stream(stderr, format, __VA_ARGS__)
static
void
usage
(
char
*
me
,
bool
fail
)
__noreturn
static
void
usage
(
bool
fail
)
{
fprintf
(
stderr
,
"Usage: %s create {lxcpath} {name} {pid} {type} "
"{bridge} {nicname}
\n
"
,
me
);
fprintf
(
stderr
,
"Usage: %s delete {lxcpath} {name} "
"{/proc/<pid>/ns/net} {type} {bridge} {nicname}
\n
"
,
me
);
fprintf
(
stderr
,
"{nicname} is the name to use inside the container
\n
"
);
fprintf
(
stderr
,
"Description:
\n
"
);
fprintf
(
stderr
,
" Manage nics in another network namespace
\n\n
"
);
fprintf
(
stderr
,
"Usage:
\n
"
);
fprintf
(
stderr
,
" lxc-user-nic [command]
\n\n
"
);
fprintf
(
stderr
,
"Available Commands:
\n
"
);
fprintf
(
stderr
,
" create {lxcpath} {name} {pid} {type} {bridge} {container nicname}
\n
"
);
fprintf
(
stderr
,
" delete {lxcpath} {name} {/proc/<pid>/ns/net} {type} {bridge} {container nicname}
\n
"
);
if
(
fail
)
_exit
(
EXIT_FAILURE
);
...
...
@@ -83,9 +88,10 @@ static void usage(char *me, bool fail)
_exit
(
EXIT_SUCCESS
);
}
static
int
open_and_lock
(
char
*
path
)
static
int
open_and_lock
(
c
onst
c
har
*
path
)
{
int
fd
,
ret
;
__do_close_prot_errno
int
fd
=
-
EBADF
;
int
ret
;
struct
flock
lk
;
fd
=
open
(
path
,
O_RDWR
|
O_CREAT
,
S_IWUSR
|
S_IRUSR
);
...
...
@@ -102,11 +108,10 @@ static int open_and_lock(char *path)
ret
=
fcntl
(
fd
,
F_SETLKW
,
&
lk
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to lock
\"
%s
\"\n
"
,
path
);
close
(
fd
);
return
-
1
;
}
return
fd
;
return
move_fd
(
fd
)
;
}
static
char
*
get_username
(
void
)
...
...
@@ -881,16 +886,15 @@ static char *lxc_secure_rename_in_ns(int pid, char *oldname, char *newname,
close
(
fd
);
fd
=
-
1
;
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to setns() to the network namespace of
"
"the container with PID %d
\n
"
,
pid
);
CMD_SYSERROR
(
"Failed to setns() to the network namespace of
the container with PID %d
\n
"
,
pid
);
goto
do_partial_cleanup
;
}
ret
=
setresuid
(
ruid
,
ruid
,
0
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to drop privilege by setting effective "
"user id and real user id to %d, and saved user "
"ID to 0
\n
"
,
ruid
);
CMD_SYSERROR
(
"Failed to drop privilege by setting effective user id and real user id to %d, and saved user ID to 0
\n
"
,
ruid
);
/* It's ok to jump to do_full_cleanup here since setresuid()
* will succeed when trying to set real, effective, and saved to
* values they currently have.
...
...
@@ -936,18 +940,15 @@ static char *lxc_secure_rename_in_ns(int pid, char *oldname, char *newname,
do_full_cleanup:
ret
=
setresuid
(
ruid
,
euid
,
suid
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to restore privilege by setting "
"effective user id to %d, real user id to %d, "
"and saved user ID to %d
\n
"
,
ruid
,
euid
,
suid
);
CMD_SYSERROR
(
"Failed to restore privilege by setting effective user id to %d, real user id to %d, and saved user ID to %d
\n
"
,
ruid
,
euid
,
suid
);
string_ret
=
NULL
;
}
ret
=
setns
(
ofd
,
CLONE_NEWNET
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to setns() to original network namespace "
"of PID %d
\n
"
,
ofd
);
CMD_SYSERROR
(
"Failed to setns() to original network namespace of PID %d
\n
"
,
ofd
);
string_ret
=
NULL
;
}
...
...
@@ -981,9 +982,8 @@ static bool may_access_netns(int pid)
ret
=
setresuid
(
ruid
,
ruid
,
euid
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to drop privilege by setting effective "
"user id and real user id to %d, and saved user "
"ID to %d
\n
"
,
ruid
,
euid
);
CMD_SYSERROR
(
"Failed to drop privilege by setting effective user id and real user id to %d, and saved user ID to %d
\n
"
,
ruid
,
euid
);
return
false
;
}
...
...
@@ -1000,8 +1000,8 @@ static bool may_access_netns(int pid)
ret
=
setresuid
(
ruid
,
euid
,
suid
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to restore user id to %d, real user id
"
"to %d, and saved user ID to %d
\n
"
,
ruid
,
euid
,
suid
);
CMD_SYSERROR
(
"Failed to restore user id to %d, real user id
to %d, and saved user ID to %d
\n
"
,
ruid
,
euid
,
suid
);
may_access
=
false
;
}
...
...
@@ -1018,8 +1018,10 @@ struct user_nic_args {
char
*
veth_name
;
};
#define LXC_USERNIC_CREATE 0
#define LXC_USERNIC_DELETE 1
enum
lxc_user_nic_command
{
LXC_USERNIC_CREATE
=
0
,
LXC_USERNIC_DELETE
=
1
,
};
static
bool
is_privileged_over_netns
(
int
netns_fd
)
{
...
...
@@ -1050,9 +1052,8 @@ static bool is_privileged_over_netns(int netns_fd)
ret
=
setresuid
(
ruid
,
ruid
,
0
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to drop privilege by setting effective "
"user id and real user id to %d, and saved user "
"ID to 0
\n
"
,
ruid
);
CMD_SYSERROR
(
"Failed to drop privilege by setting effective user id and real user id to %d, and saved user ID to 0
\n
"
,
ruid
);
/* It's ok to jump to do_full_cleanup here since setresuid()
* will succeed when trying to set real, effective, and saved to
* values they currently have.
...
...
@@ -1072,16 +1073,15 @@ static bool is_privileged_over_netns(int netns_fd)
do_full_cleanup:
ret
=
setresuid
(
ruid
,
euid
,
suid
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to restore privilege by setting "
"effective user id to %d, real user id to %d, "
"and saved user ID to %d
\n
"
,
ruid
,
euid
,
suid
);
CMD_SYSERROR
(
"Failed to restore privilege by setting effective user id to %d, real user id to %d, and saved user ID to %d
\n
"
,
ruid
,
euid
,
suid
);
bret
=
false
;
}
ret
=
setns
(
ofd
,
CLONE_NEWNET
);
if
(
ret
<
0
)
{
CMD_SYSERROR
(
"Failed to setns() to original network namespace
"
"of PID %d
\n
"
,
ofd
);
CMD_SYSERROR
(
"Failed to setns() to original network namespace
of PID %d
\n
"
,
ofd
);
bret
=
false
;
}
...
...
@@ -1090,6 +1090,18 @@ do_partial_cleanup:
return
bret
;
}
static
inline
int
validate_args
(
const
struct
user_nic_args
*
args
,
int
argc
)
{
int
request
=
-
EINVAL
;
if
(
!
strcmp
(
args
->
cmd
,
"create"
))
request
=
LXC_USERNIC_CREATE
;
else
if
(
!
strcmp
(
args
->
cmd
,
"delete"
))
request
=
LXC_USERNIC_DELETE
;
return
request
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
__do_free
char
*
me
=
NULL
,
*
newname
=
NULL
,
*
nicname
=
NULL
;
...
...
@@ -1099,10 +1111,8 @@ int main(int argc, char *argv[])
char
*
cnic
=
NULL
;
struct
alloted_s
*
alloted
=
NULL
;
if
(
argc
<
7
||
argc
>
8
)
{
usage
(
argv
[
0
],
true
);
_exit
(
EXIT_FAILURE
);
}
if
(
argc
<
7
||
argc
>
8
)
usage
(
true
);
memset
(
&
args
,
0
,
sizeof
(
struct
user_nic_args
));
...
...
@@ -1112,17 +1122,12 @@ int main(int argc, char *argv[])
args
.
pid
=
argv
[
4
];
args
.
type
=
argv
[
5
];
args
.
link
=
argv
[
6
];
if
(
argc
>
=
8
)
if
(
argc
=
=
8
)
args
.
veth_name
=
argv
[
7
];
if
(
!
strcmp
(
args
.
cmd
,
"create"
))
{
request
=
LXC_USERNIC_CREATE
;
}
else
if
(
!
strcmp
(
args
.
cmd
,
"delete"
))
{
request
=
LXC_USERNIC_DELETE
;
}
else
{
usage
(
argv
[
0
],
true
);
_exit
(
EXIT_FAILURE
);
}
request
=
validate_args
(
&
args
,
argc
);
if
(
request
<
0
)
usage
(
true
);
/* Set a sane env, because we are setuid-root. */
ret
=
clearenv
();
...
...
@@ -1218,8 +1223,7 @@ int main(int argc, char *argv[])
has_priv
=
is_privileged_over_netns
(
netns_fd
);
close
(
netns_fd
);
if
(
!
has_priv
)
{
usernic_error
(
"%s"
,
"Process is not privileged over "
"network namespace
\n
"
);
usernic_error
(
"%s"
,
"Process is not privileged over network namespace
\n
"
);
_exit
(
EXIT_FAILURE
);
}
}
...
...
@@ -1231,8 +1235,7 @@ int main(int argc, char *argv[])
bool
found_nicname
=
false
;
if
(
!
is_ovs_bridge
(
args
.
link
))
{
usernic_error
(
"%s"
,
"Deletion of non ovs type network "
"devices not implemented
\n
"
);
usernic_error
(
"%s"
,
"Deletion of non ovs type network devices not implemented
\n
"
);
close
(
fd
);
free_alloted
(
&
alloted
);
_exit
(
EXIT_FAILURE
);
...
...
@@ -1251,16 +1254,13 @@ int main(int argc, char *argv[])
free_alloted
(
&
alloted
);
if
(
!
found_nicname
)
{
usernic_error
(
"Caller is not allowed to delete network "
"device
\"
%s
\"\n
"
,
args
.
veth_name
);
usernic_error
(
"Caller is not allowed to delete network device
\"
%s
\"\n
"
,
args
.
veth_name
);
_exit
(
EXIT_FAILURE
);
}
ret
=
lxc_ovs_delete_port
(
args
.
link
,
args
.
veth_name
);
if
(
ret
<
0
)
{
usernic_error
(
"Failed to remove port
\"
%s
\"
from "
"openvswitch bridge
\"
%s
\"
"
,
args
.
veth_name
,
args
.
link
);
usernic_error
(
"Failed to remove port
\"
%s
\"
from openvswitch bridge
\"
%s
\"
"
,
args
.
veth_name
,
args
.
link
);
_exit
(
EXIT_FAILURE
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment