mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 06:11:32 +02:00
[MINOR] http-request: allow/deny/auth support for frontend/backend/listen
Use the generic auth framework to control access to frontends/backends/listens
This commit is contained in:
parent
d7528e5a60
commit
59bb218b86
@ -170,6 +170,7 @@ struct proxy {
|
|||||||
char *name; /* default backend name during config parse */
|
char *name; /* default backend name during config parse */
|
||||||
} defbe;
|
} defbe;
|
||||||
struct list acl; /* ACL declared on this proxy */
|
struct list acl; /* ACL declared on this proxy */
|
||||||
|
struct list req_acl; /* request ACL: allow/deny/http-auth */
|
||||||
struct list block_cond; /* early blocking conditions (chained) */
|
struct list block_cond; /* early blocking conditions (chained) */
|
||||||
struct list redirect_rules; /* content redirecting rules (chained) */
|
struct list redirect_rules; /* content redirecting rules (chained) */
|
||||||
struct list switching_rules; /* content switching rules (chained) */
|
struct list switching_rules; /* content switching rules (chained) */
|
||||||
|
@ -882,6 +882,7 @@ static void init_new_proxy(struct proxy *p)
|
|||||||
memset(p, 0, sizeof(struct proxy));
|
memset(p, 0, sizeof(struct proxy));
|
||||||
LIST_INIT(&p->pendconns);
|
LIST_INIT(&p->pendconns);
|
||||||
LIST_INIT(&p->acl);
|
LIST_INIT(&p->acl);
|
||||||
|
LIST_INIT(&p->req_acl);
|
||||||
LIST_INIT(&p->block_cond);
|
LIST_INIT(&p->block_cond);
|
||||||
LIST_INIT(&p->redirect_rules);
|
LIST_INIT(&p->redirect_rules);
|
||||||
LIST_INIT(&p->mon_fail_cond);
|
LIST_INIT(&p->mon_fail_cond);
|
||||||
@ -1927,6 +1928,31 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
}
|
}
|
||||||
curproxy->conn_retries = atol(args[1]);
|
curproxy->conn_retries = atol(args[1]);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
|
||||||
|
struct req_acl_rule *req_acl;
|
||||||
|
|
||||||
|
if (curproxy == &defproxy) {
|
||||||
|
Alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!LIST_ISEMPTY(&curproxy->req_acl) && !LIST_PREV(&curproxy->req_acl, struct req_acl_rule *, list)->cond) {
|
||||||
|
Warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
|
||||||
|
file, linenum, args[0]);
|
||||||
|
err_code |= ERR_WARN;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_acl = parse_auth_cond((const char **)args + 1, file, linenum, &curproxy->acl, &curproxy->acl_requires);
|
||||||
|
|
||||||
|
if (!req_acl) {
|
||||||
|
err_code |= ERR_ALERT | ERR_ABORT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_ADDQ(&curproxy->req_acl, &req_acl->list);
|
||||||
|
}
|
||||||
else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
|
else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
|
||||||
if (curproxy == &defproxy) {
|
if (curproxy == &defproxy) {
|
||||||
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||||
|
@ -859,6 +859,8 @@ void deinit(void)
|
|||||||
l = l_next;
|
l = l_next;
|
||||||
}/* end while(l) */
|
}/* end while(l) */
|
||||||
|
|
||||||
|
req_acl_free(&p->req_acl);
|
||||||
|
|
||||||
pool_destroy2(p->req_cap_pool);
|
pool_destroy2(p->req_cap_pool);
|
||||||
pool_destroy2(p->rsp_cap_pool);
|
pool_destroy2(p->rsp_cap_pool);
|
||||||
pool_destroy2(p->hdr_idx_pool);
|
pool_destroy2(p->hdr_idx_pool);
|
||||||
|
@ -1351,7 +1351,6 @@ const char *http_parse_stsline(struct http_msg *msg, const char *msg_buf,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function parses a request line between <ptr> and <end>, starting with
|
* This function parses a request line between <ptr> and <end>, starting with
|
||||||
* parser state <state>. Only states HTTP_MSG_RQMETH, HTTP_MSG_RQMETH_SP,
|
* parser state <state>. Only states HTTP_MSG_RQMETH, HTTP_MSG_RQMETH_SP,
|
||||||
@ -2723,6 +2722,7 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
|
|||||||
struct http_txn *txn = &s->txn;
|
struct http_txn *txn = &s->txn;
|
||||||
struct http_msg *msg = &txn->req;
|
struct http_msg *msg = &txn->req;
|
||||||
struct acl_cond *cond;
|
struct acl_cond *cond;
|
||||||
|
struct req_acl_rule *req_acl, *req_acl_final = NULL;
|
||||||
struct redirect_rule *rule;
|
struct redirect_rule *rule;
|
||||||
struct cond_wordlist *wl;
|
struct cond_wordlist *wl;
|
||||||
int del_ka, del_cl;
|
int del_ka, del_cl;
|
||||||
@ -2762,6 +2762,29 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(req_acl, &px->req_acl, list) {
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
if (req_acl->action >= PR_REQ_ACL_ACT_MAX)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check condition, but only if attached */
|
||||||
|
if (req_acl->cond)
|
||||||
|
ret = acl_exec_cond(req_acl->cond, px, s, txn, ACL_DIR_REQ);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
req_acl_final = req_acl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req_acl_final && req_acl_final->action == PR_REQ_ACL_ACT_DENY) {
|
||||||
|
txn->status = 403;
|
||||||
|
s->logs.tv_request = now;
|
||||||
|
stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_403));
|
||||||
|
goto return_prx_cond;
|
||||||
|
}
|
||||||
|
|
||||||
/* try headers filters */
|
/* try headers filters */
|
||||||
if (px->req_exp != NULL) {
|
if (px->req_exp != NULL) {
|
||||||
if (apply_filters_to_request(s, req, px) < 0)
|
if (apply_filters_to_request(s, req, px) < 0)
|
||||||
@ -2864,6 +2887,16 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
|
|||||||
goto return_bad_req;
|
goto return_bad_req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req_acl_final && req_acl_final->action == PR_REQ_ACL_ACT_HTTP_AUTH) {
|
||||||
|
struct chunk msg;
|
||||||
|
|
||||||
|
sprintf(trash, HTTP_401_fmt, req_acl->http_auth.realm?req_acl->http_auth.realm:px->id);
|
||||||
|
chunk_initlen(&msg, trash, sizeof(trash), strlen(trash));
|
||||||
|
txn->status = 401;
|
||||||
|
stream_int_retnclose(req->prod, &msg);
|
||||||
|
goto return_prx_cond;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if stats URI was requested, and if an auth is needed */
|
/* check if stats URI was requested, and if an auth is needed */
|
||||||
if (px->uri_auth != NULL &&
|
if (px->uri_auth != NULL &&
|
||||||
(txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)) {
|
(txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user