mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-12 08:27:24 +00:00
[MEDIUM] add support for anonymous ACLs
Anonymous ACLs allow the declaration of rules which rely directly on ACL expressions without passing via the declaration of an ACL. Example : With named ACLs : acl site_dead nbsrv(dynamic) lt 2 acl site_dead nbsrv(static) lt 2 monitor fail if site_dead With anonymous ACLs : monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }
This commit is contained in:
parent
711ad9eb27
commit
95fa4698f1
@ -6216,6 +6216,36 @@ and to every request on the "img", "video", "download" and "ftp" hosts :
|
||||
use_backend static if host_static or host_www url_static
|
||||
use_backend www if host_www
|
||||
|
||||
It is also possible to form rules using "anonymous ACLs". Those are unnamed ACL
|
||||
expressions that are built on the fly without needing to be declared. They must
|
||||
be enclosed between braces, with a space before and after each brace (because
|
||||
the braces must be seen as independant words). Example :
|
||||
|
||||
The following rule :
|
||||
|
||||
acl missing_cl hdr_cnt(Content-length) eq 0
|
||||
block if METH_POST missing_cl
|
||||
|
||||
Can also be written that way :
|
||||
|
||||
block if METH_POST { hdr_cnt(Content-length) eq 0 }
|
||||
|
||||
It is generally not recommended to use this construct because it's a lot easier
|
||||
to leave errors in the configuration when written that way. However, for very
|
||||
simple rules matching only one source IP address for instance, it can make more
|
||||
sense to use them than to declare ACLs with random names. Another example of
|
||||
good use is the following :
|
||||
|
||||
With named ACLs :
|
||||
|
||||
acl site_dead nbsrv(dynamic) lt 2
|
||||
acl site_dead nbsrv(static) lt 2
|
||||
monitor fail if site_dead
|
||||
|
||||
With anonymous ACLs :
|
||||
|
||||
monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }
|
||||
|
||||
See section 4.2 for detailed help on the "block" and "use_backend" keywords.
|
||||
|
||||
|
||||
|
47
src/acl.c
47
src/acl.c
@ -963,16 +963,45 @@ struct acl_cond *parse_acl_cond(const char **args, struct list *known_acl, int p
|
||||
continue;
|
||||
}
|
||||
|
||||
/* search for <word> in the known ACL names. If we do not find
|
||||
* it, let's look for it in the default ACLs, and if found, add
|
||||
* it to the list of ACLs of this proxy. This makes it possible
|
||||
* to override them.
|
||||
*/
|
||||
cur_acl = find_acl_by_name(word, known_acl);
|
||||
if (cur_acl == NULL) {
|
||||
cur_acl = find_acl_default(word, known_acl);
|
||||
if (cur_acl == NULL)
|
||||
if (strcmp(word, "{") == 0) {
|
||||
/* we may have a complete ACL expression between two braces,
|
||||
* find the last one.
|
||||
*/
|
||||
int arg_end = arg + 1;
|
||||
const char **args_new;
|
||||
|
||||
while (*args[arg_end] && strcmp(args[arg_end], "}") != 0)
|
||||
arg_end++;
|
||||
|
||||
if (!*args[arg_end])
|
||||
goto out_free_suite;
|
||||
|
||||
args_new = calloc(1, (arg_end - arg + 1) * sizeof(*args_new));
|
||||
if (!args_new)
|
||||
goto out_free_suite;
|
||||
|
||||
args_new[0] = ".noname";
|
||||
memcpy(args_new + 1, args + arg + 1, (arg_end - arg) * sizeof(*args_new));
|
||||
args_new[arg_end - arg] = "";
|
||||
cur_acl = parse_acl(args_new, known_acl);
|
||||
free(args_new);
|
||||
|
||||
if (!cur_acl)
|
||||
goto out_free_suite;
|
||||
arg = arg_end;
|
||||
}
|
||||
else {
|
||||
/* search for <word> in the known ACL names. If we do not find
|
||||
* it, let's look for it in the default ACLs, and if found, add
|
||||
* it to the list of ACLs of this proxy. This makes it possible
|
||||
* to override them.
|
||||
*/
|
||||
cur_acl = find_acl_by_name(word, known_acl);
|
||||
if (cur_acl == NULL) {
|
||||
cur_acl = find_acl_default(word, known_acl);
|
||||
if (cur_acl == NULL)
|
||||
goto out_free_suite;
|
||||
}
|
||||
}
|
||||
|
||||
cur_term = (struct acl_term *)calloc(1, sizeof(*cur_term));
|
||||
|
@ -4733,42 +4733,36 @@ int check_config_validity()
|
||||
}
|
||||
|
||||
if (curproxy->uri_auth && curproxy->uri_auth->userlist) {
|
||||
const char *uri_auth_compat_acl[3] = { ".internal-stats-auth-ok", "http_auth(.internal-stats-userlist)", ""};
|
||||
const char *uri_auth_compat_req[][4] = {
|
||||
{ "allow", "if", ".internal-stats-auth-ok", ""},
|
||||
{ "auth", "", "", ""},
|
||||
{ 0 },
|
||||
};
|
||||
const char *uri_auth_compat_req[10];
|
||||
struct req_acl_rule *req_acl;
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
if (parse_acl(uri_auth_compat_acl, &curproxy->acl) == NULL) {
|
||||
Alert("Error compiling internal auth-compat acl.\n");
|
||||
cfgerr++;
|
||||
goto out_uri_auth_compat;
|
||||
}
|
||||
/* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
|
||||
uri_auth_compat_req[i++] = "auth";
|
||||
|
||||
if (curproxy->uri_auth->auth_realm) {
|
||||
uri_auth_compat_req[1][1] = "realm";
|
||||
uri_auth_compat_req[1][2] = curproxy->uri_auth->auth_realm;
|
||||
} else
|
||||
uri_auth_compat_req[1][1] = "";
|
||||
|
||||
for (i = 0; *uri_auth_compat_req[i]; i++) {
|
||||
req_acl = parse_auth_cond(uri_auth_compat_req[i], "internal-stats-auth-compat", i, curproxy);
|
||||
if (!req_acl) {
|
||||
cfgerr++;
|
||||
break;
|
||||
}
|
||||
|
||||
LIST_ADDQ(&curproxy->uri_auth->req_acl, &req_acl->list);
|
||||
uri_auth_compat_req[i++] = "realm";
|
||||
uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
|
||||
}
|
||||
|
||||
uri_auth_compat_req[i++] = "unless";
|
||||
uri_auth_compat_req[i++] = "{";
|
||||
uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
|
||||
uri_auth_compat_req[i++] = "}";
|
||||
uri_auth_compat_req[i++] = "";
|
||||
|
||||
req_acl = parse_auth_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
|
||||
if (!req_acl) {
|
||||
cfgerr++;
|
||||
break;
|
||||
}
|
||||
|
||||
LIST_ADDQ(&curproxy->uri_auth->req_acl, &req_acl->list);
|
||||
|
||||
if (curproxy->uri_auth->auth_realm) {
|
||||
free(curproxy->uri_auth->auth_realm);
|
||||
curproxy->uri_auth->auth_realm = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
out_uri_auth_compat:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user