Welcome! Log In Create A New Profile

Advanced

[PATCH] Start use capabilities on linux

Kirill A. Korinskiy
March 17, 2009 05:59PM
From: Kirill A. Korinskiy <catap@catap.ru>

The nginx required privilege mode only on master process and only bind
ports <1024. In linux proccess can bind ports <1024 in not privilege
mode if the process does capset(CAP_NET_BIND_SERVICE).
---
auto/lib/capabilities/conf | 20 +++++++++++++
auto/os/linux | 3 ++
src/core/nginx.c | 7 ++++-
src/core/ngx_cycle.c | 1 -
src/os/unix/ngx_process_cycle.c | 22 ++------------
src/os/unix/ngx_user.c | 61 +++++++++++++++++++++++++++++++++++++++
src/os/unix/ngx_user.h | 14 +++++++++
7 files changed, 107 insertions(+), 21 deletions(-)
create mode 100644 auto/lib/capabilities/conf

diff --git a/auto/lib/capabilities/conf b/auto/lib/capabilities/conf
new file mode 100644
index 0000000000000000000000000000000000000000..484401c045a67cc0be523f64de2f177b14cae97b
--- /dev/null
+++ b/auto/lib/capabilities/conf
@@ -0,0 +1,20 @@
+
+# Copyright (C) Kirill A. Korinskiy
+
+
+ngx_feature="capabilities"
+ngx_feature_name="NGX_HAVE_CAPABILITIES"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/capability.h>"
+ngx_feature_path=
+ngx_feature_libs="-lcap"
+ngx_feature_test="cap_user_header_t header;
+ cap_user_data_t cap;
+ capset(header, cap);
+ return -1;"
+. auto/feature
+
+
+if [ $ngx_found = yes ]; then
+ CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+fi
diff --git a/auto/os/linux b/auto/os/linux
index 3c2c8419d58cafcfafb93d30032cc7c8553cccb8..e4e036c2aaafb59c174e665a4da9a2b2db8c3e2b 100644
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -121,3 +121,6 @@ ngx_feature_libs=
ngx_feature_test="long mask = 0;
sched_setaffinity(0, 32, (cpu_set_t *) &mask)"
. auto/feature
+
+# capabilities
+. auto/lib/capabilities/conf
diff --git a/src/core/nginx.c b/src/core/nginx.c
index e6ebae54431f074fbc41974c35c44ac9ab4492cc..78e8227b8b1425a6aa7df65cc0d36f67f20ad7d9 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -322,6 +322,12 @@ main(int argc, char *const *argv)

ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

+#if (NGX_HAVE_CAPABILITIES)
+ if (geteuid() == 0) {
+ ngx_set_capabilities(cycle);
+ }
+#endif
+
ngx_process = ccf->master ? NGX_PROCESS_MASTER : NGX_PROCESS_SINGLE;

#if (NGX_WIN32)
@@ -334,7 +340,6 @@ main(int argc, char *const *argv)
if (ngx_service(cycle->log) != NGX_OK) {
return 1;
}
-
return 0;
}
#endif
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index f3dc8619b484c9727770233b26e6580ca32fda80..ce8de0dd6d827235ace0c7f328d0db2c604af070 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -14,7 +14,6 @@ static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2);
static void ngx_clean_old_cycles(ngx_event_t *ev);

-
volatile ngx_cycle_t *ngx_cycle;
ngx_array_t ngx_old_cycles;

diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index a14a03c748dd2793b5e2ea0b18f709267df01d3e..f0950e64a353d1c46c32bbb97964c7924b67e813 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -854,27 +854,11 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
}
#endif

+#ifndef NGX_HAVE_CAPABILITIES
if (geteuid() == 0) {
- if (setgid(ccf->group) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "setgid(%d) failed", ccf->group);
- /* fatal */
- exit(2);
- }
-
- if (initgroups(ccf->username, ccf->group) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "initgroups(%s, %d) failed",
- ccf->username, ccf->group);
- }
-
- if (setuid(ccf->user) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "setuid(%d) failed", ccf->user);
- /* fatal */
- exit(2);
- }
+ ngx_switch_user(cycle);
}
+#endif

