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

Reply via email to