[PATCH] Core: support for reading PROXY protocol v2 TLVs
Roman Arutyunyan
arut at nginx.com
Mon Sep 5 13:23:18 UTC 2022
Hi,
On Mon, Sep 05, 2022 at 03:52:49AM +0300, Maxim Dounin wrote:
> Hello!
>
> On Wed, Aug 31, 2022 at 07:52:15PM +0400, Roman Arutyunyan wrote:
>
> > # HG changeset patch
> > # User Roman Arutyunyan <arut at nginx.com>
> > # Date 1661436099 -14400
> > # Thu Aug 25 18:01:39 2022 +0400
> > # Node ID 4b856f1dff939e4eb9c131e17af061cf2c38cfac
> > # Parent 069a4813e8d6d7ec662d282a10f5f7062ebd817f
> > Core: support for reading PROXY protocol v2 TLVs.
>
> First of all, could you please provide details on the use case?
> I've seen requests for writing proxy protocol TLVs to upstream
> servers (see ticket #1639), but not yet seen any meaningful
> reading requests.
The known cases are these:
- https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#proxy-protocol
- https://docs.microsoft.com/en-us/azure/private-link/private-link-service-overview#getting-connection-information-using-tcp-proxy-v2
- https://cloud.google.com/vpc/docs/configure-private-service-connect-producer#proxy-protocol
The data may need further parsing, but it can be done in njs or perl.
> > The TLV values are available in HTTP and Stream variables
> > $proxy_protocol_tlv_0xN, where N is a hexadecimal TLV type number with no
> > leading zeroes.
>
> I can't say I like the "hexadecimal TLV type number with no
> leading zeroes" approach, especially given that the specification
> uses leading zeroes in TLV types. With leading zeros might be
> better, to match specification.
>
> Also, it might worth the effort to actually add names for known
> types instead or in addition to numbers.
This is indeed a good idea and we have such plans as a further extenion of this
work. One of the problems is however that the abovementioned TLV variables
are specified in internal documents of AWS/Azure/GCP which are not standards.
They can be changed anytime, while we have to maintain those variables in
nginx. Also, raw variables give more flexibility in supporting less known TLVs.
> Another question is PP2_TYPE_SSL, which is itself a complex
> structure and a list of multiple subtypes.
This is an obvious one. However we had exactly zero requests for this.
> Provided
> Given the above, not sure if the approach with early parsing and
> header-like list as in the patch is the good idea. Just
> preserving TLVs as is and parsing them all during variable
> evaluation might be easier and more efficient.
In this case, if we have two variables, say $proxy_protocol_tlv_ssl_{sni, alpn},
we'll parse the entire TLV block twice - once per variable evaluation.
> Also, the idea of merging TLV values with identical types looks
> wrong to me, especially given that many TLSs are binary.
> Specification does not seem to define the behaviour here,
> unfortunately. As far as I understand, HAProxy itself still
> doesn't implement PPv2 parsing, so there is not reference
> implementation either. On the other hand, it should be easy
> enough to check all TLVs for duplicate by using a 256-bit bitmask
> and reject connections if there are any duplicates.
This can be added, thanks.
> > diff --git a/src/core/ngx_proxy_protocol.c b/src/core/ngx_proxy_protocol.c
> > --- a/src/core/ngx_proxy_protocol.c
> > +++ b/src/core/ngx_proxy_protocol.c
> > @@ -40,6 +40,12 @@ typedef struct {
> > } ngx_proxy_protocol_inet6_addrs_t;
> >
> >
> > +typedef struct {
> > + u_char type;
> > + u_char len[2];
> > +} ngx_proxy_protocol_tlv_t;
> > +
> > +
> > static u_char *ngx_proxy_protocol_read_addr(ngx_connection_t *c, u_char *p,
> > u_char *last, ngx_str_t *addr);
> > static u_char *ngx_proxy_protocol_read_port(u_char *p, u_char *last,
> > @@ -273,8 +279,11 @@ ngx_proxy_protocol_v2_read(ngx_connectio
> > size_t len;
> > socklen_t socklen;
> > ngx_uint_t version, command, family, transport;
> > + ngx_list_t *pp_tlv;
>
> tlvs?
>
> See above though, it probably doesn't make sense to parse TLVs
> here.
>
> > ngx_sockaddr_t src_sockaddr, dst_sockaddr;
> > + ngx_table_elt_t *t;
>
> Just in case, most ngx_table_elt_t variables are named "h", as in
> "header".
>
> [...]
>
> --
> Maxim Dounin
> http://mdounin.ru/
> _______________________________________________
> nginx-devel mailing list -- nginx-devel at nginx.org
> To unsubscribe send an email to nginx-devel-leave at nginx.org
More information about the nginx-devel
mailing list