Hello, I'm new here but I work with nginx on daily basis at my company Adpilot.pl and I would like to suggest a patch to nginx.
Recently we had a need to provide a full security to our servers by securing our encryption keys and preventing them to be written on to the hard disk. But there still was an issue with swapping out nginx - there still was (a small) possibility that in extreme situations some portion of nginx memory where keys are stored (or information which could be used to recreate keys) will be swapped out and will be written on hard drive. Also keeping nginx out of swap has few performance benefits on heavy loaded systems ;) In earlier Linux systems process could be kept out of swap by setting a sticky bit (chmod +S) but on all modern linux distributions - this flag doesn't work anymore. Now it must be done manually in code, so I'm sending a patch which is adding a configuration parameter that can enable marking all nginx memory (also workers) as nonswappable. Feedback welcome! Thanks Marcin Strągowski
diff -r c86dd32573c0 src/core/nginx.c --- a/src/core/nginx.c Tue Jan 28 00:31:31 2014 +0400 +++ b/src/core/nginx.c Wed May 21 12:02:30 2014 +0200 @@ -48,6 +47,15 @@ offsetof(ngx_core_conf_t, master), NULL }, +#if (NGX_LINUX) + { ngx_string("mlockall"), + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + 0, + offsetof(ngx_core_conf_t, mlockall), + NULL }, +#endif + { ngx_string("timer_resolution"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -400,9 +408,16 @@ ngx_use_stderr = 0; +#if (NGX_LINUX) + if (ccf->mlockall) { + if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "mlockall failed"); + } + } +#endif + if (ngx_process == NGX_PROCESS_SINGLE) { ngx_single_process_cycle(cycle); - } else { ngx_master_process_cycle(cycle); } @@ -947,6 +962,11 @@ ccf->daemon = NGX_CONF_UNSET; ccf->master = NGX_CONF_UNSET; + +#if (NGX_LINUX) + ccf->mlockall = NGX_CONF_UNSET; +#endif + ccf->timer_resolution = NGX_CONF_UNSET_MSEC; ccf->worker_processes = NGX_CONF_UNSET; diff -r c86dd32573c0 src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Tue Jan 28 00:31:31 2014 +0400 +++ b/src/core/ngx_cycle.h Wed May 21 12:02:30 2014 +0200 @@ -76,6 +76,10 @@ ngx_flag_t daemon; ngx_flag_t master; +#if (NGX_LINUX) + ngx_flag_t mlockall; +#endif + ngx_msec_t timer_resolution; ngx_int_t worker_processes; diff -r c86dd32573c0 src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c Tue Jan 28 00:31:31 2014 +0400 +++ b/src/os/unix/ngx_process.c Wed May 21 12:02:30 2014 +0200 @@ -91,6 +91,11 @@ ngx_pid_t pid; ngx_int_t s; +#if (NGX_LINUX) + ngx_core_conf_t *ccf; + struct rlimit rlmt; +#endif + if (respawn >= 0) { s = respawn; @@ -195,8 +200,27 @@ case 0: ngx_pid = ngx_getpid(); + +#if (NGX_LINUX) + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + rlmt.rlim_cur = (rlim_t) RLIM_INFINITY; + rlmt.rlim_max = (rlim_t) RLIM_INFINITY; + + if (setrlimit(RLIMIT_MEMLOCK, &rlmt) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "setrlimit(RLIMIT_MEMLOCK) failed"); + } + + if (ccf->mlockall) { + if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "mlockall failed"); + } + } +#endif + proc(cycle, data); break; default: break;
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel