chroot more tests and more documentation.

git-svn-id: file:///svn/unbound/trunk@1067 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-04-24 12:37:01 +00:00
parent 8ef2cb4705
commit 9dd64e357f
6 changed files with 76 additions and 24 deletions

View File

@ -295,13 +295,6 @@ 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));
}
verbose(VERB_QUERY, "chdir to %s", cfg->directory);
}
if(cfg->username && cfg->username[0]) {
struct passwd *pwd;
if((pwd = getpwnam(cfg->username)) == NULL)
@ -311,6 +304,11 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode,
endpwent();
}
if(cfg->chrootdir && cfg->chrootdir[0]) {
if(chdir(cfg->chrootdir)) {
fatal_exit("unable to chdir to chroot %s: %s",
cfg->chrootdir, strerror(errno));
}
verbose(VERB_QUERY, "chdir to %s", cfg->chrootdir);
if(chroot(cfg->chrootdir))
fatal_exit("unable to chroot to %s: %s",
cfg->chrootdir, strerror(errno));
@ -319,6 +317,18 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode,
strlen(cfg->chrootdir)) == 0)
(*cfgfile) += strlen(cfg->chrootdir);
}
if(cfg->directory && cfg->directory[0]) {
char* dir = cfg->directory;
if(cfg->chrootdir && cfg->chrootdir[0] &&
strncmp(dir, cfg->chrootdir,
strlen(cfg->chrootdir)) == 0)
dir += strlen(cfg->chrootdir);
if(chdir(dir)) {
fatal_exit("Could not chdir to %s: %s",
dir, strerror(errno));
}
verbose(VERB_QUERY, "chdir to %s", dir);
}
if(cfg->username && cfg->username[0]) {
if(setgid(gid) != 0)
fatal_exit("unable to set group id of %s: %s",

View File

@ -1,3 +1,7 @@
24 April 2008: Wouter
- chroot checks improved. working directory relative to chroot.
checks if config file path is inside chroot. Documentation on it.
23 April 2008: Wouter
- parseunbound.pl contrib update from Kai Storbeck for threads.
- iana ports update

View File

@ -144,7 +144,23 @@ 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.
# If you give "" no chroot is performed.
#
# If chroot is enabled, you should pass the configfile (from the
# commandline) as a full path from the original root. After the
# chroot has been performed the now defunct portion of the config
# file path is removed to be able to reread the config after a reload.
#
# All other file paths (working dir, pidfile, logfile, roothints,
# key files) can be specified in several ways:
# o as an absolute path relative to the new root.
# o as a relative path to the working directory.
# o as an absolute path relative to the original root.
# In the last case the path is adjusted to remove the unused portion.
#
# Additionally, unbound may need to access /dev/random (for entropy)
# and to /dev/log (if you use syslog) from inside the chroot.
#
# If you give "" no chroot is performed. The path must not end in a /.
# chroot: "/usr/local/etc/unbound"
# if given, user privileges are dropped (after binding port),
@ -152,7 +168,7 @@ server:
# If you give "" no privileges are dropped.
# username: "unbound"
# the working directory.
# the working directory. "" disables.
# directory: "/usr/local/etc/unbound"
# the log file, "" means log to stderr.

View File

@ -238,8 +238,23 @@ is not designed to handle dropped packets due to policy, and dropping may
result in (possibly excessive) retried queries.
.TP
.B chroot: \fI<directory>
If chroot is enabled, you should pass the configfile (from the
commandline) as a full path from the original root. After the
chroot has been performed the now defunct portion of the config
file path is removed to be able to reread the config after a reload.
.IP
All other file paths (working dir, pidfile, logfile, roothints,
key files) can be specified in several ways:
as an absolute path relative to the new root,
as a relative path to the working directory, or
as an absolute path relative to the original root.
In the last case the path is adjusted to remove the unused portion.
.IP
Additionally, unbound may need to access /dev/random (for entropy)
and to /dev/log (if you use syslog) from inside the chroot.
.IP
If given a chroot is done to the given directory. The default is
"/etc/unbound". If you give "" no chroot is performed.
"/usr/local/etc/unbound". If you give "" no chroot is performed.
.TP
.B username: \fI<name>
If given, after binding the port the user privileges are dropped. Default is
@ -271,14 +286,14 @@ The logfile setting is overridden when use\-syslog is turned on.
The default is to log to syslog.
.TP
.B pidfile: \fI<filename>
The process id is written to the file. Default is "/etc/unbound/unbound.pid".
The process id is written to the file. Default is "/usr/local/etc/unbound/unbound.pid".
So,
.nf
kill \-HUP `cat /etc/unbound/unbound.pid`
kill \-HUP `cat /usr/local/etc/unbound/unbound.pid`
.fi
triggers a reload,
.nf
kill \-QUIT `cat /etc/unbound/unbound.pid`
kill \-QUIT `cat /usr/local/etc/unbound/unbound.pid`
.fi
gracefully terminates.
.TP
@ -648,7 +663,7 @@ server:
.fi
.SH "FILES"
.TP
.I /etc/unbound
.I /usr/local/etc/unbound
default unbound working directory and default
\fIchroot\fR(2)
location.

View File

@ -297,7 +297,7 @@ check_chroot_filelist(const char* desc, struct config_strlist* list,
/** check configuration for errors */
static void
morechecks(struct config_file* cfg)
morechecks(struct config_file* cfg, char* fname)
{
warn_hosts("stub-host", cfg->stubs);
warn_hosts("forward-host", cfg->forwards);
@ -321,14 +321,21 @@ morechecks(struct config_file* cfg)
!is_dir(cfg->chrootdir)) {
fatal_exit("bad chroot directory");
}
if((cfg->chrootdir && cfg->chrootdir[0])
&& (cfg->directory && cfg->directory[0])
&& strncmp(cfg->chrootdir, cfg->directory,
strlen(cfg->chrootdir)) != 0) {
fatal_exit("chdir directory '%s' not inside the chroot "
"directory '%s'", cfg->directory, cfg->chrootdir);
if(cfg->chrootdir && cfg->chrootdir[0]) {
char buf[10240];
buf[0] = 0;
if(fname[0] != '/') {
if(getcwd(buf, sizeof(buf)) == NULL)
fatal_exit("getcwd: %s", strerror(errno));
strncat(buf, "/", sizeof(buf));
}
strncat(buf, fname, sizeof(buf));
if(strncmp(buf, cfg->chrootdir, strlen(cfg->chrootdir)) != 0)
fatal_exit("config file %s is not inside chroot %s",
buf, cfg->chrootdir);
}
if(cfg->directory && cfg->directory[0] && !is_dir(cfg->directory)) {
if(cfg->directory && cfg->directory[0] && !is_dir(
fname_after_chroot(cfg->directory, cfg, 0))) {
fatal_exit("bad chdir directory");
}
if( (cfg->chrootdir && cfg->chrootdir[0]) ||
@ -341,7 +348,7 @@ morechecks(struct config_file* cfg)
if(cfg->logfile && cfg->logfile[0] &&
basedir(cfg->logfile, cfg) &&
!is_dir(basedir(cfg->logfile, cfg))) {
fatal_exit("pidfile directory does not exist");
fatal_exit("logfile directory does not exist");
}
}
@ -382,7 +389,7 @@ checkconf(char* cfgfile)
config_delete(cfg);
exit(1);
}
morechecks(cfg);
morechecks(cfg, cfgfile);
check_mod(cfg, iter_get_funcblock());
check_mod(cfg, val_get_funcblock());
config_delete(cfg);

Binary file not shown.