HOWTO: Apache 2 SSL Name-Based Virtual Hosting

I recently reported being stuck trying to set up multiple SSL name-based virtual hosts on the same IP address with non-SSL name-based virtual hosts. Soon after, I figured it out. Shortly after that, one of my students suggested the same solution to me…


The key idea in achieving SSL name-based virtual hosts in Apache 2 is this: Apache's decision as to whether or not the connection is SSL is made by port number early in the process, just as one would hope. If Apache decides that the connection is SSL, it presents the site certificate.

For a self-signed cert, the vistor's browser will put up the normal "this cert is no good" warning. Since each site can have only one cert (since Apache otherwise has no idea which one to present, as the connection hasn't yet been established), the visitor's browser may also put up a "this cert doesn't match the site" warning. Big whoop.

Anyway, the only slightly tricky part in all this is understanding the rules Apache 2 uses to select a name-based virtual host. Recall that for a non-SSL host, Apache 2 will default to the first VirtualHost it finds in its config if it can't match the incoming name to a specific virtual host. It turns out that for an SSL virtual host, the rules are the same, except that it only considers the VirtualHosts on the SSL port.

So here's how:

  1. Find the "Listen 80" directive in your Apache 2 config. Add a "Listen 443" directive on the following line.
  2. Find the "NameVirtualHost *" directive in your config. Change it to say "NameVirtualHost *:80". Then add "NameVirtualHost *:443" on the following line.
  3. All your VirtualHosts currently are probably set up as "<Virtual Host *>". Change this to "<VirtualHost *:80>".
  4. Add a default SSL virtual host early in your config by using "<VirtualHost *:443>". You can decide whether this should return a 404 or do something useful on random SSL connections.
  5. Go nuts adding more SSL name-based virtual hosts.

The word on the street is that the Apache folks don't want you to know about this because it's "wrong"; presumably they're concerned about getting users used to clicking "OK" on host/cert mismatches. There's a proposal underway to modify SSL so that the web server can find out the host being requested before setting up an SSL connection and present the appropriate cert; I hear that many of the Apache folks don't like that either for some mysterious reason. For myself, I'm unwilling to pay for a commercial cert (and unsure why SSL can't have a mode that merely provides encryption without authentication), so I'm happy to have my stuff just work.

Hopefully I'm the only one who's going to hit my personal to-do list site anyhow. Friend of Bart

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Thanks!

Just wanted to say thanks for giving me the final piece: Setting up your first vhost (I use localhost as my first vhost) with both port 80 and 443. After that they all fall into place.

Just to re-iterate to some who may not have gotten this one particular point: This isn't a way of cheating ('cause you will still be warned that the certificate is NOT authentic), but for a web developer who needs reproduce a production environment as closely as possible on his development machine, this is the trick.

I have hundreds of sites I've worked on, or currently maintain, some are commerce solutions with shopping carts (for example), and I need to have it switch from http to httpS, this is the way to go.Since only very few people ever see the existence of this particular network, the autentication is not needed, 'cause we all know who we are.

Just to be sure: what you try to achieve

Hi Bart,

Just to be sure: are you "just" trying to create several SSL/TLS-enabled virtual hosts on the same box and do you put up with the browser warning that the single site certificate does not match the URL host name?

I spend some time understanding exactly what you tried to do, and did not assume that your trick would bypass the common limitation "one SSL site per IP address" without, important, setting off any browser alert.

After some experimentation I found out that I can indeed get more than one SSL site functioning, if I do accept the browser security exception for certificate mismatch.

This is perfect for limited deployment but of course not good enough for anything production. No problem, as long as this limitation is clear.

Jeroen

You will still get cert mismatches

Yes, the way I described setting things up here you will still get cert mismatch warnings in your browser. As I explain in some of the other comments, this is caused by a fundamental limitation of the current TLS protocol (the CERT is checked by the browser before any transaction occurs, so the server has no way to konw which URL the browser is trying to access) that is hard to work around. There's an alternate protocol floating around out there that removes this limitation, but I'm not sure what the state of it is currently.

We've talked in the past about some tricks like signing the IP or signing with DNS wildcards, but I never got around to playing with these. I would be curious if others have. Friend of Bart

Encription

You can not have encryption without authentication. First we are using encryption to fight man in the middle attack. But if the man installs a reverse proxy and redirects all the traffic for your site to his proxy you will have an encrypted connection between the browser and the reverse proxy, an encrypted connection between reverse proxy and you site, but the traffic will be unencrypted on the proxy site. Everyone (the client and the server) will think falsely that the data is unaltered and private.

The conclusion is that a selfsigned certificate on a web site is insecure. The only way to make it secure is: when you accept the selfsigned certificate to check by other means that the certificate is valid for that site (eg calling the webmaster of the site and asking for the fingerprint of the certificate).

