You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Roy T. Fielding" <fi...@gbiv.com> on 2011/03/29 23:04:48 UTC

blocking Upgrade

Does anyone with a working install want a quick project?

We need to block the Upgrade header field by default.  What this
will require is a new configuration command, like

   AllowUpgrade None | word ...

where word is any protocol name, like HTTP/2.0, waka, websocket, etc.
The config command must only be allowed in rsrc_conf.

We then need a check somewhere in the http filter for an incoming
request header field called "Upgrade".  If present and the config option
is set to None (or default), then remove the Upgrade field before it
is seen by the request handler (i.e., before it might be used by some
module or CGI script to send the server down a rat hole).
If the config option is set and not None, then set the Upgrade
header field-value to be the intersection of what was sent by the
client and what is allowed by the config.

Likewise, perform the same filtering on outbound responses.

In other words, only allow a handler to upgrade the connection
if it has been explicitly configured by the main server config
to be an okay thing to do.

Any takers?  If not, I'll give it a try next week when I am back
from the IETF.

....Roy

Re: blocking Upgrade

Posted by "William A. Rowe Jr." <wr...@rowe-clan.net>.
On 3/29/2011 4:16 PM, Greg Stein wrote:
> Do you have an internet draft spec for some context here? Is there a
> proposal for HTTP/2.0?
> 
> I might also argue that a directive is not the right answer here.
> Instead, I'd suggest that modules advertise their ability to consume
> protocols. If an Upgrade arrives, and a relevant module is found, then
> the request is handled. If no such module is found, then the Upgrade
> header is ignored, and nothing happens.˛˛
> 
> If a module or CGI sees the Upgrade header, then what is the problem?
> It cannot truly alter the protocol in effect for the connection. That
> seems to be something only possible to handle within the core (to
> change the connection handler).
> 
> And back to the "AllowUpgrade" directive. What the heck should it do
> if something is present *besides* "none". It isn't like that can be
> handled. Some code must be written to provide other protocols, and
> *that* code should manage the tokens recognized. Not a directive.

Agreed, we already have a single example case; in the presence of the
'SSLEngine optional' directive, which consumes the Upgrade: TLS/1.0
given Connection: Upgrade

All such handlers must respond with a 101 Switching Protocols.

So if we don't see the resulting Upgrade: TLS/1.0, HTTP/1.1 response
header, we can easily short circuit any further response in the core
handler.  The mechanics of this could be simplified, but I'd suggest
we start by stealing code from mod_ssl's upgrade handler.

The only remaining system administration decision is "allow or refuse
unrecognized Upgrade requests?"  The recognition of specific upgrade
headers is up to the installed modules and their specific configurations.



Re: blocking Upgrade

Posted by Graham Leggett <mi...@sharp.fm>.
On 30 Mar 2011, at 5:48 PM, Greg Stein wrote:

> I think that Roy's point is simply that httpd would be nothing more
> than a socket-listener and tunnel. There is very little that it can
> bring to the table at that point, so it doesn't make a lot of sense to
> lump in websockets capabilities.

In theory, for somebody it might be a socket listener and a tunnel,  
using the same HTTP endpoint as their existing HTTP server, with the  
same port and the same digital certificate, perhaps additionally  
secured by an authn or authz module.

While I don't doubt that for a gateway like this to be practical there  
would be issues to overcome, such as ensuring long lived requests  
cannot starve out other server requests, however I do see some value  
in trying it. Disclaimer: ENOTIME right now, so no plans to do so for  
a while.

Regards,
Graham
--


Re: blocking Upgrade

