Re: Extending Proxy Protocol

2014-01-30 Thread Willy Tarreau
Hi David,

On Wed, Jan 29, 2014 at 10:53:22PM -0500, David S wrote:
 I want to use HAProxy to terminate my incoming SSL connections and forward
 the messages to my server application.   My challenge is that my
 application needs information from the client certificates.
 
 The Proxy Protocol is one way that connection information can be forwarded
 from HAProxy to the receiver.  I'm interested in extending the Proxy
 Protocol to include client certificate information.
 
 The Proxy Protocol documentation mentions that this has been considered
 before.

yes indeed.

 Do you have any advice for someone who might start developing a patch to
 extend Proxy Protocol?

The difficulty lies more in trying to achieve something compatible with
existing implementations than writing the code.

One of the problems is to consider other information some people might
want to pass. I'm thinking about the interface name, SSL/TLS version,
ciphers, SSL session ID, SNI, local cert, ... We don't need to implement
all this. But we need to ensure that whatever we add will not prevent
these from being added later.

One possibility would be to add new keywords. But that makes something
quite complex to parse for receivers, and it's already very problematic
not to know how many bytes to read. For example, in Postfix, postscreen
uses recv(MSG_PEEK) and cannot poll, so it would like to know easily how
many bytes to read in each block and if possible not to have to parse
one char at a time.

Another option could be to implement it only in the V2 of the protocol
which is binary. The length is variable and depends on the types present
in the header. So the parsing is very fast. I think one solution would
be to implement a new command which would represent the encapsulated
information, and that LOCAL (\x00) or PROXY (\x01) are alwas final.
For example, let's imagine we have SSLCRT=\x02 followed by a length
and a cert, then by a command again. By doing so we can easily implement
up to 254 extra commands, thus as many extra types. One point of particular
care is that the length of each field is encoded on 8 bits. If that's not
always enough, maybe it would be simple enough to decide to cut large data
into chunks. Another possibility would be to use a variable length encoding,
but this is not always properly implemented, and is sometimes hard to
implement for the sender. For example, if we consider that 16kB per data
type, we can encode the length using values 0..191 as 1-byte, and values
192..255 as 14 bits (6 bits followed by an extra byte). But as it stands
now, I really think that chunking large data into 255-or-less chunks is
much easier for everyone, including the receiver which will need less
buffers.

 Are there alternatives that I should consider?

There's always an alternative, which is to decide whether or not it would
make sense to migrate the application to HTTP, where all of this becomes
immediately available for free. Maybe at the beginning it's not planned
to do so, but in the long term, using HTTP is useful because it adds lots
of new possibilities (proxies, compression, cookies, ...).
 
Regards,
Willy




Re: Extending Proxy Protocol

2014-01-30 Thread Neil
On 30 Jan 2014 08:12, Willy Tarreau w...@1wt.eu wrote:

 Hi David,

 On Wed, Jan 29, 2014 at 10:53:22PM -0500, David S wrote:
  I want to use HAProxy to terminate my incoming SSL connections and
forward
  the messages to my server application.   My challenge is that my
  application needs information from the client certificates.
 
  The Proxy Protocol is one way that connection information can be
forwarded
  from HAProxy to the receiver.  I'm interested in extending the Proxy
  Protocol to include client certificate information.
 
  The Proxy Protocol documentation mentions that this has been considered
  before.

 yes indeed.

  Do you have any advice for someone who might start developing a patch to
  extend Proxy Protocol?

 The difficulty lies more in trying to achieve something compatible with
 existing implementations than writing the code.

 One of the problems is to consider other information some people might
 want to pass. I'm thinking about the interface name, SSL/TLS version,
 ciphers, SSL session ID, SNI, local cert, ... We don't need to implement
 all this. But we need to ensure that whatever we add will not prevent
 these from being added later.

 One possibility would be to add new keywords. But that makes something
 quite complex to parse for receivers, and it's already very problematic
 not to know how many bytes to read. For example, in Postfix, postscreen
 uses recv(MSG_PEEK) and cannot poll, so it would like to know easily how
 many bytes to read in each block and if possible not to have to parse
 one char at a time.

 Another option could be to implement it only in the V2 of the protocol
 which is binary. The length is variable and depends on the types present
 in the header. So the parsing is very fast. I think one solution would
 be to implement a new command which would represent the encapsulated
 information, and that LOCAL (\x00) or PROXY (\x01) are alwas final.
 For example, let's imagine we have SSLCRT=\x02 followed by a length
 and a cert, then by a command again. By doing so we can easily implement
 up to 254 extra commands, thus as many extra types. One point of
particular
 care is that the length of each field is encoded on 8 bits. If that's not
 always enough, maybe it would be simple enough to decide to cut large data
 into chunks. Another possibility would be to use a variable length
