On Thu, May 26, 2016 at 10:20:36AM -0400, Erik Seres wrote: > Hi Willy, > > Attached is my updated patch per your styling update request.
Thanks Erik. I'm now CCing Dave and Amos, both of whom worked on this 18 months ago. Amos requested the use of value 0x01 for ALPN and 0x02 for SNI by then, though I don't know if in the end he implemlented anything. Same for Dave who wanted to implement them in the protocol. Guys, for a bit of context, Erik proposes a patch to implement SNI on PP2. If nobody implemented anything yet, maybe it's best to continue with 0x23 and so on for now. Otherwise if anything was already implemented, we'll stay on what was already done. Please however, do provide patches at least for the doc if anything was done, as it's quite hard to have to dig through e-mail archives to find the details :-/ Thus please just check between all of you and tell me if I apply the attached patch or if we need to change the ID. We absolutely need to work on this to define how to extend the protocol in the future and to register new IDs... Thanks! Willy
>From ee5b141df994c8fe42f8f2d85aa20a87dc10ca19 Mon Sep 17 00:00:00 2001 From: Erik Seres <erikse...@gmail.com> Date: Thu, 12 May 2016 11:05:14 +0200 Subject: [PATCH] [RFC]/MINOR: connection: Add server name to proxy protocol v2 header. If the client provides the server name it intends to connect to, per RFC3546, Section 3.1. Server Name Indication, this patch will pass the server name onto the backend server as part of the proxy protocol v2 header. The patch defines the new SSL subtype PP2_TYPE_SSL_SNI and the corresponding flag PP2_CLIENT_SNI to accomplish this in an additional TLV. --- doc/proxy-protocol.txt | 7 +++++++ include/proto/ssl_sock.h | 1 + include/types/connection.h | 2 ++ src/connection.c | 5 +++++ src/ssl_sock.c | 9 +++++++++ 5 files changed, 24 insertions(+) diff --git a/doc/proxy-protocol.txt b/doc/proxy-protocol.txt index 472dcb2..499a4e2 100644 --- a/doc/proxy-protocol.txt +++ b/doc/proxy-protocol.txt @@ -530,6 +530,7 @@ The following types have already been registered for the <type> field : #define PP2_TYPE_SSL 0x20 #define PP2_SUBTYPE_SSL_VERSION 0x21 #define PP2_SUBTYPE_SSL_CN 0x22 + #define PP2_SUBTYPE_SSL_SNI 0x23 #define PP2_TYPE_NETNS 0x30 @@ -552,6 +553,7 @@ indicating which element is present : #define PP2_CLIENT_SSL 0x01 #define PP2_CLIENT_CERT_CONN 0x02 #define PP2_CLIENT_CERT_SESS 0x04 + #define PP2_CLIENT_SNI 0x08 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 @@ -566,6 +568,11 @@ 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. +PP2_CLIENT_SNI flag indicates that the client provided a server name according +to the Server Name Indication TLS extension. When this field is present, the +string representation of the intended server name is appended at the end of the +field in the TLV format using the type PP2_SUBTYPE_SSL_SNI. + In all cases, the string representation (in UTF8) of the Common Name field (OID: 2.5.4.3) of the client certificate's DistinguishedName, is appended using the TLV format and the type PP2_SUBTYPE_SSL_CN. diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h index cb9a1e9..a5a05f0 100644 --- a/include/proto/ssl_sock.h +++ b/include/proto/ssl_sock.h @@ -53,6 +53,7 @@ void ssl_sock_free_ca(struct bind_conf *bind_conf); const char *ssl_sock_get_cipher_name(struct connection *conn); const char *ssl_sock_get_proto_version(struct connection *conn); char *ssl_sock_get_version(struct connection *conn); +char *ssl_sock_get_servername(struct connection *conn); void ssl_sock_set_servername(struct connection *conn, const char *hostname); int ssl_sock_get_cert_used_sess(struct connection *conn); int ssl_sock_get_cert_used_conn(struct connection *conn); diff --git a/include/types/connection.h b/include/types/connection.h index dfbff6a..3159085 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -335,6 +335,7 @@ struct proxy_hdr_v2 { #define PP2_TYPE_SSL 0x20 #define PP2_TYPE_SSL_VERSION 0x21 #define PP2_TYPE_SSL_CN 0x22 +#define PP2_TYPE_SSL_SNI 0x23 #define PP2_TYPE_NETNS 0x30 #define TLV_HEADER_SIZE 3 @@ -355,6 +356,7 @@ struct tlv_ssl { #define PP2_CLIENT_SSL 0x01 #define PP2_CLIENT_CERT_CONN 0x02 #define PP2_CLIENT_CERT_SESS 0x04 +#define PP2_CLIENT_SNI 0x08 #endif /* _TYPES_CONNECTION_H */ diff --git a/src/connection.c b/src/connection.c index 330f3ef..29c45d6 100644 --- a/src/connection.c +++ b/src/connection.c @@ -820,6 +820,11 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec ssl_tlv_len += make_tlv(&buf[ret+ssl_tlv_len], (buf_len - ret - ssl_tlv_len), PP2_TYPE_SSL_CN, cn_trash->len, cn_trash->str); } } + value = ssl_sock_get_servername(remote); + if (value) { + tlv->client |= PP2_CLIENT_SNI; + ssl_tlv_len += make_tlv(&buf[ret + ssl_tlv_len], (buf_len - ret-ssl_tlv_len), PP2_TYPE_SSL_SNI, strlen(value), value); + } } tlv->tlv.length_hi = (uint16_t)(ssl_tlv_len - sizeof(struct tlv)) >> 8; tlv->tlv.length_lo = (uint16_t)(ssl_tlv_len - sizeof(struct tlv)) & 0x00ff; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 0d35c29..41f8f18 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -3973,6 +3973,15 @@ char *ssl_sock_get_version(struct connection *conn) return (char *)SSL_get_version(conn->xprt_ctx); } +/* returns server name if client passed TLS SNI extension, NULL if not */ +char *ssl_sock_get_servername(struct connection *conn) +{ + if (!ssl_sock_is_ssl(conn)) + return NULL; + + return (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name); +} + void ssl_sock_set_servername(struct connection *conn, const char *hostname) { #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -- 2.7.4 (Apple Git-66)