Posted by Greg Stein <gs...@gmail.com>.
On Wed, Mar 30, 2011 at 11:08, Graham Leggett <mi...@sharp.fm> wrote:
> On 30 Mar 2011, at 4:41 PM, Roy T. Fielding wrote:
>
>> My guess is that it would if it were told to use a proxy for ws.
>>
>> Keep in mind that when I say proxy, I do not mean to include "reverse
>> proxy".
>> A reverse proxy of websockets is just an implementation of websockets or
>> a tunnel.  I consider both to be pretty dangerous and better done in
>> a special-purpose server rather than as a child of Apache httpd.
>
> When you say "pretty dangerous", are you referring to the danger of reaching
> the limit of slots willing to be served by the server, or something else?
>
> I would say that any server that supports the idea of long lived connections
> faces this danger, I don't see why httpd (suitably and sensibly configured
> obviously, probably with an event mpm and a limit as to the number of slots
> we allow to be long lived) can't play too.

I think that Roy's point is simply that httpd would be nothing more
than a socket-listener and tunnel. There is very little that it can
bring to the table at that point, so it doesn't make a lot of sense to
lump in websockets capabilities.

Cheers,
-g

Re: blocking Upgrade

Posted by Graham Leggett <mi...@sharp.fm>.
On 30 Mar 2011, at 4:41 PM, Roy T. Fielding wrote:

> My guess is that it would if it were told to use a proxy for ws.
>
> Keep in mind that when I say proxy, I do not mean to include  
> "reverse proxy".
> A reverse proxy of websockets is just an implementation of  
> websockets or
> a tunnel.  I consider both to be pretty dangerous and better done in
> a special-purpose server rather than as a child of Apache httpd.

When you say "pretty dangerous", are you referring to the danger of  
reaching the limit of slots willing to be served by the server, or  
something else?

I would say that any server that supports the idea of long lived  
connections faces this danger, I don't see why httpd (suitably and  
sensibly configured obviously, probably with an event mpm and a limit  
as to the number of slots we allow to be long lived) can't play too.

Regards,
Graham
--


Re: blocking Upgrade

Posted by "Roy T. Fielding" <fi...@gbiv.com>.
On Mar 30, 2011, at 4:11 PM, Graham Leggett wrote:
> On 30 Mar 2011, at 3:53 PM, Roy T. Fielding wrote:
> 
>> No, websockets is not designed to work with intermediaries.
>> There is no standard behavior beyond opening the connection,
>> so connections through proxies should use CONNECT.
> 
> Does a websocket client have a way of knowing it should use CONNECT?

My guess is that it would if it were told to use a proxy for ws.

Keep in mind that when I say proxy, I do not mean to include "reverse proxy".
A reverse proxy of websockets is just an implementation of websockets or
a tunnel.  I consider both to be pretty dangerous and better done in
a special-purpose server rather than as a child of Apache httpd.

....Roy


Re: blocking Upgrade

Posted by Graham Leggett <mi...@sharp.fm>.
On 30 Mar 2011, at 3:53 PM, Roy T. Fielding wrote:

> No, websockets is not designed to work with intermediaries.
> There is no standard behavior beyond opening the connection,
> so connections through proxies should use CONNECT.

Does a websocket client have a way of knowing it should use CONNECT?

Regards,
Graham
--


Re: blocking Upgrade

Posted by "Roy T. Fielding" <fi...@gbiv.com>.
On Mar 30, 2011, at 12:32 PM, Graham Leggett wrote:
> On 30 Mar 2011, at 10:49 AM, Roy T. Fielding wrote:
>> On Mar 29, 2011, at 11:16 PM, Greg Stein wrote:
>> 
>>> Do you have an internet draft spec for some context here? Is there a
>>> proposal for HTTP/2.0?
>> 
>> websockets
> 
> In theory, over and above natively supporting websockets, it may be useful to teach mod_proxy how to reverse proxy the ws scheme to another websockets server. Would a module like mod_proxy_websockets or mod_proxy_ws make sense?

No, websockets is not designed to work with intermediaries.
There is no standard behavior beyond opening the connection,
so connections through proxies should use CONNECT.

I am not planning to implement websockets -- I just want to
protect the rest of the server from kids playing with toys.

....Roy

Re: blocking Upgrade

