r1482 - trunk/varnish-cache/bin/varnishd

des at projects.linpro.no des at projects.linpro.no
Thu May 31 14:57:32 CEST 2007


Author: des
Date: 2007-05-31 14:57:30 +0200 (Thu, 31 May 2007)
New Revision: 1482

Modified:
   trunk/varnish-cache/bin/varnishd/heritage.h
   trunk/varnish-cache/bin/varnishd/mgt_child.c
   trunk/varnish-cache/bin/varnishd/mgt_param.c
   trunk/varnish-cache/bin/varnishd/varnishd.1
   trunk/varnish-cache/bin/varnishd/varnishd.c
Log:
Add two run-time parameters, "user" and "group", which specify an unprivileged
user and group to which the child process will switch immediately after fork()
returns, before it starts accepting connections.  The default values are
"nobody" and "nogroup" (they should probably be tweakable at compile time...)

Note that this does not provide full privilege separation, as there are still
channels between the parent and child processes which need to be monitored,
but it is an improvement on the previous situation.


Modified: trunk/varnish-cache/bin/varnishd/heritage.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/heritage.h	2007-05-31 09:18:56 UTC (rev 1481)
+++ trunk/varnish-cache/bin/varnishd/heritage.h	2007-05-31 12:57:30 UTC (rev 1482)
@@ -66,6 +66,12 @@
 
 struct params {
 
+	/* Unprivileged user / group */
+	char			*user;
+	uid_t			uid;
+	char			*group;
+	gid_t			gid;
+
 	/* TTL used for lack of anything better */
 	unsigned		default_ttl;
 

Modified: trunk/varnish-cache/bin/varnishd/mgt_child.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_child.c	2007-05-31 09:18:56 UTC (rev 1481)
+++ trunk/varnish-cache/bin/varnishd/mgt_child.c	2007-05-31 12:57:30 UTC (rev 1482)
@@ -177,6 +177,11 @@
 	if (i < 0)
 		errx(1, "Could not fork child");
 	if (i == 0) {
+		if (geteuid() == 0) {
+			XXXAZ(setgid(params->gid) == -1);
+			XXXAZ(setuid(params->uid) == -1);
+		}
+
 		/* Redirect stdin/out/err */
 		AZ(close(0));
 		i = open("/dev/null", O_RDONLY);

Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_param.c	2007-05-31 09:18:56 UTC (rev 1481)
+++ trunk/varnish-cache/bin/varnishd/mgt_param.c	2007-05-31 12:57:30 UTC (rev 1482)
@@ -29,6 +29,10 @@
  * $Id$
  */
 
+#include <sys/types.h>
+
+#include <grp.h>
+#include <pwd.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -134,6 +138,70 @@
 /*--------------------------------------------------------------------*/
 
 static void
+tweak_user(struct cli *cli, struct parspec *par, const char *arg)
+{
+	struct passwd *pw;
+	struct group *gr;
+
+	(void)par;
+	if (arg != NULL) {
+		if ((pw = getpwnam(arg)) == NULL) {
+			cli_out(cli, "Unknown user");
+			cli_result(cli, CLIS_PARAM);
+			return;
+		}
+		if (params->user)
+			free(params->user);
+		params->user = strdup(pw->pw_name);
+		AN(params->user);
+		params->uid = pw->pw_uid;
+
+		/* set group to user's primary group */
+		if (params->group)
+			free(params->group);
+		if ((gr = getgrgid(pw->pw_gid)) != NULL &&
+		    (gr = getgrnam(gr->gr_name)) != NULL &&
+		    gr->gr_gid == pw->pw_gid) {
+			params->group = strdup(gr->gr_name);
+			AN(params->group);
+		}
+		params->gid = pw->pw_gid;
+	} else if (params->user) {
+		cli_out(cli, "%s (%d)", params->user, (int)params->uid);
+	} else {
+		cli_out(cli, "%d", (int)params->uid);
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+tweak_group(struct cli *cli, struct parspec *par, const char *arg)
+{
+	struct group *gr;
+
+	(void)par;
+	if (arg != NULL) {
+		if ((gr = getgrnam(arg)) == NULL) {
+			cli_out(cli, "Unknown group");
+			cli_result(cli, CLIS_PARAM);
+			return;
+		}
+		if (params->group)
+			free(params->group);
+		params->group = strdup(gr->gr_name);
+		AN(params->group);
+		params->gid = gr->gr_gid;
+	} else if (params->group) {
+		cli_out(cli, "%s (%d)", params->group, (int)params->gid);
+	} else {
+		cli_out(cli, "%d", (int)params->gid);
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
 tweak_default_ttl(struct cli *cli, struct parspec *par, const char *arg)
 {
 
@@ -447,6 +515,15 @@
  * change its default value.
  */
 static struct parspec parspec[] = {
+	{ "user", tweak_user,
+	        "The unprivileged user to run as.  Setting this will "
+		"also set \"group\" to the specified user's primary group.\n"
+		MUST_RESTART,
+		"nobody" },
+	{ "group", tweak_group,
+	        "The unprivileged group to run as.\n"
+		MUST_RESTART,
+		"nogroup" },
 	{ "default_ttl", tweak_default_ttl,
 		"The TTL assigned to objects if neither the backend nor "
 		"the VCL code assigns one.\n"

Modified: trunk/varnish-cache/bin/varnishd/varnishd.1
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.1	2007-05-31 09:18:56 UTC (rev 1481)
+++ trunk/varnish-cache/bin/varnishd/varnishd.1	2007-05-31 12:57:30 UTC (rev 1482)
@@ -28,7 +28,7 @@
 .\"
 .\" $Id$
 .\"
-.Dd May 16, 2007
+.Dd May 30, 2007
 .Dt VARNISHD 1
 .Os
 .Sh NAME
@@ -40,12 +40,14 @@
 .Op Fl b Ar host Ns Op : Ns Ar port
 .Op Fl d
 .Op Fl f Ar config
+.Op Fl g Ar group
 .Op Fl h Ar type Ns Op , Ns Ar options
 .Op Fl P Ar file
 .Op Fl p Ar param Ns = Ns Ar value
 .Op Fl s Ar type Ns Op , Ns Ar options
 .Op Fl T Ar address Ns Op : Ns Ar port
 .Op Fl t Ar ttl
+.Op Fl u Ar user
 .Op Fl V
 .Op Fl w Ar min Ns Op , Ns Ar max Ns Op , Ns Ar timeout
 .Sh DESCRIPTION
@@ -114,6 +116,12 @@
 See
 .Xr vcl 7
 for details on VCL syntax.
+.It Fl g Ar group
+Specifies the name of an unprivileged group to which the child process
+should switch before it starts accepting connections.
+This is a shortcut for specifying the
+.Va group
+run-time parameter.
 .It Fl h Ar type Ns Op , Ns Ar options
 Specifies the hash algorithm.
 See
@@ -148,6 +156,15 @@
 This is a shortcut for specifying the
 .Va default_ttl
 run-time parameter.
+.It Fl u Ar user
+Specifies the name of an unprivileged user to which the child process
+should switch before it starts accepting connections.
+This is a shortcut for specifying the
+.Va user
+run-time parameter.
+.Pp
+If specifying both a user and a group, the user should be specified
+first.
 .It Fl V
 Display the version number and exit.
 .It Fl w Ar min Ns Op , Ns Ar max Ns Op , Ns Ar timeout
@@ -349,6 +366,20 @@
 backend server does not specify a content length.
 .Pp
 The default is 128 kilobytes.
+.It Va group
+The name of an unprivileged group to which the child process should
+switch before it starts accepting connections.
+Note that setting
+.Va user
+will automatically set
+.Va group
+to the primary group of the specified user, so if both
+.Va user
+and
+.Va group
+are specified, the latter should be specified last.
+.Pp
+The default is "nogroup".
 .It Va http_workspace
 The size of the per-session workspace for HTTP protocol data.
 For performance reasons, this space is preallocated, so any change to
@@ -443,6 +474,20 @@
 .Va thread_pool_min .
 .Pp
 The default is 120 seconds.
+.It Va user
+The name of an unprivileged user to which the child process should
+switch before it starts accepting connections.
+Note that setting
+.Va user
+will automatically set
+.Va group
+to the primary group of the specified user, so if both
+.Va user
+and
+.Va group
+are specified, the latter should be specified last.
+.Pp
+The default is "nobody".
 .It Va vcl_trace
 Whether to issue log entries for calls to VCL code and their results.
 Note that this will generate large amounts of log data.

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2007-05-31 09:18:56 UTC (rev 1481)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2007-05-31 12:57:30 UTC (rev 1482)
@@ -401,7 +401,7 @@
 	unsigned d_flag = 0;
 	const char *b_arg = NULL;
 	const char *f_arg = NULL;
-	const char *h_flag = "classic";
+	const char *h_arg = "classic";
 	const char *P_arg = NULL;
 	const char *s_arg = "file";
 	const char *T_arg = NULL;
@@ -441,7 +441,7 @@
 	MCF_ParamInit(cli);
 	cli_check(cli);
 
-	while ((o = getopt(argc, argv, "a:b:Cdf:h:P:p:s:T:t:Vw:")) != -1)
+	while ((o = getopt(argc, argv, "a:b:Cdf:g:h:P:p:s:T:t:u:Vw:")) != -1)
 		switch (o) {
 		case 'a':
 			MCF_ParamSet(cli, "listen_address", optarg);
@@ -459,8 +459,11 @@
 		case 'f':
 			f_arg = optarg;
 			break;
+		case 'g':
+			MCF_ParamSet(cli, "group", optarg);
+			break;
 		case 'h':
-			h_flag = optarg;
+			h_arg = optarg;
 			break;
 		case 'P':
 			P_arg = optarg;
@@ -483,6 +486,9 @@
 		case 'T':
 			T_arg = optarg;
 			break;
+		case 'u':
+			MCF_ParamSet(cli, "user", optarg);
+			break;
 		case 'V':
 			varnish_version("varnishd");
 			exit(0);
@@ -521,7 +527,7 @@
 		exit (0);
 
 	setup_storage(s_arg);
-	setup_hash(h_flag);
+	setup_hash(h_arg);
 
 	VSL_MgtInit(SHMLOG_FILENAME, 8*1024*1024);
 




More information about the varnish-commit mailing list