1

I would like to make my apache2 webserver serve both http and https on the same port.
With the different method i tried it was either not working on http or on https..

How can I do this?

Update:
If I enable SSL and then visit the with http I get page like this:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
<blockquote>Hint: <a href="https://server/"><b>https://server/</b></a></blockquote></p>
<hr>
<address>Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny16 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8g Server at server Port 443</address>
</body></html>

Because of this, it seems very much possible to have both http and https on the same port.
A first step would be to change this default-page so it would present a 301-Moved header.

Update2: According to this, it is possible. Now, the question is just how to configure apache to do it.

Zulakis
  • 4,153
  • 14
  • 48
  • 76
  • First, it would be a *great* idea to tell us what method you tried that didn't work. Second, why want you do this? Standard port for https is 443, and if you change that to e.g. 80, you'll need to open the site in the browser like this: `https://example.com:80`. Third: I don't believe it is possible anyway. – Sven Sep 22 '12 at 15:49
  • We are having other services on non-standard ports like 999. Now I want it to be possible for our users to use both https://server:999 and http://server:999. – Zulakis Sep 22 '12 at 15:52
  • Apache is even telling you that it can't do what you want. – Sven Sep 22 '12 at 16:01
  • No it is not. It is telling me that it does only accept https connections (for security reasons, obviously). That it is ACTUALY TELLING me this is proof that it can do both http and https on the same port. – Zulakis Sep 22 '12 at 16:06
  • 1
    @Zulakis Yes, it's possible to detect the protocol that the client is attempting to use before the server sends any response - but it's not possible to configure Apache to serve up anything other than errors via HTTP on an HTTPS port. To do this, you'd probably need to heavily modify `mod_ssl`. – Shane Madden Sep 22 '12 at 16:39
  • For those who find this question through Google: Serving both HTTP and HTTPS on the same port is totally possible — see https://github.com/mscdex/httpolyglot . The highly-voted negative answers are just saying that it's just not necessarily solvable using _only_ Apache and no other tools at all. – Quuxplusone Mar 16 '20 at 21:43

4 Answers4

2

SSL trafic can not work on same port as non-SSL traffic, TLS can do that but it is not used on web servers TLS is mostls used on SMTP server precisesly because of that reason

The same question was already asked several times (see two examples beneath) by different people, and it was always said, it is not possible by using Apache alone, you would have to use some other software or make your own listener of some kind:

Apache2 Rewrite http to https on port 5553

Apache answer both HTTP and HTTPS on the same port

Also I could not find any official Apache document that mentions http and https traffic on same port without some redirecting.

Keep in mind that when people say SSL they usually mean SSL/TLS which are not the same.

I would take this answer from apache.org as a definitive NO to your question to working with http and https on same port

    Can we have both http and https listening on the same port?

Comment 1 Eric Covener 2011-11-22 14:36:45 UTC

No, and bugzilla is not for support or Q&A.  Try the users mailing list.

https://issues.apache.org/bugzilla/show_bug.cgi?id=52228

You can try the mod_rewrite module but I suggest that you open another question on how to use it to make https redirects (you will still need to have multiple ports). I haven't worked with it so can't give you details about how to do it.

Like I said don't know much about the module so my guess is that you would need three ports. One non-SSL port for mod_rewrite to listen, one non-SSL for http traffic and one SSL port for https, you would have to make the 999 port for mod_rewrite and then have your services listen on two different port for http and https.

Pay attention to what Shane Madden said in his comment, http request on SSL enabled port would only give you errors even if you put mod_rewrite on that port.

ralz
  • 2,751
  • 2
  • 17
  • 22
  • Please have a look at my updated initial post. – Zulakis Sep 22 '12 at 15:56
  • check this two posts. http://stackoverflow.com/questions/5327850/support-both-ssl-and-non-ssl-on-the-same-server-port, http://blog.magicaltux.net/2008/12/07/ssl-server-how-to-autodetect-sslnon-ssl/ – ralz Sep 22 '12 at 16:00
  • Okay, according to the posts it's possible. Now, how can I do this with apache2? – Zulakis Sep 22 '12 at 16:03
  • i never tried what you want but as far as I see it you would have to have a service on 999 port which would see if it is the SSL or non-SSL traffic and then redirect it at the other ports (997 or 998 lets say) based on type of traffic. Both post as I see speak of TLS, but I don't know that you can put TLS certificates on Apache – ralz Sep 22 '12 at 16:04
  • Well I get the message mentioned in my initial post when using a SSL-certificate... It seems to be possible with one too. As a first step, we could try to change this to a 301-Moved message. Any ideas? – Zulakis Sep 22 '12 at 16:08
  • The second post mentioned webmin btw, which is actually using SSL. – Zulakis Sep 22 '12 at 16:10
  • 1
    SSL is predecessor to TLS, and as far as I know (could be wrong) https connections on server side use SSL connection. TLS send first hello message in clear text and then sees if it gets encrypted or unecrypted response and based on that client send data either in clear text pr encrypted. SSL starts with encyrption from start so neither the server or the client can choose the type of traffic – ralz Sep 22 '12 at 16:10
  • What happens is that the client sends a non-encrypted GET request. The server sees this and then also answers non-encrypted. ***Edit:*** This is also what is described in the [first post](http://blog.magicaltux.net/2008/12/07/ssl-server-how-to-autodetect-sslnon-ssl/) mentioned by you.. – Zulakis Sep 22 '12 at 16:12
  • 1
    @Zulakis take a look at my answer, I edited it, I say definitely not possible – ralz Sep 22 '12 at 16:38
  • Thanks alot! I think this really added some good information to the question. Still, it must be possible to serve a 301-header instead of a 400-one which would help me a bit already. Any ideas on that one? – Zulakis Sep 22 '12 at 16:48
  • I already tried doing it with mod_rewrite, but it seems like the conenction gets terminated before mod_rewrite is being used.. – Zulakis Sep 22 '12 at 17:01
  • Look at my answer, I updated it with a proof-of-concept snippet. No idea why this got a down-vote. – Zulakis Sep 22 '12 at 21:33
  • It is definitely possible. With both protocols, the client sends first. So all you have to do is look at the data the client sends you. If it's an SSL/TLS handshake, respond with SSL/TLS replies. If it's an HTTP verb, respond with an unencrypted reply. – David Schwartz Sep 23 '12 at 07:14
  • @rAlen, it is due to clear some confusion. STARTTLS is a method of upgrading a plaintext protocol to TLS, most prominently used as an ESMTP extension. However, even end to end encrypted TLS/SSL trafic can be [analyzed and routed to appropriate upstream](https://www.nginx.com/blog/running-non-ssl-protocols-over-ssl-port-nginx-1-15-2/ ). This is used in [sslh](https://linux.die.net/man/8/sslh) which can effectively serve HTTPS and SSL on the same port by sniffing the protocol initiation. – Robert Cutajar Mar 11 '21 at 12:08
2

It is possible to redirect http to https by using a custom ErrorDocument.
Having the whole webserver run on both http and https is not possible at the current version of Apache though.

Sadly, there is a bug in Apache 2.2-16 which has not been fixed yet because of which the redirection does only work in Apache 2.4.

For further infos have a look here: https://issues.apache.org/bugzilla/show_bug.cgi?id=50823

Update
Here is a proof-of-concept snippet I testet with apache 2.4:

<?php
if ($_SERVER["REDIRECT_STATUS"] == "400" && preg_match("/.*?Reason: You're speaking plain HTTP to an SSL-enabled server port\..*/", $_SERVER["REDIRECT_ERROR_NOTES"])) {
    header("Location: https://localhost:999");
} else {
    //echo normal error message
}
?>

Use it by setting ErrorDocument 400 /redirect-400-error.php in your apache config file. You can find more info on the implementation of custom ErrorDocuments here.

Zulakis
  • 4,153
  • 14
  • 48
  • 76
1

Easy Solution:

ErrorDocument 400 https://server:port/

Now you get a "Found" redirect, and no nasty error message.

Catalyst
  • 11
  • 1
  • That's pretty much the same solution I came up with above. Just without the checking if it's actually a error with `http://` instead of `https://` – Zulakis Oct 19 '12 at 15:57
  • How is that not checking the error? Apache already knows there's an error, thus you have a 400 status to begin with. What you did with your code was rewrite something that Apache already did ... You're overthinking it. ;-) – Catalyst Nov 10 '12 at 03:43
  • If the code ever produces a 400 error this is clearly wrong. – Tim Ludwinski Dec 07 '15 at 23:23
0

I think it could work by defining a static ErrorDocument eg:

ErrorDocument 400 /redirect_https.txt

Then create the file redirect_https.txt in your document root with the following content:

HTTP/1.1 302 Found
Location: https://www.example.com/mypage.html

This works (even tried) and sends the browser a "faked" HTTP-redirect.

slm
  • 7,615
  • 16
  • 56
  • 76
powo
  • 1