Posted by Graham Leggett <mi...@sharp.fm>.
On 30 Mar 2011, at 10:49 AM, Roy T. Fielding wrote:

> On Mar 29, 2011, at 11:16 PM, Greg Stein wrote:
>
>> Do you have an internet draft spec for some context here? Is there a
>> proposal for HTTP/2.0?
>
> websockets

In theory, over and above natively supporting websockets, it may be  
useful to teach mod_proxy how to reverse proxy the ws scheme to  
another websockets server. Would a module like mod_proxy_websockets or  
mod_proxy_ws make sense?

Regards,
Graham
--


Re: blocking Upgrade

Posted by "Roy T. Fielding" <fi...@gbiv.com>.
On Mar 29, 2011, at 11:16 PM, Greg Stein wrote:

> Do you have an internet draft spec for some context here? Is there a
> proposal for HTTP/2.0?

websockets

> I might also argue that a directive is not the right answer here.
> Instead, I'd suggest that modules advertise their ability to consume
> protocols. If an Upgrade arrives, and a relevant module is found, then
> the request is handled. If no such module is found, then the Upgrade
> header is ignored, and nothing happens.˛˛
> 
> If a module or CGI sees the Upgrade header, then what is the problem?
> It cannot truly alter the protocol in effect for the connection. That
> seems to be something only possible to handle within the core (to
> change the connection handler).
> 
> And back to the "AllowUpgrade" directive. What the heck should it do
> if something is present *besides* "none". It isn't like that can be
> handled. Some code must be written to provide other protocols, and
> *that* code should manage the tokens recognized. Not a directive.

Right, I woke up thinking the same thing -- that the http filter
is the only place that an Upgrade could actually be implemented
because it would have to switch itself off.  What I was trying
to avoid is a script thinking that it can switch without writing
a new protocol filter, or a CGI that deliberately spoofs an upgrade
for some nefarious purpose I haven't thought of yet.

We can just delete the Upgrade header in the http_filter, for now.

....Roy


Re: blocking Upgrade

Posted by Greg Stein <gs...@gmail.com>.
Do you have an internet draft spec for some context here? Is there a
proposal for HTTP/2.0?

I might also argue that a directive is not the right answer here.
Instead, I'd suggest that modules advertise their ability to consume
protocols. If an Upgrade arrives, and a relevant module is found, then
the request is handled. If no such module is found, then the Upgrade
header is ignored, and nothing happens.˛˛

If a module or CGI sees the Upgrade header, then what is the problem?
It cannot truly alter the protocol in effect for the connection. That
seems to be something only possible to handle within the core (to
change the connection handler).

And back to the "AllowUpgrade" directive. What the heck should it do
if something is present *besides* "none". It isn't like that can be
handled. Some code must be written to provide other protocols, and
*that* code should manage the tokens recognized. Not a directive.

Cheers,
-g

On Tue, Mar 29, 2011 at 17:04, Roy T. Fielding <fi...@gbiv.com> wrote:
> Does anyone with a working install want a quick project?
>
> We need to block the Upgrade header field by default.  What this
> will require is a new configuration command, like
>
>   AllowUpgrade None | word ...
>
> where word is any protocol name, like HTTP/2.0, waka, websocket, etc.
> The config command must only be allowed in rsrc_conf.
>
> We then need a check somewhere in the http filter for an incoming
> request header field called "Upgrade".  If present and the config option
> is set to None (or default), then remove the Upgrade field before it
> is seen by the request handler (i.e., before it might be used by some
> module or CGI script to send the server down a rat hole).
> If the config option is set and not None, then set the Upgrade
> header field-value to be the intersection of what was sent by the
> client and what is allowed by the config.
>
> Likewise, perform the same filtering on outbound responses.
>
> In other words, only allow a handler to upgrade the connection
> if it has been explicitly configured by the main server config
> to be an okay thing to do.
>
> Any takers?  If not, I'll give it a try next week when I am back
> from the IETF.
>
> ....Roy
>