#if (NGX_HAVE_SCHED_SETAFFINITY)

diff --git a/src/os/unix/ngx_user.c b/src/os/unix/ngx_user.c
index 4bad1c3070e517fadb53007be7f90acb576fba4f..d5ebb6c3e22b96d66a5e816dbfa860635fa7a3d8 100644
--- a/src/os/unix/ngx_user.c
+++ b/src/os/unix/ngx_user.c
@@ -7,6 +7,10 @@
#include <ngx_config.h>
#include <ngx_core.h>

+#if (NGX_HAVE_CAPABILITIES)
+#include <sys/capability.h>
+#endif
+

/*
* Solaris has thread-safe crypt()
@@ -106,3 +110,60 @@ ngx_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
#endif

#endif /* NGX_CRYPT */
+
+void ngx_switch_user(ngx_cycle_t *cycle)
+{
+ ngx_core_conf_t *ccf;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+ if (setgid(ccf->group) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "setgid(%d) failed", ccf->group);
+ /* fatal */
+ exit(2);
+ }
+
+ if (initgroups(ccf->username, ccf->group) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "initgroups(%s, %d) failed",
+ ccf->username, ccf->group);
+ }
+
+ if (setuid(ccf->user) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "setuid(%d) failed", ccf->user);
+ /* fatal */
+ exit(2);
+ }
+}
+
+#if (NGX_HAVE_CAPABILITIES)
+
+void ngx_set_capabilities(ngx_cycle_t *cycle)
+{
+ ngx_core_conf_t *ccf;
+
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+ ngx_switch_user(cycle);
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+
+ cap.effective = cap.permitted = (1 << CAP_NET_BIND_SERVICE);
+
+ if (capset(&header, &cap) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+ "capset(%d) failed", ccf->user);
+ /* fatal */
+ exit(2);
+ }
+}
+
+#endif
diff --git a/src/os/unix/ngx_user.h b/src/os/unix/ngx_user.h
index a24a66bf34ead7e9a1f8007e1c4be785601a937c..1ea5e360219af2dab4da5df1811c3a30eb783821 100644
--- a/src/os/unix/ngx_user.h
+++ b/src/os/unix/ngx_user.h
@@ -15,10 +15,24 @@
typedef uid_t ngx_uid_t;
typedef gid_t ngx_gid_t;

+#if (NGX_CRYPT)
+
+#if (NGX_HAVE_GNU_CRYPT_R)
+

ngx_int_t ngx_crypt(ngx_pool_t *pool, u_char *key, u_char *salt,
u_char **encrypted);

+#endif
+
+#endif /* NGX_CRYPT */
+
+void ngx_switch_user(ngx_cycle_t *cycle);
+
+#if (NGX_HAVE_CAPABILITIES)
+
+void ngx_set_capabilities(ngx_cycle_t *cycle);

+#endif

#endif /* _NGX_USER_H_INCLUDED_ */
--
1.6.2
Subject Author Posted

[PATCH] Start use capabilities on linux

Kirill A. Korinskiy March 17, 2009 05:59PM

Re: [PATCH] Start use capabilities on linux

Maxim Dounin March 17, 2009 09:43PM

Re: [PATCH] Start use capabilities on linux

Igor Sysoev March 18, 2009 02:30AM

[PATCH 2/2] Setting more capabilities(CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH and CAP_SETUID).

Kirill A. Korinskiy March 18, 2009 12:03PM

[PATCH] Setting more capabilities(CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH and CAP_SETUID).

Kirill A. Korinskiy March 18, 2009 12:45PM

[PATCH 3/3] Add support libcap1

Kirill A. Korinskiy March 18, 2009 09:02PM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 179
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready