質問

Background

I have implemented a HTTPS server which sits inside a piece of hardware for the purpose of secure remote configuration of the device. To achieve this, I have used an existing lightweight embedded TCP/IP stack together with an open source SSL library. The web server that sits on top of that has been written by me entirely from scratch. (This may seem like reinvention of the wheel, but for our purposes it needs to be very lightweight and have a very narrow set of specific features. For instance, compatibility with the embedded RTOS we are using, and the ROM "file system". This is a system where just several hundred kilobytes are available for HTTP(S) sessions and SSL contexts, not many megabytes. After all things considered and various other offerings looked at, it made sense to create my own). This web server only needs to support somewhere between 5 and 10 simultaneous socket connections (i.e. 5 to 10 concurrent or persistent HTTP connections), which is about as much as the hardware can handle. This is fine, because it's designed for just one or two people to access, to administer the box.

At present it now all works great. I have coded it to implement as much of RFC2616 that I believe necessary for HTTP 1.1. At the moment, it is just listening on five HTTPS ports (443) and I have not yet implemented anything to redirect from port 80.

First question - Redirection

I have seen countless articles about redirection from HTTP to HTTPS, but everything I have read concerns how to configure existing and conventional web servers to do this. What I want to work out is what techniques are used at protocol level, as I have to implement this programmatically.

The common way seems to be to issue a 301 / 302 response. So, the strategy I had thought of doing is, assuming for the sake of example I have the resources for eight simultaneous requests:

  • Listen on port 443 for HTTPS connections. Up to six simultaneous HTTPS connections (six sockets) available.

  • Listen on port 80 for HTTP connections, and up to two HTTP connections (thus two sockets on port 80) available. For the sockets on port 80, the real web server wouldn't really be accessed. Instead, I would just keep reading from the socket until \r\n\r\n or \n\n is seen (indicating end of request header) and then send back a 301 (or 302) response, which in my code would pretty much be a hard-coded const char* string. Then, close the socket. Those two port 80 sockets would exist purely for the purpose of redirection.

Does this strategy sound sensible?

The only thing I'm not sure about at the moment is the inclusion of the redirect URL in the 301 / 302 response. This hardware 'box' is a device that could be sat in a house or somewhere behind a router, possibly accessed via a dynamic DNS service, etc. So, how would I programmatically determine its 'outside world' equivalent HTTPS URL? Perhaps by using a combination of what's in the request URI and the host: field of the original HTTP request header?

If the above poses any problems, then the next best idea I have is to instead serve back a small piece of HTML, that contains a bit of JavaScript that performs a HTTPS redirection by fetching the URL from the browser (specifically what JavaScript methods I would call to do this I can't remember offhand, but I have done it ages back). (At present I am also unsure how on earth the SSL certificate is going to work considering there's no specific domain that can be specified, but I'm going to cross that bridge later, perhaps in a separate SO question.)

Second question - offering HTTP and HTTPS

This is perhaps a lot more of a design question, or down to what the customer wants, than a programming question - but I thought I'd chuck it in here anyway to see what opinions people have. My issue is that the client have simply stated that the box "should have SSL", but little more than that. What I don't know is if they might be expecting to be able to offer the end user a choice over whether or not SSL is used, for instance. Now before actually asking them, I'm just anticipating what might be asked, and I'd like to arm myself with some knowledge and answers beforehand. To put it another way, the people writing the specification for this "just want to see a padlock" and "want SSL", which is obviously a good thing; but I need to prepare myself for daft suggestions.

First of all, I know there is no such thing as a half-way solution with SSL: You either need to have it all, or nothing. In other words, let's say I decided to try to reduce the work my little processor has to do by serving the important stuff via HTTPS, but I serve the images and CSS files via HTTP. After doing some reading I now know exactly why this is an absolute no-no for many reasons.

What if I did, however, offer the end user the ability to choose either HTTPS or HTTP at some initial login page? Selecting 'HTTPS' would redirect to a secure HTTPS login page. This might be a useful option to offer should the user make the choice to compromise security for the sake of additional access speed when accessing the box from a mobile phone, for example. This initial page might offer both a 'secure login' and a 'standard unsecure login - not advised' or similar. Obviously this opens up a vulnerability as far as the user is concerned, but does it also compromise the SSL connection? What I mean by that is, since this initial login page has to be served via HTTP, presumably an attacker could in theory mangle it so that the buttons are swapped around - that kind of thing. Therefore, should HTTPS mean HTTPS right from the start? Given that I have managed to shoehorn HTTPS into this thing and make it work, and also given that is is specifically designed to be used with a modern browser (IE8/9, FF), is there any practical reason why normal HTTP access should be offered as an alternative?

役に立ちましたか?

解決

On question 1: I think both techniques are sound are used regularly by commercial sites, however reading the host header and returning a 301 is definitely preferable if space is really so limited on the server end.

On question 2, one possible objection to offering both protocols is that some man-in-the-middle attacks will re-route the https request/response comm to http from the client's perspective during a session. Most browsers guard against a mid-session re-route with a warning message but if the attacker knows the target site in advance, he may be able to fool the user, especially if the user is expecting that the site could operate in either mode. For this (and probably a bunch of even better reasons that I don't know) it likely makes sense to limit to https since you're already done the work anyway.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top