Re: Extending Proxy Protocol
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
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
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
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