It's not just about man-in-the-middle

It is true that a self-signed cert or a standard Diffie-Hellman key exchange by itself will not protect you from a man-in-the-middle attack. However, this is not the principal threat to web clients and servers today.

Consider the normal workflow of a typical web user. The user types or clicks a URL, which causes their local DNS client to query the DNS system for a corresponding IP address. If this lookup is not performed safely and correctly, there are opportunities for a host of security problems; for the moment, let's assume that this lookup is performed properly, either through some kind of DNSSEC or just because the user's trust path hasn't been subverted. To the best of my knowledge, in 20 years of converting hostnames to IP address I have never been maliciously given a bogus IP by an attacker.

Once the user has a valid IP address for the service they are trying to reach, mounting a man-in-the-middle attack against a self-signed cert or EDHE becomes quite difficult. In particular, the proxy server approach you describe seems pretty much infeasible in practice; it would require either quite broad access by the attacker to protected Internet infrastructure or some particularly fortuitous and clever set of TCP/IP tricks of which I am unaware.

So, if you believe that there is no grey area between "secure" and "insecure", which is certainly a valid position for you to take, then I agree with you that a self-signed cert or an EDHE exchange is insecure.

I, on the other hand, believe that there is such a thing as relative security. For most kinds of transactions in which I participate, I am willing to assume the small risk of MITM in exchange for the ease of creating an SSL connection using self-certs or EDHE.

Remember that typically the only alternative is to run in-clear except for transmitting passwords using the fairly flimsy HTTP digest auth protocol. In the worst case, you'll be faced with using the HTTP basic auth, which doesn't even protect the passwords. Don't even get me started on OpenID security. (I'm serious. Don't get me started.)

It would be nice to at least have a secure way of validating a DNS mapping. With that and ubiquitous EDHE, I think we'd be ready to secure all but the most critical transactions on the web. Friend of Bart

Free SSL now exists

You can ship SSL certificates for free with some authorities like http://cert.startcom.org/

... your captcha is very very secure even for a human ... Sad

Is SmartCom in IE?

I don't have a Windows install handy to test on, so I'd be curious whether SmartCom got a root cert into IE. They seem to have gotten one into Iceweasel, which is pretty cool.

I'll try signing up for a SmartCom cert and see how it goes. Thanks much for the pointer! Friend of Bart

WIldcard SSL

I am going to try to use this in combination with a Wildcard SSL certificate...

thanks this worked for me

Thanks for this it worked for me too. Now I run two virtual hosts on port 80 and one on 443, and the secure host doesn't accept unsecure connections at all.

This is suddenly very relevant

With this plugin for Firefox there is now a very good reason to do configurations like this.

http://www.cs.cmu.edu/~perspectives/index.html

I have been testing it on a few websites, and it works quite well.

PS: The CAPTCHA is ridiculous. It has taken me over 20 tries to find one I can actually read.

Thanks for the pointer; sorry about the CAPTCHA!

Thanks for the pointer to the Perspectives project. That looks really interesting, and fits well with some ideas I've had over the last couple of years.

Sorry about the graphic CAPTCHA problem. I had easy text CAPTCHAs for a long time, but finally folks seemed to be either auto-cracking them or just plain cracking them. Either way, I felt forced to return to graphics, which are admittedly bad. I'll try to tune the parameters to make them a bit easier to solve, though. Friend of Bart

Bad CAPTCHA config! Bad!

I just looked at the generated CAPTCHAs, and the config had got screwed up at some point. Those were really unreadable! My apologies, and thanks much for your patience in pointing out the problem to me. Friend of Bart

Hello, Just stumbled upon

Hello,

Just stumbled upon this page. This 'dummy' Virtual Host, how does this look like?

Just put this in my config?

(the dummy)

ServerName realweb.site.com ....rest of all the webstuff ('real' SSL site) Regards.

"dummy" ?

I'm not quite understanding your question. There's a default VirtualHost: that's just the first one listed in your config files. There's nothing terribly special about it, except that it's the one that people will get if Apache can't find any information (such as a ServerName directive that matches the URL) that says they should get some different one.

mod_gnutls

Session caching somehow fixes this problem (I think)

mod_gnutls allows apache to communicate with the browser with TLS

  • Support for SSL 3.0, TLS 1.0 and TLS 1.1.
  • Support for client certificates.

I think it may be part of evolution for these sort of things.

mod_gnutls looks cool

Thanks much for the pointer to mod_gnutls. The mod_gnutls Server Name Indication (SNI) support solves the fundamental problem that prevents the solution I propose in this blog post from being ideal. Without SNI Apache can't decide which name-based host certificate to present until after it has already negotiated the TLS connection, at which point it is too late. With SNI Apache can find the appropriate certificate before TLS initialization, and present that certificate during the TLS negotiation process.

