Mobile app version of vmapp.org
Login or Join
Annie201

: Apache - Force https by default on custom port I am hosting a control panel for web management on a second Apache instance that runs on port 2083. It has port 2082 for the HTTP version of

@Annie201

Posted in: #Apache

I am hosting a control panel for web management on a second Apache instance that runs on port 2083. It has port 2082 for the HTTP version of the site because it needed something to run the HTTP version on but the port is closed. When the user connects to the site like so:
example.com:2083/

They see the web panel. However, when they visit the site like this:
example.com:2083/

They get the error

Bad Request

Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.


There is no link to click to continue. Instead of showing this error, I would like to automatically force the HTTPS protocol on the URL so they use the secured version of the portal. Since 2083 is being used for the SSL port on this panel, it causes a conflict if they don't specify HTTPS. And using the .htaccess file to add a redirect does not work since the port is loaded and sees the error before it loads anything else, ending there without ever reading the .htaccess file.

I am running Apache 2.4.23 on both the main version of the site (hosted on a Windows machine) and on the control panel. As far as I am aware this is the newest available model for a win64 model machine.

Is there any way to force the HTTPS before it loads anything else?

Here is the current httpd-ssl file

Listen 2083
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
SSLProxyCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
SSLHonorCipherOrder on
SSLProtocol all -SSLv2 -SSLv3
SSLProxyProtocol all -SSLv2 -SSLv3
SSLPassPhraseDialog builtin
SSLSessionCache "shmcb:c:/panel/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300
<VirtualHost *:2083>
SSLEngine on
SSLCertificateFile "c:/panel/conf/ssl/sslcert.crt"
SSLCertificateKeyFile "c:/panel/conf/ssl/sslcert.key"
SSLCertificateChainFile "c:/panel/conf/ssl/sslcert.ca-bundle"
ServerName sitename.com ServerAlias example.com DocumentRoot "c:/panel/htdocs/"
</VirtualHost>

10.03% popularity Vote Up Vote Down


Login to follow query

More posts by @Annie201

3 Comments

Sorted by latest first Latest Oldest Best

 

@Cody1181609

I don't believe you can do this directly with Apache. Once you tell it you're using SSL (or actually TLS) on a port, it will expect a TLS negotiation to happen, and things will break if the browser sends "regular" HTTP rather than TLS.

Theoretically, it should be possible to have something listen on that port, detect from the first few bytes if it's regular HTTP or TLS, and act accordingly: if it's HTTP, send back a redirect, otherwise actually start TLS (either directly and then proxy/tunnel the cleartext contents to Apache, or just forward the whole encrypted stream to Apache transparently).

I was not aware of any software doing anything like this out of the box, but it seems that Nginx actually does support it, see stackoverflow.com/a/15435799/3527940 for an example.

10% popularity Vote Up Vote Down


 

@Alves908

As Simon has already pointed out (and you surmise in your question), this does not seem to be possible directly from the server. Since a request for example.com:2083/ simply can't be handled by the server (when it already handles example.com:2083/). As the response indicates, it's simply a "Bad Request".

Any solution would need to come from the client end (or some intermediary device) that knows to "upgrade" the request, before actually making the request to your server. There are browser extensions that might be able to handle this - but I suspect that installing something on the client is not desirable (or even possible).

There is the HTTP Strict Transport Security (HSTS) policy that instructs the client to always request the HTTPS version of the site in subsequent requests. However, this has some caveats which I can't see workarounds for in your case:


this requires the user to have already successfully requested the HTTPS version (at which point the Strict-Transport-Security response header is sent informing the client that all future requests to this host must be HTTPS).
HSTS is for when the host uses only SSL. All HTTP (non-SSL) requests will be upgraded. There is no HTTP anymore. Which means that domain.com:2082/ will not be accessible either. The browser will try to upgrade this request to domain.com:2082/ (yes, wrong port - see below) - this request will now break.
As seen in the above point, HSTS does not really work with non standard ports (ie. ports other than 80/443). For non port 80 requests, the port number is preserved in the request. So, as stated above, port 2082 stays as port 2082. (Because the intention is that everything is now HTTPS.)


(Aside: I've not really studied the spec, but I wonder why the desired port couldn't be set as part of the initial Strict-Transport-Security response header, or have an option/flag that instructs the browser to direct requests back to the same port as the initial "successful" request? This would seem to get around points #2 and #3 above?)

So, the same conclusion as Simon, this does not seem to be possible.

Custom 400 Bad Request ...?

Just a thought... you could try defining a custom 400 ErrorDocument to have a more meaningful message and perhaps a link (or even JavaScript redirect?). However, this would need to be defined directly in the main server config to stand any chance of being triggered. (But it's not always possible to override some system generated Apache errors anyway.) And I would think you would need to specify an absolute URL in order to trigger an external redirect to another site (which will naturally lose the error status). Even if this "works", I'm not sure that it would necessarily be a good idea. (?)

10% popularity Vote Up Vote Down


 

@Nimeshi995

Sorry but as far as I know this can't be done by using either htaccess or the virtual host by Apache, as NON-SSL and SSL both have to have their own dedicated port, they can not share a port and its impossible for a browser to communicate with a server using the wrong protocol.

Most websites will use port 80 and 443, these ports do not appear in the address bar and therefore when you connect to http your actually connecting to example.com:80 and with a SSL enabled site you connect to example.com:443. So when you see a site redirect from HTTP to HTTPS its happened over two ports, not one.

You can have:

example.com:80 redirect to example.com:443

You can not have:

example.com:443 redirect to example.com:443

cPanel by default will use these ports:

2082 TCP CPanel default
2083 TCP CPanel default SSL


The major problem is the browser expecting the data to be either HTTPS or HTTP based on the address typed into the action bar unless a redirect is actioned but then the browser is notified of the protocol change. Since you can't connect to action that redirect the browser will fail. I'm fairly confident if there was a way then Apache or cPanel would support it and have it documented somewhere.

I'm not saying it can't be done entirely, but it can't be done on the Apache or cPanel level. I'd imagine you would need something sitting in-between both the user and Apache which monitors the packets and then does something with it, other than that I can't speculate any further or tell you a full solution.

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme