2

I have an application that is deployed on Glassfish and listens to port 8181 for HTTPS traffic (currently). The problem is that when deployed, customers rarely create a valid certificate for the server. This means that the HTTPS fails certificate checks.

There is some type of content in our application that we'd like to fetch over HTTP, as it's static and the fact that fetching is not encrypted is not a problem.

The problem we DO have is that only port 8181 is available for the users (firewalls, etc., cannot be changed).

So, we need a way for Glassfish to listen to the incoming connection on port 8181 and identify what protocol is being attempted (https://myserver:8181 or http://myserver:8181).

I've seen a solution for Tomcat: https://serverfault.com/questions/47876/handling-http-and-https-requests-using-a-single-port-with-nginx#comment-37501

Any ideas on how to do this with Glassfish? Can we implement a hook in there and hand off to either handler (HTTP or HTTPS) appropriately?

Community
  • 1
  • 1
Yon
  • 1,023
  • 4
  • 13
  • 23

2 Answers2

2

What you're trying to do is called "port unification", and should be supported by Glassfish, as implemented in Grizzly.

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • Very interesting... I'm curious whether performance suffers too much or not? Because apparently "magic recognizer" does exist out of the box. – n1ckolas Mar 15 '13 at 12:36
  • The "magic recognizer" is very simple. If the first byte from the client is `0x16` or `>= 0x80`, it's TLS/SSL. If it's printable 7-bit ASCII, it's HTTP. I strongly doubt there is significant performance impact. – Robert Tupelo-Schneck Jul 22 '14 at 15:21
  • 1
    In case it is useful for others who come across this question, [here is an implementation of port unification using Jetty](http://stackoverflow.com/a/24891007/394431). – Robert Tupelo-Schneck Jul 22 '14 at 15:22
  • For people following the linked tutorial, it's worth noting that the class names have changed in glassfish4 https://java.net/jira/browse/GLASSFISH-18440 – moneyt Jun 13 '15 at 13:54
0

I've looked at all answers over there and they tell almost the same: it is impossible because of the differences between HTTP and HTTPS. Even browsers use different default ports for handling HTTP/HTTPS.

Why this is happening: HTTP is basically text protocol, and browsers just sends HTTP (text) headers over TCP-IP. HTTPS isn't just SSL over HTTP. First of all browser performs "handshake", then it receives from server certificate, and all information from server to browser and vice versa is being encoded with symmetric keys negotiated during the handshake.

Because of 2 keys (public and private), which is used in asymmetric encryption, nobody (except who knows private key) can't sniff or change the information.

Experiment: try to do following: change https to http and explicitly add "443" in the end (something like http://google.com:443) You've got either "The connection was reset" or suggestion to store binary file (e.g. certificate).

Note: usually servers are set to reject such requests.

So even if you use the same connector to handle both HTTP and HHTPS connections, you are supposed to use different connection handlers (we faced with this when were implementing high-load server based on Netty).

And the only possibility to use HTTP and HTTPS on the same port is with using "magic recognizer", which would check either plain text has come or binary handshake. If we put that recognizer on the container's side (Glassfish protocol handler), it would have quite big performance overhead (checking each request whether it SSL or not!). If we put it on the proxy server's side (e.g. nginx or other non-blocking servers, such as Netty) performance wouldn't suffer too much, but anyway this doesn't guarantee 100% of success.

Note: that proxy server just recognizes, and after that it forwards request to 2 different ports!

As a conclusion: in general, it's possible, but from my point of view, the needed work doesn't worth the result.

EDIT: As @Bruno answered, there is present magic recognizer out of the box, but it is not officially supported by Glassfish.

Community
  • 1
  • 1
n1ckolas
  • 4,380
  • 3
  • 37
  • 43
  • 2
    "*all information from server to browser and vice versa is being encoded with that certificate.*": not really, the encryption of the actual application data isn't done with the certificate, but with symmetric keys negotiated during the handshake. – Bruno Mar 15 '13 at 11:44
  • "*I've looked at all answers*": Not quite, see [here](http://stackoverflow.com/a/6564086/372643) and [here](http://stackoverflow.com/a/11986016/372643). (Easy to miss, though) – Bruno Mar 15 '13 at 11:57
  • 1
    HTTPS is just HTTP over SSL actually. The certificate exchange is part of the handshake. There is no asymmetric encryption in SSL except in a small part of the handshake in some cipher suites. What the OP asks for is indeed possible. Too many errors here. -1 – user207421 Mar 16 '13 at 00:21
  • @EJP I thought I mentioned everything, that you wrote. But I'm not going to argue with you, thanks for comment. – n1ckolas Mar 16 '13 at 07:55
  • @n1ckolas You mentioned them all right, incorrectly. My comments were *corrections* to what you wrote, in every case. – user207421 Mar 17 '13 at 00:23