At least in theory. I'll try it out RSN.

It looks like mod_gnutls also has support for SRP passwords, which I'm not sure I would use, and for DHE key negotiation, which I'm sure I would if browsers support it yet. I need to check this soon too.

I'm also curious about the OpenPGP support, although I don't understand it very well yet. Soon.

Interesting times. Thanks again. Friend of Bart

Angry Rant

Thanks for the read. This info is hard to come by for some reason.

My question is:

Why wont apache support multiple identities on the same IP:PORT?

My guess is either like the above poster said, something about money or a "legitimate reason". Ever notice how ISP's whore IP addresses given out for customers' VDS/Dedicated servers?

The answer may also be that some developers think having multiple identities on the same IP is absurd. I personally can't figure out the connection between unified web servers (having one ip for who knows how many sites/services) and authentication.

My argument is that even though 2 sites with 2 unique certs have 2 unique ips, are not guaranteed to be on 2 physical machines. Technically there is no limit to how many ips a server may be alloted.

Having an HTTPD act in this way is IMHO ridiculous.

Doesn't IIS have this kind of support?
Why do we even have to put up with this kind of crap.

I'm tempted to make my own damn httpd just to spite this nonsense.

Thanks -- just what I was looking for...

Cheers, needed to set up a test PC and couldnt add extra IPs dues to cmpnay tied down XP box. This solution was sweet, although I still get told off by apache: "[warn] Init: You should not use name-based virtual hosts in conjunction with SSL!!", its only a warn and all 3 test domains work just fine...

Thanks again!

Two Thumbs Up. Nice one!

Works a treat. I knew it was possible because a Plesk server install does it with no problem allowing multiple sites serving SSL on the same IP, and that's just a hacked Apache config surely?

Anyway this works a treat. I used my server IP instead I.e. and and it still works great. Many thanks.

I totally agree about the enc-auth but not trusted issue. I need to offer my users SSL control panel and webmail access to mitigate again wi-fi session hijacking. To do so I either buy one cert for a common domain or force SSL on https://webmail.[domain.tld]

The later is much more desirable. Users bless-em can remember their own domain but are hard pressed to remember anything else. The simpler the better and as long as they know that its there domain that they are accessing they don't care about the cert not being trusted.

Although I completely understand Apache's concern regarding users getting too used to just clicking any old cert. The issue is entirely to do with keeping access encrypted in this instance.

So I'm all for keeping this way open and free.

Glad it worked for you

Glad it worked for you.

I wish the browser developers would support the Diffie-Hellman Ephemeral (DHE) mode of TLS. This would be the right way to handle this kind of case. It looks like Firefox just might, but I'm not sure how to test it, since I don't see how to get Apache to do the other end offhand. Bleah. Friend of Bart

This was exactly what I was

This was exactly what I was looking for..one site that does ssl and nonssl and another site that was strictly nonssl..

Thanks!

Wildcard Certs

While there's nothing you can do about the self signed warning without installing your own CA certificate (which only works for browsers within your control), you may be able to eliminate the site mismatch IF you're dealing with subdomains.

You can have, for example, www.domain.org and fob.domain.org as named virtual hosts on port 443 if you have a wildcard certificate of *.domain.org. This won't help with completely different domains, which will require different port numbers as you discovered, but it's a great help for subdomain hosting. Most documentation on name based virtual hosts with SSL seems to neglect this.

CERT the IP address

One of my students suggested the right way to handle this one: certify the IP address rather than the name. This should get rid of the host mismatch dialog for whatever hosts are attached. I haven't tried it yet, though. Friend of Bart

Excellent point

I'll need to think about what games one can play with wildcard certificates. In particular, can one generate a self-signed certificate for *.org, or for just *? Friend of Bart

Yes your a certified genius

Yes your a certified genius it worked, as soon as I replaced 'VirtualHost *' with 'VirtualHost *:80' on my normal hosts, added the default SSL directives (for random https) on a '*:443' and then just the one other SSL config on another '*:443' it worked! No complaints and with a few redirects it's tidy, thanks alot man!

Thanks alot! I agree on the

Thanks alot! I agree on the encryption without authentication (encrypted, not trusted), I also just ran into this problem and got 80% of the way realising the need for *:443 on the default site but didn't realise you need *:80 on the others and reverted because things were getting messy. I will try completing this now, thanks again and you can be sure that the reason for the lack of support for multiple ssl vhosts is something to do with money.

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
This question is for testing whether you are a human visitor to prevent automated spam submissions.
Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.
Syndicate content