small feature
David CARLIER
devnexen at gmail.com
Wed Oct 7 04:53:45 UTC 2015
Hi all,
I developed a small feature which puts nginx in chroot mode, off by default
and when you set a prefix path via -p, although OpenBSD team did already a
version far before me.
Hope it is useful.
Kind regards.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20151007/96515d1e/attachment.html>
-------------- next part --------------
diff -r 4b4aee40c508 src/core/nginx.c
--- a/src/core/nginx.c Tue Oct 06 08:57:09 2015 +0300
+++ b/src/core/nginx.c Wed Oct 07 05:49:50 2015 +0100
@@ -49,6 +49,13 @@
offsetof(ngx_core_conf_t, master),
NULL },
+ { ngx_string("chroot"),
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ 0,
+ offsetof(ngx_core_conf_t, chroot),
+ NULL },
+
{ ngx_string("timer_resolution"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
@@ -967,6 +974,7 @@
ccf->daemon = NGX_CONF_UNSET;
ccf->master = NGX_CONF_UNSET;
+ ccf->chroot = NGX_CONF_UNSET;
ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
ccf->worker_processes = NGX_CONF_UNSET;
@@ -984,6 +992,9 @@
return NULL;
}
+ ccf->chroot_directory.len = NGX_CONF_UNSET_UINT;
+ ccf->chroot_directory.data = NULL;
+
return ccf;
}
@@ -995,6 +1006,7 @@
ngx_conf_init_value(ccf->daemon, 1);
ngx_conf_init_value(ccf->master, 1);
+ ngx_conf_init_value(ccf->chroot, 0);
ngx_conf_init_msec_value(ccf->timer_resolution, 0);
ngx_conf_init_value(ccf->worker_processes, 1);
@@ -1014,7 +1026,6 @@
#endif
-
if (ccf->pid.len == 0) {
ngx_str_set(&ccf->pid, NGX_PID_PATH);
}
@@ -1063,6 +1074,19 @@
}
+ if (ccf->chroot) {
+ if (ngx_prefix) {
+ ngx_uint_t ngx_prefixlen = ngx_strlen(ngx_prefix);
+ ccf->chroot_directory.len = ngx_prefixlen;
+ ccf->chroot_directory.data = ngx_palloc(cycle->pool, ngx_prefixlen + 1);
+ ngx_memcpy(ccf->chroot_directory.data, ngx_prefix, ngx_prefixlen);
+ } else if(ccf->chroot_directory.len == NGX_CONF_UNSET_UINT) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "in chroot mode the prefix path must be set ");
+ return NGX_CONF_ERROR;
+ }
+ }
+
if (ccf->lock_file.len == 0) {
ngx_str_set(&ccf->lock_file, NGX_LOCK_PATH);
}
diff -r 4b4aee40c508 src/core/ngx_cycle.c
--- a/src/core/ngx_cycle.c Tue Oct 06 08:57:09 2015 +0300
+++ b/src/core/ngx_cycle.c Wed Oct 07 05:49:50 2015 +0100
@@ -1087,6 +1087,8 @@
ngx_uint_t i;
ngx_list_part_t *part;
ngx_open_file_t *file;
+ ngx_core_conf_t *ccf = (ngx_core_conf_t *)ngx_get_conf(cycle->conf_ctx,
+ ngx_core_module);
part = &cycle->open_files.part;
file = part->elts;
@@ -1106,6 +1108,8 @@
continue;
}
+ ngx_adjust_path(ccf, cycle, &file[i].name);
+
if (file[i].flush) {
file[i].flush(&file[i], cycle->log);
}
@@ -1278,6 +1282,34 @@
return shm_zone;
}
+void
+ngx_adjust_path(ngx_core_conf_t *ccf, ngx_cycle_t *cycle, ngx_str_t *path)
+{
+ if (!ccf->chroot)
+ return;
+
+ ngx_uint_t cpathlen = path->len;
+ u_char *cpath = path->data;
+ cpath[cpathlen] = '\0';
+
+ if (cycle->prefix.data != NULL) {
+ u_char *prefix = cycle->prefix.data;
+ prefix[cycle->prefix.len] = '\0';
+
+ if (ngx_strnstr(cpath, prefix, cycle->prefix.len)) {
+ cpath += cycle->prefix.len;
+ cpathlen -= cycle->prefix.len;
+ }
+ }
+
+ if (cpath[0] != '/') {
+ u_char *newpath = ngx_palloc(cycle->pool, cpathlen + 2);
+ newpath[0] = '/';
+ ngx_memcpy(newpath + 1, cpath, cpathlen);
+ path->data = newpath;
+ path->len = cpathlen + 1;
+ }
+}
static void
ngx_clean_old_cycles(ngx_event_t *ev)
diff -r 4b4aee40c508 src/core/ngx_cycle.h
--- a/src/core/ngx_cycle.h Tue Oct 06 08:57:09 2015 +0300
+++ b/src/core/ngx_cycle.h Wed Oct 07 05:49:50 2015 +0100
@@ -77,6 +77,7 @@
typedef struct {
ngx_flag_t daemon;
ngx_flag_t master;
+ ngx_flag_t chroot;
ngx_msec_t timer_resolution;
@@ -97,6 +98,7 @@
ngx_str_t working_directory;
ngx_str_t lock_file;
+ ngx_str_t chroot_directory;
ngx_str_t pid;
ngx_str_t oldpid;
@@ -119,6 +121,7 @@
uint64_t ngx_get_cpu_affinity(ngx_uint_t n);
ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
size_t size, void *tag);
+void ngx_adjust_path(ngx_core_conf_t *, ngx_cycle_t *, ngx_str_t *);
extern volatile ngx_cycle_t *ngx_cycle;
diff -r 4b4aee40c508 src/core/ngx_file.c
--- a/src/core/ngx_file.c Tue Oct 06 08:57:09 2015 +0300
+++ b/src/core/ngx_file.c Wed Oct 07 05:49:50 2015 +0100
@@ -566,9 +566,12 @@
ngx_err_t err;
ngx_uint_t i;
ngx_path_t **path;
+ ngx_core_conf_t *ccf = (ngx_core_conf_t *)ngx_get_conf(cycle->conf_ctx,
+ ngx_core_module);
path = cycle->paths.elts;
for (i = 0; i < cycle->paths.nelts; i++) {
+ ngx_adjust_path(ccf, cycle, &path[i]->name);
if (ngx_create_dir(path[i]->name.data, 0700) == NGX_FILE_ERROR) {
err = ngx_errno;
diff -r 4b4aee40c508 src/http/modules/ngx_http_auth_basic_module.c
--- a/src/http/modules/ngx_http_auth_basic_module.c Tue Oct 06 08:57:09 2015 +0300
+++ b/src/http/modules/ngx_http_auth_basic_module.c Wed Oct 07 05:49:50 2015 +0100
@@ -441,6 +441,8 @@
ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_auth_basic_loc_conf_t *alcf = conf;
+ ngx_core_conf_t *ccf =
+ (ngx_core_conf_t *)ngx_get_conf(cf->cycle->conf_ctx, ngx_core_module);
ngx_str_t *value;
ngx_http_compile_complex_value_t ccv;
@@ -453,6 +455,8 @@
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+ ngx_adjust_path(ccf, cf->cycle, &value[1]);
+
ccv.cf = cf;
ccv.value = &value[1];
ccv.complex_value = &alcf->user_file;
diff -r 4b4aee40c508 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Tue Oct 06 08:57:09 2015 +0300
+++ b/src/http/ngx_http_core_module.c Wed Oct 07 05:49:50 2015 +0100
@@ -4430,6 +4430,8 @@
ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_core_loc_conf_t *clcf = conf;
+ ngx_core_conf_t *ccf =
+ (ngx_core_conf_t *)ngx_get_conf(cf->cycle->conf_ctx, ngx_core_module);
ngx_str_t *value;
ngx_int_t alias;
@@ -4486,9 +4488,12 @@
return NGX_CONF_ERROR;
}
+ ngx_adjust_path(ccf, cf->cycle, &value[1]);
+
clcf->alias = alias ? clcf->name.len : 0;
clcf->root = value[1];
+
if (!alias && clcf->root.data[clcf->root.len - 1] == '/') {
clcf->root.len--;
}
diff -r 4b4aee40c508 src/os/unix/ngx_process_cycle.c
--- a/src/os/unix/ngx_process_cycle.c Tue Oct 06 08:57:09 2015 +0300
+++ b/src/os/unix/ngx_process_cycle.c Wed Oct 07 05:49:50 2015 +0100
@@ -828,6 +828,28 @@
}
if (geteuid() == 0) {
+ if (ccf->chroot) {
+ u_char *chroot_directory = ccf->chroot_directory.data;
+ chroot_directory[ccf->chroot_directory.len] = '\0';
+
+ if (chroot((const char *)chroot_directory) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "chroot(%s) failed", chroot_directory);
+ /* fatal */
+ exit(2);
+ }
+
+ if (chdir("/") == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "chdir failed");
+ /* fatal */
+ exit(2);
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "chrooted into %s", chroot_directory);
+
+ }
+
if (setgid(ccf->group) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
"setgid(%d) failed", ccf->group);
More information about the nginx-devel
mailing list