Re: [PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV, from PROXYv2
This is with the fix for the misplaced #endif spotted by Emmanuel, thx again. Geoff -- ** * * UPLEX - Nils Goroll Systemoptimierung Scheffelstraße 32 22301 Hamburg Tel +49 40 2880 5731 Mob +49 176 636 90917 Fax +49 40 42949753 http://uplex.de signature.asc Description: OpenPGP digital signature
[PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV, from PROXYv2
Save the authority TLV in a PROXYv2 header from the client connection, if present, and make it available as fc_pp_authority. The fetch can be used, for example, to set the SNI for a backend TLS connection. --- doc/configuration.txt | 4 include/proto/connection.h | 7 +++ include/types/connection.h | 4 src/connection.c | 37 + 4 files changed, 52 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index 4e18f0f6e..4c820d266 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -14460,6 +14460,10 @@ fc_http_major : integer for HTTP/0.9 to HTTP/1.1 or 2 for HTTP/2. Note, this is based on the on-wire encoding and not on the version present in the request header. +fc_pp_authority : string + Returns the authority TLV sent by the client in the PROXY protocol header, + if any. + fc_rcvd_proxy : boolean Returns true if the client initiated the connection with a PROXY protocol header. diff --git a/include/proto/connection.h b/include/proto/connection.h index bbb9759ac..059d5d85a 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -35,6 +35,7 @@ extern struct pool_head *pool_head_connection; extern struct pool_head *pool_head_connstream; extern struct pool_head *pool_head_sockaddr; +extern struct pool_head *pool_head_authority; extern struct xprt_ops *registered_xprt[XPRT_ENTRIES]; extern struct mux_proto_list mux_proto_list; @@ -471,6 +472,7 @@ static inline void conn_init(struct connection *conn) conn->idle_time = 0; conn->src = NULL; conn->dst = NULL; + conn->proxy_authority = NULL; } /* sets as the connection's owner */ @@ -617,6 +619,11 @@ static inline void conn_free(struct connection *conn) sockaddr_free(>src); sockaddr_free(>dst); + if (conn->proxy_authority != NULL) { + pool_free(pool_head_authority, conn->proxy_authority); + conn->proxy_authority = NULL; + } + /* By convention we always place a NULL where the ctx points to if the * mux is null. It may have been used to store the connection as a * stream_interface's end point for example. diff --git a/include/types/connection.h b/include/types/connection.h index f8e4c07f9..f6a7d1b7e 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -461,7 +461,9 @@ struct connection { void (*destroy_cb)(struct connection *conn); /* callback to notify of imminent death of the connection */ struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */ struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */ + char *proxy_authority;/* Value of authority TLV received via PROXYv2 */ unsigned int idle_time; /* Time the connection was added to the idle list, or 0 if not in the idle list */ + uint8_t proxy_authority_len; /* Length of authority TLV received via PROXYv2 */ }; /* PROTO token registration */ @@ -578,6 +580,8 @@ struct tlv_ssl { #define PP2_CLIENT_CERT_CONN 0x02 #define PP2_CLIENT_CERT_SESS 0x04 +/* Max length of the authority TLV */ +#define PP2_AUTHORITY_MAX 255 /* * Linux seems to be able to send 253 fds per sendmsg(), not sure diff --git a/src/connection.c b/src/connection.c index 602fc79ec..7bdd6f0dd 100644 --- a/src/connection.c +++ b/src/connection.c @@ -32,6 +32,7 @@ DECLARE_POOL(pool_head_connection, "connection", sizeof(struct connection)); DECLARE_POOL(pool_head_connstream, "conn_stream", sizeof(struct conn_stream)); DECLARE_POOL(pool_head_sockaddr, "sockaddr",sizeof(struct sockaddr_storage)); +DECLARE_POOL(pool_head_authority, "authority", PP2_AUTHORITY_MAX); struct xprt_ops *registered_xprt[XPRT_ENTRIES] = { NULL, }; @@ -631,6 +632,16 @@ int conn_recv_proxy(struct connection *conn, int flag) break; } #endif + case PP2_TYPE_AUTHORITY: { + if (tlv_len > PP2_AUTHORITY_MAX) + goto bad_header; + conn->proxy_authority = pool_alloc(pool_head_authority); + if (conn->proxy_authority == NULL) + goto fail; + memcpy(conn->proxy_authority, (const char *)tlv_packet->value, tlv_len); + conn->proxy_authority_len = tlv_len; + break; + } default: break; } @@ -1415,6 +1426,31 @@ int smp_fetch_fc_rcvd_proxy(const struct arg *args, struct sample *smp, const ch
Re: [PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV from PROXYv2
On 8/27/19 18:15, Emmanuel Hocdet wrote: > >> @@ -630,6 +631,17 @@ int conn_recv_proxy(struct connection *conn, int flag) >> conn->proxy_netns = ns; >> break; >> } >> + >> +case PP2_TYPE_AUTHORITY: { > > Is inside #ifdef USE_NS Oh, now I see it. Will fix. Thx, Geoff -- ** * * UPLEX - Nils Goroll Systemoptimierung Scheffelstraße 32 22301 Hamburg Tel +49 40 2880 5731 Mob +49 176 636 90917 Fax +49 40 42949753 http://uplex.de signature.asc Description: OpenPGP digital signature
Re: [PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV from PROXYv2
Hi Geoff, For: > > @@ -630,6 +631,17 @@ int conn_recv_proxy(struct connection *conn, int flag) > conn->proxy_netns = ns; > break; > } > + > + case PP2_TYPE_AUTHORITY: { Is inside #ifdef USE_NS It work for me, with the #ifdef fix. Thanks Manu
Re: [RFC] setting the backend SNI from the client's authority TLV, when the target address was forwarded
> Le 22 août 2019 à 14:40, Willy Tarreau a écrit : > > On Thu, Aug 22, 2019 at 11:36:00AM +0200, Geoff Simmons wrote: > >> I suspect that there are other ways that the authority TLV can be useful >> for haproxy besides the specific Varnish case. Someone connecting via >> TLS, for example, might want to send the TLV to "override" the SNI for >> certain backends. > > It's definitely useful for other cases, which is why I'm interested in > seeing it addressed properly. Right now we do emit a few fields in the > PPv2 but we ignore them on receipt, which is a bit sad. For example, if > you use multi-process to chain two haproxy instances, one with TLS > offloading, passing to the next level using PPv2, you currently lose the > SNI information. With your change it would finally work. > Indeed, the receipt part of PPv2 has been postponed until needed. With authority received from PPv2 (Geoff patch), i see use cases (one is to test configuration like chaining tow haproxy :-) ) To generalize the usage of authority, i will see a get_authority func in xprt_ops. With a ssl connection: return the sni (aka ssl authority). With a tcp connection: return the ppv2 authority. So a « send-proxy-v2 proxy-v2-options authority » server line will work in both cases. To override the authority, is like « sni » for server line, we could used « authority ». « send-proxy-v2 authority hdr(Host) proxy-v2-options authority » For server line with ssl, i thought that « authority » could replace « sni » but we can have both: « ssl sni hdr(Host),lower send-proxy-v2 authority hdr(Host) proxy-v2-options authority » Note: in my test « sni hdr(Host),lower » work but « sni var(req.host) » doesn’t (with http-request content set-var(req.host) hdr(host),lower ) What do you think? Manu
[PATCH] MINOR: Add the fc_pp_authority fetch -- authority TLV from PROXYv2
Save the authority TLV sent in a PROXYv2 header from the client connection, if present, and make it available as fc_pp_authority. The fetch can be used, for example, to set the SNI for a backend TLS connection. --- doc/configuration.txt | 4 include/proto/connection.h | 7 +++ include/types/connection.h | 4 src/connection.c | 38 ++ 4 files changed, 53 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index 4e18f0f6e..4c820d266 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -14460,6 +14460,10 @@ fc_http_major : integer for HTTP/0.9 to HTTP/1.1 or 2 for HTTP/2. Note, this is based on the on-wire encoding and not on the version present in the request header. +fc_pp_authority : string + Returns the authority TLV sent by the client in the PROXY protocol header, + if any. + fc_rcvd_proxy : boolean Returns true if the client initiated the connection with a PROXY protocol header. diff --git a/include/proto/connection.h b/include/proto/connection.h index bbb9759ac..059d5d85a 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -35,6 +35,7 @@ extern struct pool_head *pool_head_connection; extern struct pool_head *pool_head_connstream; extern struct pool_head *pool_head_sockaddr; +extern struct pool_head *pool_head_authority; extern struct xprt_ops *registered_xprt[XPRT_ENTRIES]; extern struct mux_proto_list mux_proto_list; @@ -471,6 +472,7 @@ static inline void conn_init(struct connection *conn) conn->idle_time = 0; conn->src = NULL; conn->dst = NULL; + conn->proxy_authority = NULL; } /* sets as the connection's owner */ @@ -617,6 +619,11 @@ static inline void conn_free(struct connection *conn) sockaddr_free(>src); sockaddr_free(>dst); + if (conn->proxy_authority != NULL) { + pool_free(pool_head_authority, conn->proxy_authority); + conn->proxy_authority = NULL; + } + /* By convention we always place a NULL where the ctx points to if the * mux is null. It may have been used to store the connection as a * stream_interface's end point for example. diff --git a/include/types/connection.h b/include/types/connection.h index f8e4c07f9..f6a7d1b7e 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -461,7 +461,9 @@ struct connection { void (*destroy_cb)(struct connection *conn); /* callback to notify of imminent death of the connection */ struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */ struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */ + char *proxy_authority;/* Value of authority TLV received via PROXYv2 */ unsigned int idle_time; /* Time the connection was added to the idle list, or 0 if not in the idle list */ + uint8_t proxy_authority_len; /* Length of authority TLV received via PROXYv2 */ }; /* PROTO token registration */ @@ -578,6 +580,8 @@ struct tlv_ssl { #define PP2_CLIENT_CERT_CONN 0x02 #define PP2_CLIENT_CERT_SESS 0x04 +/* Max length of the authority TLV */ +#define PP2_AUTHORITY_MAX 255 /* * Linux seems to be able to send 253 fds per sendmsg(), not sure diff --git a/src/connection.c b/src/connection.c index 602fc79ec..a4f9fdbac 100644 --- a/src/connection.c +++ b/src/connection.c @@ -32,6 +32,7 @@ DECLARE_POOL(pool_head_connection, "connection", sizeof(struct connection)); DECLARE_POOL(pool_head_connstream, "conn_stream", sizeof(struct conn_stream)); DECLARE_POOL(pool_head_sockaddr, "sockaddr",sizeof(struct sockaddr_storage)); +DECLARE_POOL(pool_head_authority, "authority", PP2_AUTHORITY_MAX); struct xprt_ops *registered_xprt[XPRT_ENTRIES] = { NULL, }; @@ -630,6 +631,17 @@ int conn_recv_proxy(struct connection *conn, int flag) conn->proxy_netns = ns; break; } + + case PP2_TYPE_AUTHORITY: { + if (tlv_len > PP2_AUTHORITY_MAX) + goto bad_header; + conn->proxy_authority = pool_alloc(pool_head_authority); + if (conn->proxy_authority == NULL) + goto fail; + memcpy(conn->proxy_authority, (const char *)tlv_packet->value, tlv_len); + conn->proxy_authority_len = tlv_len; + break; + } #endif default: break; @@ -1415,6 +1427,31 @@ int smp_fetch_fc_rcvd_proxy(const struct