mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-31 10:31:46 +00:00
MEDIUM: rules/acl: Parse TCP/HTTP rules and acls defined in defaults sections
TCP and HTTP rules can now be defined in defaults sections, but only those with a name. Because these rules may use conditions based on ACLs, ACLs can also be defined in defaults sections. However there are some limitations: * A defaults section defining TCP/HTTP rules cannot be used by a defaults section * A defaults section defining TCP/HTTP rules cannot be used bu a listen section * A defaults sections defining TCP/HTTP rules cannot be used by frontends and backends at the same time * A defaults sections defining 'tcp-request connection' or 'tcp-request session' rules cannot be used by backends * A defaults sections defining 'tcp-response content' rules cannot be used by frontends The TCP request/response inspect-delay of a proxy is now inherited from the defaults section it uses. For now, these rules are only parsed. No evaluation is performed.
This commit is contained in:
parent
6ff7de5d64
commit
ee08d6cc74
@ -333,6 +333,70 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (curr_defproxy && (!LIST_ISEMPTY(&curr_defproxy->http_req_rules) ||
|
||||
!LIST_ISEMPTY(&curr_defproxy->http_res_rules) ||
|
||||
!LIST_ISEMPTY(&curr_defproxy->http_after_res_rules) ||
|
||||
!LIST_ISEMPTY(&curr_defproxy->tcp_req.l4_rules) ||
|
||||
!LIST_ISEMPTY(&curr_defproxy->tcp_req.l5_rules) ||
|
||||
!LIST_ISEMPTY(&curr_defproxy->tcp_req.inspect_rules) ||
|
||||
!LIST_ISEMPTY(&curr_defproxy->tcp_rep.inspect_rules))) {
|
||||
/* If the current default proxy defines TCP/HTTP rules, the
|
||||
* current proxy will keep a reference on it. But some sanity
|
||||
* checks are performed first:
|
||||
*
|
||||
* - It cannot be used to init a defaults section
|
||||
* - It cannot be used to init a listen section
|
||||
* - It cannot be used to init backend and frontend sections at
|
||||
* same time. It can be used to init several sections of the
|
||||
* same type only.
|
||||
* - It cannot define L4/L5 TCP rules if it is used to init
|
||||
* backend sections.
|
||||
* - It cannot define 'tcp-response content' rules if it
|
||||
* is used to init frontend sections.
|
||||
*
|
||||
* If no error is found, refcount of the default proxy is incremented.
|
||||
*/
|
||||
|
||||
/* Note: Add tcpcheck_rules too if unresolve args become allowed in defaults section */
|
||||
if (rc & PR_CAP_DEF) {
|
||||
ha_alert("parsing [%s:%d]: a defaults section cannot inherit from a defaults section defining TCP/HTTP rules (defaults section at %s:%d).\n",
|
||||
file, linenum, curr_defproxy->conf.file, curr_defproxy->conf.line);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
}
|
||||
else if ((rc & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
|
||||
ha_alert("parsing [%s:%d]: a listen section cannot inherit from a defaults section defining TCP/HTTP rules.\n",
|
||||
file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
}
|
||||
else {
|
||||
char defcap = (curr_defproxy->cap & PR_CAP_LISTEN);
|
||||
|
||||
if ((defcap == PR_CAP_BE || defcap == PR_CAP_FE) && (rc & PR_CAP_LISTEN) != defcap) {
|
||||
ha_alert("parsing [%s:%d]: frontends and backends cannot inherit from the same defaults section"
|
||||
" if it defines TCP/HTTP rules (defaults section at %s:%d).\n",
|
||||
file, linenum, curr_defproxy->conf.file, curr_defproxy->conf.line);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
}
|
||||
else if (!(rc & PR_CAP_FE) && (!LIST_ISEMPTY(&curr_defproxy->tcp_req.l4_rules) ||
|
||||
!LIST_ISEMPTY(&curr_defproxy->tcp_req.l5_rules))) {
|
||||
ha_alert("parsing [%s:%d]: a backend section cannot inherit from a defaults section defining"
|
||||
" 'tcp-request connection' or 'tcp-request session' rules (defaults section at %s:%d).\n",
|
||||
file, linenum, curr_defproxy->conf.file, curr_defproxy->conf.line);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
}
|
||||
else if (!(rc & PR_CAP_BE) && !LIST_ISEMPTY(&curr_defproxy->tcp_rep.inspect_rules)) {
|
||||
ha_alert("parsing [%s:%d]: a frontend section cannot inherit from a defaults section defining"
|
||||
" 'tcp-response content' rules (defaults section at %s:%d).\n",
|
||||
file, linenum, curr_defproxy->conf.file, curr_defproxy->conf.line);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
}
|
||||
else {
|
||||
curr_defproxy->cap = (curr_defproxy->cap & ~PR_CAP_LISTEN) | (rc & PR_CAP_LISTEN);
|
||||
proxy_ref_defaults(curproxy, curr_defproxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (curr_defproxy && (curr_defproxy->tcpcheck_rules.flags & TCPCHK_RULES_PROTO_CHK) &&
|
||||
(curproxy->cap & PR_CAP_LISTEN) == PR_CAP_BE) {
|
||||
/* If the current default proxy defines tcpcheck rules, the
|
||||
@ -641,8 +705,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
err_code |= ERR_WARN;
|
||||
}
|
||||
else if (strcmp(args[0], "acl") == 0) { /* add an ACL */
|
||||
if (curproxy->cap & PR_CAP_DEF) {
|
||||
ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||
if ((curproxy->cap & PR_CAP_DEF) && strlen(curproxy->id) == 0) {
|
||||
ha_alert("parsing [%s:%d] : '%s' not allowed in anonymous 'defaults' section.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
@ -1212,8 +1276,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
else if (strcmp(args[0], "http-request") == 0) { /* request access control: allow/deny/auth */
|
||||
struct act_rule *rule;
|
||||
|
||||
if (curproxy->cap & PR_CAP_DEF) {
|
||||
ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||
if ((curproxy->cap & PR_CAP_DEF) && strlen(curproxy->id) == 0) {
|
||||
ha_alert("parsing [%s:%d] : '%s' not allowed in anonymous 'defaults' section.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
@ -1243,8 +1307,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
else if (strcmp(args[0], "http-response") == 0) { /* response access control */
|
||||
struct act_rule *rule;
|
||||
|
||||
if (curproxy->cap & PR_CAP_DEF) {
|
||||
ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||
if ((curproxy->cap & PR_CAP_DEF) && strlen(curproxy->id) == 0) {
|
||||
ha_alert("parsing [%s:%d] : '%s' not allowed in anonymous 'defaults' section.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
@ -1273,8 +1337,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
else if (strcmp(args[0], "http-after-response") == 0) {
|
||||
struct act_rule *rule;
|
||||
|
||||
if (curproxy->cap & PR_CAP_DEF) {
|
||||
ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||
if ((curproxy->cap & PR_CAP_DEF) && strlen(curproxy->id) == 0) {
|
||||
ha_alert("parsing [%s:%d] : '%s' not allowed in anonymous 'defaults' section.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -2520,6 +2520,15 @@ int check_config_validity()
|
||||
*/
|
||||
if (curproxy->defpx) {
|
||||
if (!(curproxy->defpx->flags & PR_FL_READY)) {
|
||||
/* check validity for 'tcp-request' layer 4/5/6/7 rules */
|
||||
cfgerr += check_action_rules(&curproxy->defpx->tcp_req.l4_rules, curproxy->defpx, &err_code);
|
||||
cfgerr += check_action_rules(&curproxy->defpx->tcp_req.l5_rules, curproxy->defpx, &err_code);
|
||||
cfgerr += check_action_rules(&curproxy->defpx->tcp_req.inspect_rules, curproxy->defpx, &err_code);
|
||||
cfgerr += check_action_rules(&curproxy->defpx->tcp_rep.inspect_rules, curproxy->defpx, &err_code);
|
||||
cfgerr += check_action_rules(&curproxy->defpx->http_req_rules, curproxy->defpx, &err_code);
|
||||
cfgerr += check_action_rules(&curproxy->defpx->http_res_rules, curproxy->defpx, &err_code);
|
||||
cfgerr += check_action_rules(&curproxy->defpx->http_after_res_rules, curproxy->defpx, &err_code);
|
||||
|
||||
err = NULL;
|
||||
i = smp_resolve_args(curproxy->defpx, &err);
|
||||
cfgerr += i;
|
||||
@ -3612,8 +3621,8 @@ out_uri_auth_compat:
|
||||
if (!curproxy->accept)
|
||||
curproxy->accept = frontend_accept;
|
||||
|
||||
if (curproxy->tcp_req.inspect_delay ||
|
||||
!LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
|
||||
if (!LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules) ||
|
||||
(curproxy->defpx && !LIST_ISEMPTY(&curproxy->defpx->tcp_req.inspect_rules)))
|
||||
curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
|
||||
|
||||
if (curproxy->mode == PR_MODE_HTTP) {
|
||||
@ -3637,11 +3646,12 @@ out_uri_auth_compat:
|
||||
}
|
||||
|
||||
if (curproxy->cap & PR_CAP_BE) {
|
||||
if (curproxy->tcp_req.inspect_delay ||
|
||||
!LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
|
||||
if (!LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules) ||
|
||||
(curproxy->defpx && !LIST_ISEMPTY(&curproxy->defpx->tcp_req.inspect_rules)))
|
||||
curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
|
||||
|
||||
if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
|
||||
if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules) ||
|
||||
(curproxy->defpx && !LIST_ISEMPTY(&curproxy->defpx->tcp_rep.inspect_rules)))
|
||||
curproxy->be_rsp_ana |= AN_RES_INSPECT;
|
||||
|
||||
if (curproxy->mode == PR_MODE_HTTP) {
|
||||
|
@ -1576,6 +1576,8 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
|
||||
curproxy->except_xff_net = defproxy->except_xff_net;
|
||||
curproxy->except_xot_net = defproxy->except_xot_net;
|
||||
curproxy->retry_type = defproxy->retry_type;
|
||||
curproxy->tcp_req.inspect_delay = defproxy->tcp_req.inspect_delay;
|
||||
curproxy->tcp_rep.inspect_delay = defproxy->tcp_rep.inspect_delay;
|
||||
|
||||
if (defproxy->fwdfor_hdr_len) {
|
||||
curproxy->fwdfor_hdr_len = defproxy->fwdfor_hdr_len;
|
||||
|
@ -574,8 +574,8 @@ static int tcp_parse_response_rule(char **args, int arg, int section_type,
|
||||
unsigned int where,
|
||||
const char *file, int line)
|
||||
{
|
||||
if (curpx == defpx || !(curpx->cap & PR_CAP_BE)) {
|
||||
memprintf(err, "%s %s is only allowed in 'backend' sections",
|
||||
if ((curpx == defpx && strlen(defpx->id) == 0) || !(curpx->cap & PR_CAP_BE)) {
|
||||
memprintf(err, "%s %s is only allowed in 'backend' sections or 'defaults' section with a name",
|
||||
args[0], args[1]);
|
||||
return -1;
|
||||
}
|
||||
@ -742,9 +742,9 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type,
|
||||
struct act_rule *rule, char **err,
|
||||
unsigned int where, const char *file, int line)
|
||||
{
|
||||
if (curpx == defpx) {
|
||||
memprintf(err, "%s %s is not allowed in 'defaults' sections",
|
||||
args[0], args[1]);
|
||||
if (curpx == defpx && strlen(defpx->id) == 0) {
|
||||
memprintf(err, "%s %s is not allowed in anonymous 'defaults' sections",
|
||||
args[0], args[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1031,8 +1031,8 @@ static int tcp_parse_tcp_rep(char **args, int section_type, struct proxy *curpx,
|
||||
}
|
||||
|
||||
if (strcmp(args[1], "inspect-delay") == 0) {
|
||||
if (curpx == defpx || !(curpx->cap & PR_CAP_BE)) {
|
||||
memprintf(err, "%s %s is only allowed in 'backend' sections",
|
||||
if ((curpx == defpx && strlen(defpx->id) == 0) || !(curpx->cap & PR_CAP_BE)) {
|
||||
memprintf(err, "%s %s is only allowed in 'backend' sections or 'defaults' section with a name",
|
||||
args[0], args[1]);
|
||||
return -1;
|
||||
}
|
||||
@ -1148,9 +1148,9 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
||||
}
|
||||
|
||||
if (strcmp(args[1], "inspect-delay") == 0) {
|
||||
if (curpx == defpx) {
|
||||
memprintf(err, "%s %s is not allowed in 'defaults' sections",
|
||||
args[0], args[1]);
|
||||
if (curpx == defpx && strlen(defpx->id) == 0) {
|
||||
memprintf(err, "%s %s is not allowed in anonymous 'defaults' sections",
|
||||
args[0], args[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user