# Apache / VirtualHosts / Some SSL?



## l008com (Feb 13, 2019)

I've got a bit of a dillema. My apache listens on port 80 and port 443. 8 websites run on http. One website runs on https.
 (I know all about the ridiculous push to encrypt everything via letsencrypt, and eventually I will do that, but it's going to be a while)

The problem is that now that https is enabled, someone can plop https:// in front of any of my non-https websites and get a screen full of SSL validity error messages, and then ultimately get forwarded to a totally different website. 

Is there a way to prevent this behavior? These sites are all running on the same IP and I can't change that. Is there some graceful way to handle these https requests that don't point to anything that actually exists?


----------



## tommiie (Feb 13, 2019)

I don't think there is an easy solution for this other than setting up listeners with the correct certificates. But then you're just moving towards full TLS.


----------



## SirDice (Feb 13, 2019)

l008com said:


> The problem is that now that https is enabled, someone can plop https:// in front of any of my non-https websites and get a screen full of SSL validity error messages, and then ultimately get forwarded to a totally different website.


How did you define the vhost configurations? And how are you redirecting HTTP to HTTPS on the SSL enabled site?


----------



## l008com (Feb 13, 2019)

SirDice said:


> How did you define the vhost configurations? And how are you redirecting HTTP to HTTPS on the SSL enabled site?


Currently no redirect. The site works with and without ssl. What other info do you want to know about the vhosts?


----------



## tommiie (Feb 13, 2019)

SirDice said:


> How did you define the vhost configurations?



Does it matter? In my understanding, since the server listens on port 443, it will consider the one and only vhost to be the default to which all traffic gets directed. If the Host header is not correct - which is the case when they put "https" in front of a non-https website - the default wesbite will be shown with security warnings.

I do not believe you can disable this "feature" of a default catch-all website.


----------



## SirDice (Feb 13, 2019)

tommiie said:


> If the Host header is not correct - which is the case when they put "https" in front of a non-https website - the default wesbite will be shown with security warnings.


Oh, right. That's the problem here indeed. SNI doesn't use the host header though, the hostname is embedded in the initial SSL handshake, but the result is pretty much the same.

A nice solution would be to put the HTTP-only sites on one IP address and the HTTP/HTTPS sites on another. But I understand that's not possible for l008com


----------



## l008com (Feb 13, 2019)

SirDice said:


> Oh, right. That's the problem here indeed. SNI doesn't use the host header though, the hostname is embedded in the initial SSL handshake, but the result is pretty much the same.
> 
> A nice solution would be to put the HTTP-only sites on one IP address and the HTTP/HTTPS sites on another. But I understand that's not possible for l008com


 It's not although my most popular website does already have it's own IP, so I can at least block that site from incorrect https requests until I implement SSL on that domain. 

But how would I do that exactly? Right now each domain uses "*:80" to define IP and port. But simply adding an IP address to that vhost won't stop the whole server from still listening on 80 and 443 on all IPs, there must be something else I need to do?


----------



## tommiie (Feb 13, 2019)

SirDice said:


> SNI doesn't use the host header though, the hostname is embedded in the initial SSL handshake, but the result is pretty much the same.


Ah, right. My bad. But indeed, the logic and the result are pretty much the same.



SirDice said:


> A nice solution would be to put the HTTP-only sites on one IP address and the HTTP/HTTPS sites on another. But I understand that's not possible for l008com


This would be a nice solution indeed. I did not think of that.

Either ignore it if it does not happen that often or put in some effort of getting the certificates from Let's Encrypt. You have it set up for one website so automate the process and renewal and you're done. It's the short pain.


----------



## SirDice (Feb 13, 2019)

l008com said:


> But how would I do that exactly? Right now each domain uses "*:80" to define IP and port. But simply adding an IP address to that vhost won't stop the whole server from still listening on 80 and 443 on all IPs, there must be something else I need to do?


Keyword here is "firewall". Only IP_A allows access to port 80, IP_B allows both 80 and 443. A https://example.com when example.com only supports HTTP would result in browser time-outs since it resolved to IP_A. When you enable SSL move the website from IP_A to IP_B.


----------



## obsigna (Feb 13, 2019)

I just checked the following on my site. In the virtual host setup for a domain which I do not want to serve by HTTPS, I need to put a <VirtualHost> container with a single line, which is triggered by the SNI for that host - here using www.example.com:

```
<VirtualHost *:443>
    ServerName  www.example.com:443
</VirtualHost>
```

Provided, that we got a regular <VirtualHost> container for www.example.com:80, users might navigate to it by HTTP, however, once somebody „plops“ https in front of the address, the client simply refuses to connect, because on the server side the SSL engine is not set to ON for that vhost, and no redirection happens either - at least not from our part.

PS: It is important not to set the SSL engine in general to ON. Set it to ON only in the <VirtualHost> containers which do require TLS (SSL).


----------



## SirDice (Feb 13, 2019)

Wouldn't a bogus default site achieve the same?


```
<VirtualHost _default_:443>
</VirtualHost>
```

Edit: Oh, wait. Apparently `_default_` only works for Apache 2.2, it has the same meaning as '*' on 2.4.

Edit2: For crying out loud, [noparse] still parses underscores and translates them to [i][/i].


----------



## l008com (Feb 13, 2019)

obsigna said:


> I just checked the following on my site. In the virtual host setup for a domain which I do not want to serve by HTTPS, I need to put a <VirtualHost> container with a single line, which triggers the SNI for that host - here using www.example.com:
> 
> ```
> <VirtualHost *:443>
> ...



I like this solution. I'll give it a try. I have a lot of virtual hosts but I'm going to need to duplicate them all for real SSL at some point anyway, so if this works, it will solve this current problem until then! (Update: Success!)


----------



## CyberCr33p (Feb 14, 2019)

You have to use a dedicated IP for non-SSL websites and another dedicated IP for SSL websites. This is the only way to not load a wrong SSL for non-SSL websites.


----------



## xtaz (Feb 14, 2019)

There is another possibility but it adds complexity and personally I would rather just put SSL on every one of the websites. To simplify that process you could either just get a wildcard certificate if they are all under the same domain, or else use multiple domains in the SubjectAltName field so the same certificate is valid for all sites.

But anyway, the other possibility is to use something like SSLH which is a port multiplexer. There is a port of it in net/sslh. It's designed for being able to run both sshd and a webserver on the same port like 443, but it could be used for what you want too. You could make it send http to a different IP/port than https. This could either be a real webserver, or a fake IP/port that isn't listening so that the connection is just closed with a timeout or a reset.


----------



## ekingston (Feb 14, 2019)

CyberCr33p said:


> You have to use a dedicated IP for non-SSL websites and another dedicated IP for SSL websites. This is the only way to not load a wrong SSL for non-SSL websites.



Really?

Then why does my site work with both http and https on the same IP address with multiple domains, even on the same port?

SNI has been around a while now and seams to be working fine for me.


----------



## CyberCr33p (Feb 14, 2019)

Disable the SSL configuration from your website. And then try to load it using https and you will see that it loads SSL certificate from different domain.


----------



## ekingston (Feb 14, 2019)

CyberCr33p said:


> Disable the SSL configuration from your website. And then try to load it using https and you will see that it loads SSL certificate from different domain.



Why would it do that? If I disable the SSL config for a virtualhost running on port 443, then the website is not properly configured and should fail due to the misconfiguration.

Or do you mean that the browser would then request HTTP (not HTTPS), in which case no certificate at all would be presented.


----------



## xtaz (Feb 14, 2019)

If you read what the OP is actually trying to do then it makes sense. 8 websites run on http and 1 website runs on https. When OP goes to any of the other 7 websites using https they get an invalid certificate warning because the webserver returns the certificate from the 1 configured website because it is the default server for port 443. SNI doesn't help here as the OP is not willing at this time to configure the other 7 websites with proper SSL configuration.

OP wants the webserver to timeout or just reset the connection I believe. But that can't happen if port 80 and 443 are on the same IP address as the webserver will just respond with the default vhost certificate to the other 7 vhosts.

My method of redirecting http and https using sslh would do the trick, but means running something else in front of Apache.


----------



## ekingston (Feb 14, 2019)

xtaz said:


> If you read what the OP is actually trying to do then it makes sense. 8 websites run on http and 1 website runs on https. When OP goes to any of the other 7 websites using https they get an invalid certificate warning because the webserver returns the certificate from the 1 configured website because it is the default server for port 443. SNI doesn't help here as the OP is not willing at this time to configure the other 7 websites with proper SSL configuration.



Okay, that explains how the OP's set-up issues. It still doesn't mean you have to use a separate IP for HTTP and HTTPS (which is what I was complaining about).

Personally, since I started using LetsEncrypt, everything gets a TLS certificate since I can just put them all in the AltNames field.

If I didn't want a site to have SSL, I would probably set-up a dummy site with a self-signed cert (so the user still gets an error) that displays a static page (should the user click-through anyway) that says "this website does not support https" or simply redirects you to the HTTP site.


----------



## obsigna (Feb 14, 2019)

xtaz said:


> ... My method of redirecting http and https using sslh would do the trick, but means running something else in front of Apache.



The more simple trick is to not set SSL engine to ON in general, i.e. for all vhosts, but enable it only in those <VirtualHost> containers where you need it.


----------



## SirDice (Feb 14, 2019)

ekingston said:


> If I disable the SSL config for a virtualhost running on port 443, then the website is not properly configured and should fail due to the misconfiguration.


It doesn't fail. It falls back to the default vhost (which is the first one that's defined). Besides showing the wrong website, it also produces SSL errors because the certificate of the default vhost doesn't match the URL. 

If there's only one SSL vhost defined and you disable that one it would indeed fail. It fails because there's no default to fallback on. 



> Since the first (default) vhost will be used for any request where the provided server name doesn't match another vhost,








						NameBasedSSLVHostsWithSNI - HTTPD - Apache Software Foundation
					






					wiki.apache.org


----------

