BUG/MINOR: tcpcheck: Set socks4 and send-proxy flags before the connect call

Since the health-check refactoring in the 2.2, the checks through a socks4 proxy
are broken. To fix this bug, CO_FL_SOCKS4 flag must be set on the connection
before calling the connect() callback function because this flags is checked to
use the right destination address. The same is done for the CO_FL_SEND_PROXY
flag for a consistency purpose.

A reg-test has been added to test the "check-via-socks4" directive.

This patch must be backported to 2.2.
This commit is contained in:
Christopher Faulet 2020-10-02 13:41:55 +02:00
parent 2079a4ad36
commit f7177271f3
2 changed files with 81 additions and 17 deletions

View File

@ -0,0 +1,63 @@
varnishtest "Health-checks: basic HTTP health-check though a socks4 proxy"
#REQUIRE_VERSION=2.0
#REGTEST_TYPE=slow
feature ignore_unknown_macro
# This scripts tests a simple HTTP health-checks though a socks4 proxy.
server s1 {
} -start
server socks {
## get socks4 request
recv 16
## send socks4 response :
## constant(1): 0x00
## statut(1) : 0x5a (success)
## padding(6) : ignored
sendhex "005A000000000000"
rxreq
expect req.method == OPTIONS
expect req.url == /
expect req.proto == HTTP/1.0
txresp
} -start
syslog S1 -level notice {
recv
expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Proxy be1 started."
recv
expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+code: 200.+check duration: [[:digit:]]+ms, status: 1/1 UP."
} -start
haproxy h1 -conf {
defaults
mode tcp
timeout client 1s
timeout server 1s
timeout connect 100ms
backend be1
log ${S1_addr}:${S1_port} daemon
option log-health-checks
option httpchk
server srv ${s1_addr}:${s1_port} socks4 ${h1_socks_addr}:${h1_socks_port} check-via-socks4 check inter 1s rise 1 fall 1
listen socks
bind "fd@${socks}"
tcp-request inspect-delay 500ms
## Accept socks4 request on 16 bytes :
## version(1) : 0x04
## command(1) : 0x01
## port(2) : ${s1_port}
## addr(4) : ${s1_addr}
## user-id : "HAProxy\0"
tcp-request content accept if { req.len eq 16 } { req.payload(0,1) -m bin "04" } { req.payload(1,1) -m bin "01" } { req.payload(2,2),hex,hex2i eq ${s1_port} } { req.payload(4,4),hex,hex2i -m ip ${s1_addr} } { req.payload(8,8) -m bin "484150726F787900" }
tcp-request content reject
server srv ${socks_addr}:${socks_port}
} -start
syslog S1 -wait

View File

@ -1073,6 +1073,24 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
conn_prepare(conn, proto, xprt);
cs_attach(cs, check, &check_conn_cb);
if ((connect->options & TCPCHK_OPT_SOCKS4) && s && (s->flags & SRV_F_SOCKS4_PROXY)) {
conn->send_proxy_ofs = 1;
conn->flags |= CO_FL_SOCKS4;
}
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && s && s->check.via_socks4 && (s->flags & SRV_F_SOCKS4_PROXY)) {
conn->send_proxy_ofs = 1;
conn->flags |= CO_FL_SOCKS4;
}
if (connect->options & TCPCHK_OPT_SEND_PROXY) {
conn->send_proxy_ofs = 1;
conn->flags |= CO_FL_SEND_PROXY;
}
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && s && s->check.send_proxy && !(check->state & CHK_ST_AGENT)) {
conn->send_proxy_ofs = 1;
conn->flags |= CO_FL_SEND_PROXY;
}
status = SF_ERR_INTERNAL;
next = get_next_tcpcheck_rule(check->tcpcheck_rules, rule);
if (proto && proto->connect) {
@ -1102,23 +1120,6 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && s && s->check.alpn_str)
ssl_sock_set_alpn(conn, (unsigned char *)s->check.alpn_str, s->check.alpn_len);
#endif
if ((connect->options & TCPCHK_OPT_SOCKS4) && s && (s->flags & SRV_F_SOCKS4_PROXY)) {
conn->send_proxy_ofs = 1;
conn->flags |= CO_FL_SOCKS4;
}
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && s && s->check.via_socks4 && (s->flags & SRV_F_SOCKS4_PROXY)) {
conn->send_proxy_ofs = 1;
conn->flags |= CO_FL_SOCKS4;
}
if (connect->options & TCPCHK_OPT_SEND_PROXY) {
conn->send_proxy_ofs = 1;
conn->flags |= CO_FL_SEND_PROXY;
}
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && s && s->check.send_proxy && !(check->state & CHK_ST_AGENT)) {
conn->send_proxy_ofs = 1;
conn->flags |= CO_FL_SEND_PROXY;
}
if (conn_ctrl_ready(conn) && (connect->options & TCPCHK_OPT_LINGER)) {
/* Some servers don't like reset on close */