encoding,
 but this is not always properly implemented, and is sometimes hard to
 implement for the sender. For example, if we consider that 16kB per data
 type, we can encode the length using values 0..191 as 1-byte, and values
 192..255 as 14 bits (6 bits followed by an extra byte). But as it stands
 now, I really think that chunking large data into 255-or-less chunks is
 much easier for everyone, including the receiver which will need less
 buffers.

  Are there alternatives that I should consider?

 There's always an alternative, which is to decide whether or not it would
 make sense to migrate the application to HTTP, where all of this becomes
 immediately available for free. Maybe at the beginning it's not planned
 to do so, but in the long term, using HTTP is useful because it adds lots
 of new possibilities (proxies, compression, cookies, ...).

 Regards,
 Willy


Another http proxy 'pound' passes on this information by added http headers
similar to x-forwarded-for.

It would,imho, be great to be able to take arbitary headers from client and
mangle and pass them on to backend servers or use in acls or put the in
state tables

Similarly passing from backend to client after mangling would be useful


Re: Extending Proxy Protocol

2014-01-30 Thread Willy Tarreau
On Thu, Jan 30, 2014 at 09:19:34AM +, Neil wrote:
 Another http proxy 'pound' passes on this information by added http headers
 similar to x-forwarded-for.
 
 It would,imho, be great to be able to take arbitary headers from client and
 mangle and pass them on to backend servers or use in acls or put the in
 state tables

But this is already supported. I understand that David's application does not
use HTTP if he wants to extend the PROXY protocol. PROXY is mostly useless for
HTTP, since HTTP is much more flexible.

Willy




Re: Extending Proxy Protocol

2014-01-30 Thread Baptiste
Already the case:
http://blog.exceliance.fr/2013/06/13/ssl-client-certificate-information-in-http-headers-and-logs/

Baptiste

On Thu, Jan 30, 2014 at 10:19 AM, Neil n...@iamafreeman.com wrote:

 On 30 Jan 2014 08:12, Willy Tarreau w...@1wt.eu wrote:

 Hi David,

 On Wed, Jan 29, 2014 at 10:53:22PM -0500, David S wrote:
  I want to use HAProxy to terminate my incoming SSL connections and
  forward
  the messages to my server application.   My challenge is that my
  application needs information from the client certificates.
 
  The Proxy Protocol is one way that connection information can be
  forwarded
  from HAProxy to the receiver.  I'm interested in extending the Proxy
  Protocol to include client certificate information.
 
  The Proxy Protocol documentation mentions that this has been considered
  before.

 yes indeed.

  Do you have any advice for someone who might start developing a patch to
  extend Proxy Protocol?

 The difficulty lies more in trying to achieve something compatible with
 existing implementations than writing the code.

 One of the problems is to consider other information some people might
 want to pass. I'm thinking about the interface name, SSL/TLS version,
 ciphers, SSL session ID, SNI, local cert, ... We don't need to implement
 all this. But we need to ensure that whatever we add will not prevent
 these from being added later.

 One possibility would be to add new keywords. But that makes something
 quite complex to parse for receivers, and it's already very problematic
 not to know how many bytes to read. For example, in Postfix, postscreen
 uses recv(MSG_PEEK) and cannot poll, so it would like to know easily how
 many bytes to read in each block and if possible not to have to parse
 one char at a time.

 Another option could be to implement it only in the V2 of the protocol
 which is binary. The length is variable and depends on the types present
 in the header. So the parsing is very fast. I think one solution would
 be to implement a new command which would represent the encapsulated
 information, and that LOCAL (\x00) or PROXY (\x01) are alwas final.
 For example, let's imagine we have SSLCRT=\x02 followed by a length
 and a cert, then by a command again. By doing so we can easily implement
 up to 254 extra commands, thus as many extra types. One point of
 particular
 care is that the length of each field is encoded on 8 bits. If that's not
 always enough, maybe it would be simple enough to decide to cut large data
 into chunks. Another possibility would be to use a variable length
 encoding,
 but this is not always properly implemented, and is sometimes hard to
 implement for the sender. For example, if we consider that 16kB per data
 type, we can encode the length using values 0..191 as 1-byte, and values
 192..255 as 14 bits (6 bits followed by an extra byte). But as it stands
 now, I really think that chunking large data into 255-or-less chunks is
 much easier for everyone, including the receiver which will need less
 buffers.

  Are there alternatives that I should consider?

 There's always an alternative, which is to decide whether or not it would
 make sense to migrate the application to HTTP, where all of this becomes
 immediately available for free. Maybe at the beginning it's not planned
 to do so, but in the long term, using HTTP is useful because it adds lots
 of new possibilities (proxies, compression, cookies, ...).

 Regards,
 Willy


 Another http proxy 'pound' passes on this information by added http headers
 similar to x-forwarded-for.

 It would,imho, be great to be able to take arbitary headers from client and
 mangle and pass them on to backend servers or use in acls or put the in
 state tables

 Similarly passing from backend to client after mangling would be useful