Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PP2] Handle the Type-Length-Values #5

Open
Proximyst opened this issue Apr 2, 2021 · 0 comments · May be fixed by #9
Open

[PP2] Handle the Type-Length-Values #5

Proximyst opened this issue Apr 2, 2021 · 0 comments · May be fixed by #9
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@Proximyst
Copy link
Owner

Version 2 defines "Type-Length-Values" that should be possible to parse. Perhaps this is worth throwing behind a feature gate?

The applicable text from the protocol:

If the length specified in the PROXY protocol header indicates that additional
bytes are part of the header beyond the address information, a receiver may
choose to skip over and ignore those bytes, or attempt to interpret those
bytes.
The information in those bytes will be arranged in Type-Length-Value (TLV
vectors) in the following format. The first byte is the Type of the vector.
The second two bytes represent the length in bytes of the value (not included
the Type and Length bytes), and following the length field is the number of
bytes specified by the length.
struct pp2_tlv {
uint8_t type;
uint8_t length_hi;
uint8_t length_lo;
uint8_t value[0];
};
A receiver may choose to skip over and ignore the TLVs it is not interested in
or it does not understand. Senders can generate the TLVs only for
the information they choose to publish.
The following types have already been registered for the <type> field :
#define PP2_TYPE_ALPN 0x01
#define PP2_TYPE_AUTHORITY 0x02
#define PP2_TYPE_CRC32C 0x03
#define PP2_TYPE_NOOP 0x04
#define PP2_TYPE_UNIQUE_ID 0x05
#define PP2_TYPE_SSL 0x20
#define PP2_SUBTYPE_SSL_VERSION 0x21
#define PP2_SUBTYPE_SSL_CN 0x22
#define PP2_SUBTYPE_SSL_CIPHER 0x23
#define PP2_SUBTYPE_SSL_SIG_ALG 0x24
#define PP2_SUBTYPE_SSL_KEY_ALG 0x25
#define PP2_TYPE_NETNS 0x30
2.2.1 PP2_TYPE_ALPN
Application-Layer Protocol Negotiation (ALPN). It is a byte sequence defining
the upper layer protocol in use over the connection. The most common use case
will be to pass the exact copy of the ALPN extension of the Transport Layer
Security (TLS) protocol as defined by RFC7301 [9].
2.2.2 PP2_TYPE_AUTHORITY
Contains the host name value passed by the client, as an UTF8-encoded string.
In case of TLS being used on the client connection, this is the exact copy of
the "server_name" extension as defined by RFC3546 [10], section 3.1, often
referred to as "SNI". There are probably other situations where an authority
can be mentioned on a connection without TLS being involved at all.
2.2.3. PP2_TYPE_CRC32C
The value of the type PP2_TYPE_CRC32C is a 32-bit number storing the CRC32c
checksum of the PROXY protocol header.
When the checksum is supported by the sender after constructing the header
the sender MUST:
- initialize the checksum field to '0's.
- calculate the CRC32c checksum of the PROXY header as described in RFC4960,
Appendix B [8].
- put the resultant value into the checksum field, and leave the rest of
the bits unchanged.
If the checksum is provided as part of the PROXY header and the checksum
functionality is supported by the receiver, the receiver MUST:
- store the received CRC32c checksum value aside.
- replace the 32 bits of the checksum field in the received PROXY header with
all '0's and calculate a CRC32c checksum value of the whole PROXY header.
- verify that the calculated CRC32c checksum is the same as the received
CRC32c checksum. If it is not, the receiver MUST treat the TCP connection
providing the header as invalid.
The default procedure for handling an invalid TCP connection is to abort it.
2.2.4. PP2_TYPE_NOOP
The TLV of this type should be ignored when parsed. The value is zero or more
bytes. Can be used for data padding or alignment. Note that it can be used
to align only by 3 or more bytes because a TLV can not be smaller than that.
2.2.5. PP2_TYPE_UNIQUE_ID
The value of the type PP2_TYPE_UNIQUE_ID is an opaque byte sequence of up to
128 bytes generated by the upstream proxy that uniquely identifies the
connection.
The unique ID can be used to easily correlate connections across multiple
layers of proxies, without needing to look up IP addresses and port numbers.
2.2.6. The PP2_TYPE_SSL type and subtypes
For the type PP2_TYPE_SSL, the value is itself a defined like this :
struct pp2_tlv_ssl {
uint8_t client;
uint32_t verify;
struct pp2_tlv sub_tlv[0];
};
The <verify> field will be zero if the client presented a certificate
and it was successfully verified, and non-zero otherwise.
The <client> field is made of a bit field from the following values,
indicating which element is present :
#define PP2_CLIENT_SSL 0x01
#define PP2_CLIENT_CERT_CONN 0x02
#define PP2_CLIENT_CERT_SESS 0x04
Note, that each of these elements may lead to extra data being appended to
this TLV using a second level of TLV encapsulation. It is thus possible to
find multiple TLV values after this field. The total length of the pp2_tlv_ssl
TLV will reflect this.
The PP2_CLIENT_SSL flag indicates that the client connected over SSL/TLS. When
this field is present, the US-ASCII string representation of the TLS version is
appended at the end of the field in the TLV format using the type
PP2_SUBTYPE_SSL_VERSION.
PP2_CLIENT_CERT_CONN indicates that the client provided a certificate over the
current connection. PP2_CLIENT_CERT_SESS indicates that the client provided a
certificate at least once over the TLS session this connection belongs to.
The second level TLV PP2_SUBTYPE_SSL_CIPHER provides the US-ASCII string name
of the used cipher, for example "ECDHE-RSA-AES128-GCM-SHA256".
The second level TLV PP2_SUBTYPE_SSL_SIG_ALG provides the US-ASCII string name
of the algorithm used to sign the certificate presented by the frontend when
the incoming connection was made over an SSL/TLS transport layer, for example
"SHA256".
The second level TLV PP2_SUBTYPE_SSL_KEY_ALG provides the US-ASCII string name
of the algorithm used to generate the key of the certificate presented by the
frontend when the incoming connection was made over an SSL/TLS transport layer,
for example "RSA2048".
In all cases, the string representation (in UTF8) of the Common Name field
(OID: 2.5.4.3) of the client certificate's Distinguished Name, is appended
using the TLV format and the type PP2_SUBTYPE_SSL_CN. E.g. "example.com".
2.2.7. The PP2_TYPE_NETNS type
The type PP2_TYPE_NETNS defines the value as the US-ASCII string representation
of the namespace's name.
2.2.8. Reserved type ranges
The following range of 16 type values is reserved for application-specific
data and will be never used by the PROXY Protocol. If you need more values
consider extending the range with a type field in your TLVs.
#define PP2_TYPE_MIN_CUSTOM 0xE0
#define PP2_TYPE_MAX_CUSTOM 0xEF
This range of 8 values is reserved for temporary experimental use by
application developers and protocol designers. The values from the range will
never be used by the PROXY protocol and should not be used by production
functionality.
#define PP2_TYPE_MIN_EXPERIMENT 0xF0
#define PP2_TYPE_MAX_EXPERIMENT 0xF7
The following range of 8 values is reserved for future use, potentially to
extend the protocol with multibyte type values.
#define PP2_TYPE_MIN_FUTURE 0xF8
#define PP2_TYPE_MAX_FUTURE 0xFF

@Proximyst Proximyst added enhancement New feature or request help wanted Extra attention is needed labels Apr 2, 2021
@Proximyst Proximyst mentioned this issue Apr 2, 2021
@g2p g2p linked a pull request Sep 29, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant