mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-09-06 18:07:41 +02:00
better chroot support, and also default chroot and userchange.
git-svn-id: file:///svn/unbound/trunk@723 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
+4
-3
@@ -32,8 +32,8 @@ staticexe=@staticexe@
|
||||
YACC=@YACC@
|
||||
LEX=@LEX@
|
||||
CC=@CC@
|
||||
CPPFLAGS=-I. @CPPFLAGS@ @DEFS@
|
||||
CFLAGS=-I. @CFLAGS@
|
||||
CPPFLAGS=-I$(srcdir) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS=@CFLAGS@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
LIBS=@LIBS@
|
||||
LIBOBJS=@LIBOBJS@
|
||||
@@ -59,7 +59,8 @@ COMMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/services/*.c \
|
||||
util/configparser.c util/configlexer.c testcode/checklocks.c
|
||||
COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.o))
|
||||
COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS))
|
||||
UNITTEST_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/testcode/unit*.c)) \
|
||||
UNITTEST_SRC=$(patsubst $(srcdir)/%,%, \
|
||||
$(wildcard $(srcdir)/testcode/unit*.c)) \
|
||||
testcode/readhex.c testcode/ldns-testpkts.c checkconf/worker_cb.c \
|
||||
$(COMMON_SRC)
|
||||
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
|
||||
@@ -172,7 +172,7 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
log_ident_set("unbound-checkconf");
|
||||
log_init(NULL, 0);
|
||||
log_init(NULL, 0, NULL);
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "h")) != -1) {
|
||||
switch(c) {
|
||||
|
||||
@@ -460,7 +460,6 @@ daemon_delete(struct daemon* daemon)
|
||||
infra_delete(daemon->env->infra_cache);
|
||||
}
|
||||
alloc_clear(&daemon->superalloc);
|
||||
free(daemon->cwd);
|
||||
free(daemon->pidfile);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
|
||||
@@ -58,8 +58,6 @@ struct rrset_cache;
|
||||
struct daemon {
|
||||
/** The config settings */
|
||||
struct config_file* cfg;
|
||||
/** current working directory */
|
||||
char* cwd;
|
||||
/** pidfile that is used */
|
||||
char* pidfile;
|
||||
/** port number that has ports opened. */
|
||||
|
||||
+27
-22
@@ -110,25 +110,15 @@ checkrlimits(struct config_file* cfg)
|
||||
}
|
||||
}
|
||||
|
||||
/** to changedir, logfile */
|
||||
/** set verbosity, check rlimits, cache settings */
|
||||
static void
|
||||
apply_dir(struct daemon* daemon, struct config_file* cfg, int cmdline_verbose)
|
||||
apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
int cmdline_verbose)
|
||||
{
|
||||
/* apply if they have changed */
|
||||
daemon->cfg = cfg;
|
||||
verbosity = cmdline_verbose + cfg->verbosity;
|
||||
config_apply(cfg);
|
||||
if(cfg->directory && cfg->directory[0]) {
|
||||
if(!daemon->cwd || strcmp(daemon->cwd, cfg->directory) != 0) {
|
||||
if(chdir(cfg->directory)) {
|
||||
log_err("Could not chdir to %s: %s",
|
||||
cfg->directory, strerror(errno));
|
||||
}
|
||||
free(daemon->cwd);
|
||||
if(!(daemon->cwd = strdup(cfg->directory)))
|
||||
log_err("cwd: malloc failed");
|
||||
}
|
||||
}
|
||||
if(!daemon->env->msg_cache ||
|
||||
cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) ||
|
||||
cfg->msg_cache_slabs != daemon->env->msg_cache->size) {
|
||||
@@ -223,7 +213,12 @@ static void
|
||||
checkoldpid(struct config_file* cfg)
|
||||
{
|
||||
pid_t old;
|
||||
if((old = readpid(cfg->pidfile)) != -1) {
|
||||
char* file = cfg->pidfile;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(file, cfg->chrootdir, strlen(cfg->chrootdir))==0) {
|
||||
file += strlen(cfg->chrootdir);
|
||||
}
|
||||
if((old = readpid(file)) != -1) {
|
||||
/* see if it is still alive */
|
||||
if(kill(old, 0) == 0 || errno == EPERM)
|
||||
log_warn("unbound is already running as pid %u.",
|
||||
@@ -268,9 +263,15 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
|
||||
log_assert(cfg);
|
||||
|
||||
/* daemonize last to be able to print error to user */
|
||||
if(cfg->directory && cfg->directory[0])
|
||||
if(chdir(cfg->directory)) {
|
||||
fatal_exit("Could not chdir to %s: %s",
|
||||
cfg->directory, strerror(errno));
|
||||
}
|
||||
if(cfg->chrootdir && cfg->chrootdir[0])
|
||||
if(chroot(cfg->chrootdir))
|
||||
fatal_exit("unable to chroot: %s", strerror(errno));
|
||||
fatal_exit("unable to chroot to %s: %s",
|
||||
cfg->chrootdir, strerror(errno));
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
struct passwd *pwd;
|
||||
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||
@@ -287,13 +288,17 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
|
||||
}
|
||||
|
||||
/* init logfile just before fork */
|
||||
log_init(cfg->logfile, cfg->use_syslog);
|
||||
log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
|
||||
if(!debug_mode && cfg->do_daemonize) {
|
||||
detach(cfg);
|
||||
}
|
||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||
writepid(cfg->pidfile, getpid());
|
||||
if(!(daemon->pidfile = strdup(cfg->pidfile)))
|
||||
char* pf = cfg->pidfile;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(pf, cfg->chrootdir, strlen(cfg->chrootdir))==0)
|
||||
pf += strlen(cfg->chrootdir);
|
||||
writepid(pf, getpid());
|
||||
if(!(daemon->pidfile = strdup(pf)))
|
||||
log_err("pidf: malloc failed");
|
||||
}
|
||||
}
|
||||
@@ -324,7 +329,7 @@ run_daemon(char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
fatal_exit("Could not alloc config defaults");
|
||||
if(!config_read(cfg, cfgfile))
|
||||
fatal_exit("Could not read config file: %s", cfgfile);
|
||||
apply_dir(daemon, cfg, cmdline_verbose);
|
||||
apply_settings(daemon, cfg, cmdline_verbose);
|
||||
|
||||
/* prepare */
|
||||
if(!daemon_open_shared_ports(daemon))
|
||||
@@ -332,7 +337,7 @@ run_daemon(char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
if(!done_chroot) {
|
||||
do_chroot(daemon, cfg, debug_mode);
|
||||
done_chroot = 1;
|
||||
} else log_init(cfg->logfile, cfg->use_syslog);
|
||||
} else log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
|
||||
/* work */
|
||||
daemon_fork(daemon);
|
||||
|
||||
@@ -369,7 +374,7 @@ main(int argc, char* argv[])
|
||||
/* take debug snapshot of heap */
|
||||
unbound_start_brk = sbrk(0);
|
||||
|
||||
log_init(NULL, 0);
|
||||
log_init(NULL, 0, NULL);
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "c:dhv")) != -1) {
|
||||
switch(c) {
|
||||
@@ -399,6 +404,6 @@ main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode);
|
||||
log_init(NULL, 0); /* close logfile */
|
||||
log_init(NULL, 0, NULL); /* close logfile */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
31 October 2007: Wouter
|
||||
- cache-max-ttl config option.
|
||||
- building outside sourcedir works again.
|
||||
- defaults more secure:
|
||||
username: "unbound"
|
||||
chroot: "/etc/unbound"
|
||||
The operator can override them to be less secure ("") if necessary.
|
||||
|
||||
30 October 2007: Wouter
|
||||
- fixup assertion failure that relied on compressed names to be
|
||||
|
||||
@@ -52,3 +52,4 @@ o make timeout backoffs randomized (a couple percent random) to spread traffic.
|
||||
o inspect date on executable, then warn user in log if its more than 1 year.
|
||||
o proactively prime root, stubs and trust anchors, feature.
|
||||
early failure, faster on first query, but more traffic.
|
||||
o use privilege separation, to change privilege options during reload securely
|
||||
|
||||
+4
-2
@@ -114,10 +114,12 @@ server:
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
# chroot: "/some/directory"
|
||||
# If you give "" no chroot is performed.
|
||||
# chroot: "/etc/unbound"
|
||||
|
||||
# if given, user privileges are dropped (after binding port),
|
||||
# and the given username is assumed. Default is nothing "".
|
||||
# and the given username is assumed. Default is user "unbound".
|
||||
# If you give "" no priviliges are dropped.
|
||||
# username: "unbound"
|
||||
|
||||
# the working directory.
|
||||
|
||||
+8
-4
@@ -155,10 +155,11 @@ Enable or disable whether UDP queries are answered. Default is yes.
|
||||
.It \fBdo-tcp:\fR <yes or no>
|
||||
Enable or disable whether TCP queries are answered. Default is yes.
|
||||
.It \fBchroot:\fR <directory>
|
||||
If given a chroot is done to the given directory. The default is none ("").
|
||||
If given a chroot is done to the given directory. The default is
|
||||
"/etc/unbound". If you give "" no chroot is performed.
|
||||
.It \fBusername:\fR <name>
|
||||
If given, after binding the port the user privileges are dropped. Default is
|
||||
not to change user, username: "".
|
||||
"unbound". If you give username: "" no user change is performed.
|
||||
.Pp
|
||||
If this user is not capable of binding the
|
||||
port, reloads (by signal HUP) will still retain the opened ports.
|
||||
@@ -355,13 +356,16 @@ server:
|
||||
.Sh FILES
|
||||
.Bl -tag -width indent
|
||||
.It Pa /etc/unbound
|
||||
default unbound working directory
|
||||
default unbound working directory and default
|
||||
.Xr chroot 2
|
||||
location.
|
||||
.It Pa unbound.conf
|
||||
unbound configuration file.
|
||||
.It Pa unbound.pid
|
||||
default unbound pidfile with process ID of the running daemon.
|
||||
.It Pa unbound.log
|
||||
unbound log file.
|
||||
unbound log file. default is to log to
|
||||
.Xr syslog 3 .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr unbound 8 ,
|
||||
|
||||
@@ -385,7 +385,7 @@ main(int argc, char* argv[])
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
log_init(NULL, 0);
|
||||
log_init(NULL, 0, NULL);
|
||||
log_ident_set("lock-verify");
|
||||
/* init */
|
||||
all_locks = rbtree_create(order_lock_cmp);
|
||||
|
||||
+1
-1
@@ -236,7 +236,7 @@ process_nsec3(int argc, char* argv[])
|
||||
/** main program */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
log_init(NULL, 0);
|
||||
log_init(NULL, 0, NULL);
|
||||
if(argc != 6) {
|
||||
usage();
|
||||
}
|
||||
|
||||
@@ -138,6 +138,8 @@ setup_config(FILE* in, char* configfile, int* lineno,
|
||||
/* some basic settings to not pollute the host system */
|
||||
fprintf(cfg, "server: use-syslog: no\n");
|
||||
fprintf(cfg, " directory: \"\"\n");
|
||||
fprintf(cfg, " chroot: \"\"\n");
|
||||
fprintf(cfg, " username: \"\"\n");
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
parse = line;
|
||||
(*lineno)++;
|
||||
@@ -207,7 +209,7 @@ main(int argc, char* argv[])
|
||||
char* init_optarg = optarg;
|
||||
struct replay_scenario* scen = NULL;
|
||||
|
||||
log_init(NULL, 0);
|
||||
log_init(NULL, 0, NULL);
|
||||
log_info("Start of %s testbound program.", PACKAGE_STRING);
|
||||
/* determine commandline options for the daemon */
|
||||
cfgfile[0] = 0;
|
||||
|
||||
+1
-1
@@ -228,7 +228,7 @@ rnd_test()
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
log_init(NULL, 0);
|
||||
log_init(NULL, 0, NULL);
|
||||
if(argc != 1) {
|
||||
printf("usage: %s\n", argv[0]);
|
||||
printf("\tperforms unit tests.\n");
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
+2
-2
@@ -93,8 +93,8 @@ config_create()
|
||||
cfg->infra_cache_slabs = 4;
|
||||
cfg->infra_cache_numhosts = 10000;
|
||||
cfg->infra_cache_lame_size = 10240; /* easily 40 or more entries */
|
||||
if(!(cfg->username = strdup(""))) goto error_exit;
|
||||
if(!(cfg->chrootdir = strdup(""))) goto error_exit;
|
||||
if(!(cfg->username = strdup("unbound"))) goto error_exit;
|
||||
if(!(cfg->chrootdir = strdup("/etc/unbound"))) goto error_exit;
|
||||
if(!(cfg->directory = strdup("/etc/unbound"))) goto error_exit;
|
||||
if(!(cfg->logfile = strdup(""))) goto error_exit;
|
||||
if(!(cfg->pidfile = strdup("unbound.pid"))) goto error_exit;
|
||||
|
||||
+4
-1
@@ -71,7 +71,7 @@ static int log_to_syslog = 0;
|
||||
#endif /* HAVE_SYSLOG_H */
|
||||
|
||||
void
|
||||
log_init(const char* filename, int use_syslog)
|
||||
log_init(const char* filename, int use_syslog, const char* chrootdir)
|
||||
{
|
||||
FILE *f;
|
||||
if(!key_created) {
|
||||
@@ -103,6 +103,9 @@ log_init(const char* filename, int use_syslog)
|
||||
return;
|
||||
}
|
||||
/* open the file for logging */
|
||||
if(chrootdir && chrootdir[0] && strncmp(filename, chrootdir,
|
||||
strlen(chrootdir)) == 0)
|
||||
filename += strlen(chrootdir);
|
||||
f = fopen(filename, "a");
|
||||
if(!f) {
|
||||
log_err("Could not open logfile %s: %s", filename,
|
||||
|
||||
+2
-1
@@ -78,8 +78,9 @@ void verbose(enum verbosity_value level,
|
||||
* call this to initialize logging services.
|
||||
* @param filename: if NULL stderr is used.
|
||||
* @param use_syslog: set to true to ignore filename and use syslog(3).
|
||||
* @param chrootdir: to which directory we have been chrooted, if any.
|
||||
*/
|
||||
void log_init(const char* filename, int use_syslog);
|
||||
void log_init(const char* filename, int use_syslog, const char* chrootdir);
|
||||
|
||||
/**
|
||||
* Init a thread (will print this number for the thread log entries).
|
||||
|
||||
Reference in New Issue
Block a user