From 31c4a9e21ebf55a7252a6e9363e671264e281425 Mon Sep 17 00:00:00 2001 From: Jim Jagielski <jim@apache.org> Date: Thu, 13 Jan 2011 15:59:22 +0000 Subject: [PATCH] Move nonce to balancer struct and add logic for nonce and growth. Adjust mmn and update doccos git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1058629 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/mod/mod_proxy.xml | 19 ++++++++ docs/manual/mod/mod_proxy_balancer.xml | 33 +------------ include/ap_mmn.h | 5 ++ modules/proxy/mod_proxy.c | 19 ++++++++ modules/proxy/mod_proxy.h | 8 ++-- modules/proxy/mod_proxy_balancer.c | 64 ++++++-------------------- modules/proxy/proxy_util.c | 5 ++ 7 files changed, 70 insertions(+), 83 deletions(-) diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml index bcc0b7744f..8c127f6bdb 100644 --- a/docs/manual/mod/mod_proxy.xml +++ b/docs/manual/mod/mod_proxy.xml @@ -837,6 +837,7 @@ expressions</description> ProxyPass /example http://backend.example.com max=20 ttl=120 retry=300 </example> + <table border="2"><tr><th>BalancerMember parameters</th></tr></table> <table> <tr><th>Parameter</th> <th>Default</th> @@ -1009,6 +1010,7 @@ expressions</description> parameters can be add to this virtual worker. See <module>mod_proxy_balancer</module> for more information about how the balancer works. </p> + <table border="2"><tr><th>Balancer parameters</th></tr></table> <table> <tr><th>Parameter</th> <th>Default</th> @@ -1058,6 +1060,23 @@ expressions</description> force the worker into error state when the backend returns any status code in the list. Worker recovery behaves the same as other worker errors. </td></tr> + <tr><td>nonce</td> + <td><auto></td> + <td>The protective nonce used in the <code>balancer-manager</code> application page. + The default is to use an automatically determined UUID-based + nonce, to provide for further protection for the page. If set, + then the nonce is set to that value. A setting of <code>None</code> + disables all nonce checking. + <note><title>Note</title> + <p>In addition to the nonce, the <code>balancer-manager</code> page + should be protected via an ACL.</p> + </note> + </td></tr> + <tr><td>growth</td> + <td>0</td> + <td>Number of additional BalancerMembers to allow to be added + to this balancer in addition to those defined at configuration. + </td></tr> </table> <p>A sample balancer setup</p> diff --git a/docs/manual/mod/mod_proxy_balancer.xml b/docs/manual/mod/mod_proxy_balancer.xml index 1878faa66f..90eef4500f 100644 --- a/docs/manual/mod/mod_proxy_balancer.xml +++ b/docs/manual/mod/mod_proxy_balancer.xml @@ -62,7 +62,8 @@ for use: Request Counting, Weighted Traffic Counting and Pending Request Counting. These are controlled via the <code>lbmethod</code> value of the Balancer definition. See the <directive module="mod_proxy">ProxyPass</directive> - directive for more information.</p> + directive for more information, especially regarding how to + configure the Balancer and BalancerMembers.</p> </section> <section id="stickyness"> @@ -300,34 +301,4 @@ be to high for production servers under high load.</p> </section> -<directivesynopsis> -<name>BalancerNonce</name> -<description>Set the nonce used in the balancer-manager application</description> -<syntax>BalancerNonce Default|None|Set "value"</syntax> -<default>ProxyStatus Default</default> -<contextlist><context>server config</context> -<context>virtual host</context> -</contextlist> -<compatibility>Available in version 2.4 and later</compatibility> - -<usage> - <p>This directive specifies the protective nonce used in the - <code>balancer-manager</code> application page.</p> - <p>The default is to use an automatically determined UUID-based - nonce, to provide for further protection for the page. If set - to <code>Set</code>, then the next argument sets the nonce to that - value. A setting of <code>None</code> disables all nonce checking.</p> - - <example> - BalancerNonce Set "RealGudSharedSecret" - </example> - - <note><title>Note</title> - <p>In addition to the nonce, the <code>balancer-manager</code> page - should be protected via an ACL.</p> - </note> - -</usage> -</directivesynopsis> - </modulesynopsis> diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 9cf3d41a0e..db3bfa1c5e 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -289,6 +289,11 @@ * 20101113.2 (2.3.9-dev) Add ap_expr_exec_re() * 20101204.0 (2.3.10-dev) Add _t to ap_expr's typedef names * 20101223.0 (2.3.11-dev) Remove cleaned from proxy_conn_rec. + * 20101223.1 (2.3.11-dev) Rework mod_proxy, et.al. Remove proxy_worker_stat + * and replace w/ proxy_worker_shared; remove worker + * info from scoreboard and use slotmem; Allow + * dynamic growth of balancer members; Remove + * BalancerNonce in favor of 'nonce' parameter. */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 94c2954b9c..5988ed530f 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -399,6 +399,25 @@ static const char *set_balancer_param(proxy_server_conf *conf, } } + else if (!strcasecmp(key, "nonce")) { + if (!strcasecmp(val, "None")) { + *balancer->nonce = '\0'; + } + else { + if (strlen(val) > sizeof(balancer->nonce)-1) { + return "Provided nonce is too large"; + } + else { + apr_cpystrn(balancer->nonce, val, sizeof(balancer->nonce)); + } + } + } + else if (!strcasecmp(key, "growth")) { + ival = atoi(val); + if (ival < 1 || ival > 100) /* arbitrary limit here */ + return "growth must be between 1 and 100"; + balancer->growth = ival; + } else { return "unknown Balancer parameter"; } diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 0c7bdac96d..b66d524e1a 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -42,6 +42,7 @@ #include "apr_reslist.h" #define APR_WANT_STRFUNC #include "apr_want.h" +#include "apr_uuid.h" #include "util_mutex.h" #include "apr_global_mutex.h" #include "apr_thread_mutex.h" @@ -369,12 +370,13 @@ struct proxy_balancer { const char *sticky; /* sticky session identifier */ int max_attempts; /* Number of attempts before failing */ + apr_time_t updated; /* timestamp of last update */ + char nonce[APR_UUID_FORMATTED_LENGTH + 1]; + apr_global_mutex_t *mutex; /* global lock for updating lb params */ + void *context; /* general purpose storage */ int sticky_force:1; /* Disable failover for sticky sessions */ int scolonsep:1; /* true if ';' seps sticky session paths */ int max_attempts_set:1; - void *context; /* general purpose storage */ - apr_time_t updated; /* timestamp of last update */ - apr_global_mutex_t *mutex; /* global lock for updating lb params */ }; struct proxy_balancer_method { diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 7990529dd4..e7566051c7 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -21,7 +21,6 @@ #include "ap_mpm.h" #include "apr_version.h" #include "apr_hooks.h" -#include "apr_uuid.h" #include "apr_date.h" static const char *balancer_mutex_type = "proxy-balancer-shm"; @@ -29,8 +28,6 @@ ap_slotmem_provider_t *storage = NULL; module AP_MODULE_DECLARE_DATA proxy_balancer_module; -static char balancer_nonce[APR_UUID_FORMATTED_LENGTH + 1]; - /* * Register our mutex type before the config is read so we * can adjust the mutex settings using the Mutex directive. @@ -697,7 +694,6 @@ static apr_status_t lock_remove(void *data) static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { - apr_uuid_t uuid; void *data; void *sconf = s->module_config; proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); @@ -711,10 +707,6 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_cleanup_null, s->process->pool); return OK; } - /* Retrieve a UUID and store the nonce for the lifetime of - * the process. */ - apr_uuid_get(&uuid); - apr_uuid_format(balancer_nonce, &uuid); /* * Get worker slotmem setup @@ -849,20 +841,23 @@ static int balancer_handler(request_rec *r) } } - /* Check that the supplied nonce matches this server's nonce; - * otherwise ignore all parameters, to prevent a CSRF attack. */ - if (*balancer_nonce && - ((name = apr_table_get(params, "nonce")) == NULL - || strcmp(balancer_nonce, name) != 0)) { - apr_table_clear(params); - } - if ((name = apr_table_get(params, "b"))) bsel = ap_proxy_get_balancer(r->pool, conf, apr_pstrcat(r->pool, BALANCER_PREFIX, name, NULL)); + if ((name = apr_table_get(params, "w"))) { wsel = ap_proxy_get_worker(r->pool, bsel, conf, name); } + +#if 0 + /* Check that the supplied nonce matches this server's nonce; + * otherwise ignore all parameters, to prevent a CSRF attack. */ + if (*balancer_nonce && + ((name = apr_table_get(params, "nonce")) == NULL + || strcmp(balancer_nonce, name) != 0)) { + apr_table_clear(params); + } +#endif /* First set the params */ /* * Note that it is not possible set the proxy_balancer because it is not @@ -984,7 +979,7 @@ static int balancer_handler(request_rec *r) ap_rvputs(r, "<tr>\n<td><a href=\"", r->uri, "?b=", balancer->name + sizeof(BALANCER_PREFIX) - 1, "&w=", ap_escape_uri(r->pool, worker->s->name), - "&nonce=", balancer_nonce, + "&nonce=", balancer->nonce, "\">", NULL); ap_rvputs(r, worker->s->name, "</a></td>", NULL); ap_rvputs(r, "<td>", ap_escape_html(r->pool, worker->s->route), @@ -1049,7 +1044,7 @@ static int balancer_handler(request_rec *r) ap_rvputs(r, "value=\"", bsel->name + sizeof(BALANCER_PREFIX) - 1, "\">\n", NULL); ap_rvputs(r, "<input type=hidden name=\"nonce\" value=\"", - balancer_nonce, "\">\n", NULL); + bsel->nonce, "\">\n", NULL); ap_rvputs(r, "</form>\n", NULL); ap_rputs("<hr />\n", r); } @@ -1090,7 +1085,7 @@ static void balancer_child_init(apr_pool_t *p, server_rec *s) p); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, - "Failed to reopen mutex %: %s in child", + "Failed to reopen mutex %s: %s in child", balancer->name, balancer_mutex_type); exit(1); /* Ugly, but what else? */ } @@ -1111,35 +1106,6 @@ static void balancer_child_init(apr_pool_t *p, server_rec *s) } -static const char *set_balancer_nonce (cmd_parms *cmd, void *dummy, const char *arg, - const char *val) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - if (!strcasecmp(arg, "None")) { - *balancer_nonce = '\0'; - } else if (!strcasecmp(arg, "Set")) { - if (val) { - apr_cpystrn(balancer_nonce, val, sizeof(balancer_nonce)); - } else { - return "BalancerNonce Set requires an argument"; - } - } else if (strcasecmp(arg, "Default")) { - return "Bad argument for BalancerNonce: Must be 'Set', 'None' or 'Default'"; - } - return NULL; -} - -static const command_rec balancer_cmds[] = -{ - AP_INIT_TAKE12("BalancerNonce", set_balancer_nonce, NULL, - RSRC_CONF, "Set value for balancer-manager nonce"), - {NULL} -}; - static void ap_proxy_balancer_register_hook(apr_pool_t *p) { /* Only the mpm_winnt has child init hook handler. @@ -1163,6 +1129,6 @@ AP_DECLARE_MODULE(proxy_balancer) = { NULL, /* merge per-directory config structures */ NULL, /* create per-server config structure */ NULL, /* merge per-server config structures */ - balancer_cmds, /* command apr_table_t */ + NULL, /* command apr_table_t */ ap_proxy_balancer_register_hook /* register hooks */ }; diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 64c112044c..cf81e2474c 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1332,6 +1332,7 @@ PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p, { char *c, *q, *uri = apr_pstrdup(p, url); proxy_balancer_method *lbmethod; + apr_uuid_t uuid; /* We should never get here without a valid BALANCER_PREFIX... */ @@ -1360,6 +1361,10 @@ PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p, (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker *)); (*balancer)->updated = apr_time_now(); (*balancer)->mutex = NULL; + /* Retrieve a UUID and store the nonce for the lifetime of + * the process. */ + apr_uuid_get(&uuid); + apr_uuid_format((*balancer)->nonce, &uuid); return NULL; } -- 2.40.0