MEDIUM: tcp: add "tcp-request connection expect-proxy layer4"

This configures the client-facing connection to receive a PROXY protocol
header before any byte is read from the socket. This is equivalent to
having the "accept-proxy" keyword on the "bind" line, except that using
the TCP rule allows the PROXY protocol to be accepted only for certain
IP address ranges using an ACL. This is convenient when multiple layers
of load balancers are passed through by traffic coming from public
hosts.
This commit is contained in:
Willy Tarreau 2013-06-11 20:40:55 +02:00
parent 51347ed94c
commit 4f0d919bd4
3 changed files with 42 additions and 5 deletions

View File

@ -6418,7 +6418,7 @@ tcp-request connection <action> [{if | unless} <condition>]
Arguments :
<action> defines the action to perform if the condition applies. Valid
actions include : "accept", "reject", "track-sc1", "track-sc2",
and "track-sc3". See below for more details.
"track-sc3", and "expect-proxy". See below for more details.
<condition> is a standard layer4-only ACL-based condition (see section 7).
@ -6456,6 +6456,15 @@ tcp-request connection <action> [{if | unless} <condition>]
logging is absolutely desired, then "tcp-request content" rules should
be used instead.
- expect-proxy layer4 :
configures the client-facing connection to receive a PROXY protocol
header before any byte is read from the socket. This is equivalent to
having the "accept-proxy" keyword on the "bind" line, except that using
the TCP rule allows the PROXY protocol to be accepted only for certain
IP address ranges using an ACL. This is convenient when multiple layers
of load balancers are passed through by traffic coming from public
hosts.
- { track-sc1 | track-sc2 | track-sc3 } <key> [table <table>] :
enables tracking of sticky counters from current connection. These
rules do not stop evaluation and do not change default action. Two sets
@ -6516,6 +6525,10 @@ tcp-request connection <action> [{if | unless} <condition>]
tcp-request connection track-sc1 src
tcp-request connection reject if { sc1_conn_rate gt 10 }
Example: enable the PROXY protocol for traffic coming from all known proxies.
tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
See section 7 about ACL usage.
See also : "tcp-request content", "stick-table"
@ -7267,7 +7280,8 @@ accept-proxy
address will still be used. This keyword combined with support from external
components can be used as an efficient and reliable alternative to the
X-Forwarded-For mechanism which is not always reliable and not even always
usable.
usable. See also "tcp-request connection expect-proxy" for a finer-grained
setting of which client is allowed to use the protocol.
alpn <protocols>
This enables the TLS ALPN extension and advertises the specified protocol

View File

@ -32,9 +32,10 @@
enum {
TCP_ACT_ACCEPT = 1,
TCP_ACT_REJECT = 2,
TCP_ACT_TRK_SC1 = 3, /* TCP request tracking : must be contiguous */
TCP_ACT_TRK_SC2 = 4,
TCP_ACT_TRK_SC3 = 5,
TCP_ACT_EXPECT_PX = 3,
TCP_ACT_TRK_SC1 = 4, /* TCP request tracking : must be contiguous */
TCP_ACT_TRK_SC2 = 5,
TCP_ACT_TRK_SC3 = 6,
};
struct tcp_rule {

View File

@ -1105,6 +1105,10 @@ int tcp_exec_req_rules(struct session *s)
if (key && (ts = stktable_get_entry(t, key)))
session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
}
else if (rule->action == TCP_ACT_EXPECT_PX) {
s->si[0].conn->flags |= CO_FL_ACCEPT_PROXY;
conn_sock_want_recv(s->si[0].conn);
}
else {
/* otherwise it's an accept */
break;
@ -1222,6 +1226,24 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type,
rule->act_prm.trk_ctr.expr = expr;
rule->action = TCP_ACT_TRK_SC1 + args[kw][8] - '1';
}
else if (strcmp(args[arg], "expect-proxy") == 0) {
if (strcmp(args[arg+1], "layer4") != 0) {
memprintf(err,
"'%s %s %s' only supports 'layer4' in %s '%s' (got '%s')",
args[0], args[1], args[arg], proxy_type_str(curpx), curpx->id, args[arg+1]);
return -1;
}
if (!(where & SMP_VAL_FE_CON_ACC)) {
memprintf(err,
"'%s %s' is not allowed in '%s %s' rules in %s '%s'",
args[arg], args[arg+1], args[0], args[1], proxy_type_str(curpx), curpx->id);
return -1;
}
arg += 2;
rule->action = TCP_ACT_EXPECT_PX;
}
else {
memprintf(err,
"'%s %s' expects 'accept', 'reject', 'track-sc1', 'track-sc2' "