Update and document the privilege restriction.
This commit is contained in:
parent
1bc2695744
commit
e8b89a6104
3 changed files with 69 additions and 15 deletions
|
@ -145,10 +145,42 @@ options. The most important ones are:
|
||||||
|
|
||||||
<tag>-s <m/name of communication socket/</tag>
|
<tag>-s <m/name of communication socket/</tag>
|
||||||
use given filename for a socket for communications with the client, default is <it/prefix/<file>/var/run/bird.ctl</file>.
|
use given filename for a socket for communications with the client, default is <it/prefix/<file>/var/run/bird.ctl</file>.
|
||||||
|
|
||||||
|
<tag>-u <m/user/</tag>
|
||||||
|
drop privileges and use that user ID, see the next section for details.
|
||||||
|
|
||||||
|
<tag>-g <m/group/</tag>
|
||||||
|
use that group ID, see the next section for details.
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
<p>BIRD writes messages about its work to log files or syslog (according to config).
|
<p>BIRD writes messages about its work to log files or syslog (according to config).
|
||||||
|
|
||||||
|
<sect>Privileges
|
||||||
|
|
||||||
|
<p>BIRD, as a routing daemon, uses several privileged operations (like
|
||||||
|
setting routing table and using raw sockets). Traditionally, BIRD is
|
||||||
|
executed and runs with root privileges, which may be prone to security
|
||||||
|
problems. The recommended way is to use a privilege restriction
|
||||||
|
(options <cf/-u/, <cf/-g/). In that case BIRD is executed with root
|
||||||
|
privileges, but it changes its user and group ID to an unprivileged
|
||||||
|
ones, while using Linux capabilities to retain just required
|
||||||
|
privileges (capabilities CAP_NET_*). Note that the control socket is
|
||||||
|
created before the privileges are dropped, but the config file is read
|
||||||
|
after that. The privilege restriction is not implemented in BSD port
|
||||||
|
of BIRD.
|
||||||
|
|
||||||
|
<p>A nonprivileged user (as an argument to <cf/-u/ options) may be the
|
||||||
|
user <cf/nobody/, but it is suggested to use a new dedicated user
|
||||||
|
account (like <cf/bird/). The similar considerations apply for
|
||||||
|
the group option, but there is one more condition -- the users
|
||||||
|
in the same group can use <file/birdc/ to control BIRD.
|
||||||
|
|
||||||
|
<p>Finally, there is a possibility to use external tools to run BIRD in
|
||||||
|
an environment with restricted privileges. This may need some
|
||||||
|
configuration, but it is generally easy -- BIRD needs just the
|
||||||
|
standard library, privileges to read the config file and create the
|
||||||
|
control socket and the CAP_NET_* capabilities.
|
||||||
|
|
||||||
<chapt>About routing tables
|
<chapt>About routing tables
|
||||||
|
|
||||||
<p>BIRD has one or more routing tables which may or may not be
|
<p>BIRD has one or more routing tables which may or may not be
|
||||||
|
|
|
@ -48,15 +48,20 @@ drop_uid(uid_t uid)
|
||||||
CAP_TO_MASK(CAP_NET_ADMIN) |
|
CAP_TO_MASK(CAP_NET_ADMIN) |
|
||||||
CAP_TO_MASK(CAP_NET_RAW);
|
CAP_TO_MASK(CAP_NET_RAW);
|
||||||
|
|
||||||
|
/* change effective user ID to be able to switch to that
|
||||||
|
user ID completely after dropping CAP_SETUID */
|
||||||
if (seteuid(uid) < 0)
|
if (seteuid(uid) < 0)
|
||||||
die("seteuid: %m");
|
die("seteuid: %m");
|
||||||
|
|
||||||
|
/* restrict the capabilities */
|
||||||
if (set_capabilities(caps) < 0)
|
if (set_capabilities(caps) < 0)
|
||||||
die("capset: %m");
|
die("capset: %m");
|
||||||
|
|
||||||
|
/* keep the capabilities after dropping root ID */
|
||||||
if (prctl(PR_SET_KEEPCAPS, 1) < 0)
|
if (prctl(PR_SET_KEEPCAPS, 1) < 0)
|
||||||
die("prctl: %m");
|
die("prctl: %m");
|
||||||
|
|
||||||
|
/* completely switch to the unprivileged user ID */
|
||||||
if (setresuid(uid, uid, uid) < 0)
|
if (setresuid(uid, uid, uid) < 0)
|
||||||
die("setresuid: %m");
|
die("setresuid: %m");
|
||||||
}
|
}
|
||||||
|
|
|
@ -383,7 +383,7 @@ cli_connect(sock *s, int size UNUSED)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cli_init_unix(void)
|
cli_init_unix(uid_t use_uid, gid_t use_gid)
|
||||||
{
|
{
|
||||||
sock *s;
|
sock *s;
|
||||||
|
|
||||||
|
@ -393,6 +393,13 @@ cli_init_unix(void)
|
||||||
s->rx_hook = cli_connect;
|
s->rx_hook = cli_connect;
|
||||||
s->rbsize = 1024;
|
s->rbsize = 1024;
|
||||||
sk_open_unix(s, path_control_socket);
|
sk_open_unix(s, path_control_socket);
|
||||||
|
|
||||||
|
if (use_uid || use_gid)
|
||||||
|
if (chown(path_control_socket, use_uid, use_gid) < 0)
|
||||||
|
die("chown: %m");
|
||||||
|
|
||||||
|
if (chmod(path_control_socket, 0660) < 0)
|
||||||
|
die("chmod: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -503,9 +510,13 @@ get_uid(const char *s)
|
||||||
{
|
{
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
long int rv;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return 0;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
long int rv = strtol(s, &endptr, 10);
|
rv = strtol(s, &endptr, 10);
|
||||||
|
|
||||||
if (!errno && !*endptr)
|
if (!errno && !*endptr)
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -522,9 +533,13 @@ get_gid(const char *s)
|
||||||
{
|
{
|
||||||
struct group *gr;
|
struct group *gr;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
long int rv;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return 0;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
long int rv = strtol(s, &endptr, 10);
|
rv = strtol(s, &endptr, 10);
|
||||||
|
|
||||||
if (!errno && !*endptr)
|
if (!errno && !*endptr)
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -601,24 +616,26 @@ main(int argc, char **argv)
|
||||||
log_init_debug("");
|
log_init_debug("");
|
||||||
log_switch(debug_flag, NULL, NULL);
|
log_switch(debug_flag, NULL, NULL);
|
||||||
|
|
||||||
if (use_group)
|
|
||||||
drop_gid(get_gid(use_group));
|
|
||||||
|
|
||||||
if (use_user)
|
|
||||||
drop_uid(get_uid(use_user));
|
|
||||||
|
|
||||||
if (!parse_and_exit)
|
|
||||||
test_old_bird(path_control_socket);
|
|
||||||
|
|
||||||
DBG("Initializing.\n");
|
|
||||||
resource_init();
|
resource_init();
|
||||||
olock_init();
|
olock_init();
|
||||||
io_init();
|
io_init();
|
||||||
rt_init();
|
rt_init();
|
||||||
if_init();
|
if_init();
|
||||||
|
|
||||||
|
uid_t use_uid = get_uid(use_user);
|
||||||
|
gid_t use_gid = get_gid(use_group);
|
||||||
|
|
||||||
if (!parse_and_exit)
|
if (!parse_and_exit)
|
||||||
cli_init_unix();
|
{
|
||||||
|
test_old_bird(path_control_socket);
|
||||||
|
cli_init_unix(use_uid, use_gid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_gid)
|
||||||
|
drop_gid(use_gid);
|
||||||
|
|
||||||
|
if (use_uid)
|
||||||
|
drop_uid(use_uid);
|
||||||
|
|
||||||
protos_build();
|
protos_build();
|
||||||
proto_build(&proto_unix_kernel);
|
proto_build(&proto_unix_kernel);
|
||||||
|
|
Loading…
Reference in a new issue