# Cannot get apache to serve different SSL certificates

## guido-pe

Hi,

I'm having some trouble getting Apache 2.2.22-r1 to present different SSL certificates depending on which IP address of the server the request is coming in on.

What I want is basically virtual hosting with SSL enabled. I understand that, since SSL originally did not offer a way to get the desired hostname from the client before the certificate exchange happens, this is commonly done by having the server listen on multiple different IP addresses and give out different certificates based on IP address.

The problem is, my server will stubbornly present the same certificate no matter which IP address you contact.

Here's the servers configuration:

```

ServerRoot "/usr/lib64/apache2"

LoadModule actions_module modules/mod_actions.so

LoadModule alias_module modules/mod_alias.so

LoadModule autoindex_module modules/mod_autoindex.so

LoadModule auth_basic_module modules/mod_auth_basic.so

LoadModule authz_host_module modules/mod_authz_host.so

LoadModule dir_module modules/mod_dir.so

LoadModule headers_module modules/mod_headers.so

LoadModule log_config_module modules/mod_log_config.so

LoadModule logio_module modules/mod_logio.so

LoadModule mime_module modules/mod_mime.so

LoadModule mime_magic_module modules/mod_mime_magic.so

LoadModule negotiation_module modules/mod_negotiation.so

<IfDefine SSL>

LoadModule ssl_module modules/mod_ssl.so

</IfDefine>

LoadModule vhost_alias_module modules/mod_vhost_alias.so

User apache

Group apache

Include /etc/apache2/modules.d/*.conf

Listen *:80

Listen 172.18.1.25:443

Listen 172.18.1.27:443

NameVirtualHost *:80

NameVirtualHost 172.18.1.25:443

NameVirtualHost 172.18.1.27:443

<VirtualHost *:80>

      ServerName example.org

      DocumentRoot //var/vhosts/example.org/www/htdocs/

      <Directory "//var/vhosts/example.org/www/htdocs/">

                Options Indexes FollowSymLinks

                Order allow,deny

                Allow from all

      </Directory>

</VirtualHost>

<VirtualHost 172.18.1.25:443>

      ServerName example.org

      DocumentRoot //var/vhosts/example.org/www/htdocs/

      <Directory "//var/vhosts/example.org/www/htdocs/">

                Options Indexes FollowSymLinks

                Order allow,deny

                Allow from all

      </Directory>

      SSLEngine ON

      SSLCertificateFile /etc/mycerts/example.org-1-cert.pem

      SSLCertificateKeyFile /etc/mycerts/private/example.org-1-privkey.pem

</VirtualHost>

<VirtualHost 172.18.1.27:443>

      ServerName example.org

      DocumentRoot //var/vhosts/example.org/www/htdocs/

      <Directory "//var/vhosts/example.org/www/htdocs/">

                Options Indexes FollowSymLinks

                Order allow,deny

                Allow from all

      </Directory>

      SSLEngine ON

      SSLCertificateFile /etc/ssl/apache2/server.crt

      SSLCertificateKeyFile /etc/ssl/apache2/server.key

</VirtualHost>

```

I have removed the comments from the default config and a number of not needed modules for brevity, so it won't be too long for this forum post. I also have pasted the VirtualHost directives directly into the file instead of including the vhosts.d/ subdirectory, again, for brevity and easier readability, and also to make sure I don't accidentally include things that complicate matters. The contents of modules.d/ have not been touched since apache has been installed-

/etc/ssl/apache2/server.crt is the default self-signed SSL certificate that gets generated when you install Apache. It has a CommonName of "localhost".

/etc/mycerts/example.org-1-cert.pem is a "proper" certificate that has been signed by a local CA and has a CommonName of "example.org".

Theoretically, this config should present me the "example.org" when connecting to 172.18.1.25:443, and the "localhost" one when connecting 172.18.1.27:443. In practice, I get "example.org" in both cases. I have tried connecting both with my browser and with OpenSSL's s_client, to make sure the fault does not lie with my browser or with SNI.

Does somebody have an idea what might still be wrong here? I can't see where this config could have a problem.

----------

## cach0rr0

two quick things (hopefully helpful?)

-for s_client to work with SNI, you do have to pass -servername host.domain.tld for name-based SSL vhosting. I dont know that that's applicable other than as an FYI, if you didnt already know, since pretty much everything but ancient IE should support SNI. 

-as far as a working example:

```

<IfDefine SSL>

  <IfDefine SSL_DEFAULT_VHOST>

    <IfModule ssl_module>

      Listen 443

      NameVirtualHost *:443

      <VirtualHost *:443>

        SSLEngine on

        SSLCertificateFile /etc/ssl/apache2/bauer.crt

        SSLCertificateKeyFile /etc/ssl/apache2/bauer.key

        ServerName whitehathouston.com

        ServerAlias www.whitehathouston.com

        SSLOptions StrictRequire

        SSLProtocol all -SSLv2

        DocumentRoot /www/whitehathouston.com/htdocs

        <Directory /www/whitehathouston.com/htdocs/>

          SSLRequireSSL

          Order Deny,Allow

          Allow from All

        </Directory>

      </VirtualHost>

      <VirtualHost *:443>

        SSLEngine on

        SSLCertificateFile /etc/ssl/apache2/mail.crt

        SSLCertificateKeyFile /etc/ssl/apache2/mail.key

        ServerName mail.whitehathouston.com

        SSLOptions StrictRequire

        SSLProtocol all -SSLv2

        DocumentRoot /www/mail.whitehathouston.com/htdocs

        <Directory /www/mail.whitehathouston.com/htdocs/>

          SSLRequireSSL

          Order Deny,Allow

          Allow from All

        </Directory>

      </VirtualHost>

    </IfModule>

  </IfDefine>

</IfDefine>

```

'course i have my files in vhosts.d and Include'd. 

main difference i see between mine and yours, is the SSL_DEFAULT_VHOST (and the requisite -D SSL_DEFAULT_VHOST in /etc/conf.d/apache2)

one other key thing to point out; if you have things listening on different IP's, then you're doing IP-based SSL vhosts, not name-based virtual hosts. 

you can certainly do name-based ssl vhosts, with everything on the same IP

but if you have them on different IP's, the 'NameVirtualHost' is superfluous. and i think this is key

....sooo, which do you reckon you fancy going with, IP based, or Name based vhosts? Right now your config is set for "both" more or less, which is invalid.

----------

## Mad Merlin

I concur, I believe it will work as expected if you delete the NameVirtualHost lines. The relevant Apache documentation doesn't include those, just the VirtualHost sections: http://httpd.apache.org/docs/2.2/vhosts/ip-based.html

----------

## guido-pe

 *cach0rr0 wrote:*   

> ....sooo, which do you reckon you fancy going with, IP based, or Name based vhosts?

 

According to Wikipedia, MS Internet Explorer never supports SNI when running on Windows XP. Unfortunately, that combination is still way too common to just ignore in my situation, so IP based will have to be it.

 *Mad Merlin wrote:*   

> I concur, I believe it will work as expected if you delete the NameVirtualHost lines.

 

Tried that, doesn't work. What does work is setting a different document root, so when I point my browser at https://172.18.1.27, I get different content than under https://172.18.1.25. I still get the same certificate in both cases, though.

----------

## guido-pe

Follow up:

I found that if I rename the second VirtualHost to "example.com" (so its ServerName is different to that for the first VirtualHost) in addition to removing the NameVirtualHost lines for port 443, it works as intended, that is, I now get different certificates depending on what IP address I connect to.

That's a bit counter-intuitive, and I'm wondering whether this counts as a bug.Last edited by guido-pe on Mon Aug 13, 2012 5:26 pm; edited 1 time in total

----------

## Mad Merlin

 *guido-pe wrote:*   

> Follow up:
> 
> I found that if I rename the second VirtualHost to "example.com" (so its ServerName is different to that for the first VirtualHost) in addition to removing the NameVirtualHost lines for port 443, it works as intended, that is, I know get different certificates depending on what IP address I connect to.
> 
> That's a bit counter-intuitive, and I'm wondering whether this counts as a bug.

 

That makes sense to me. If you're serving different SSL certificates, you would probably want different hostnames (to match the SSL certs) anyways, no?

----------

## guido-pe

 *Mad Merlin wrote:*   

>  *guido-pe wrote:*   Follow up:
> 
> I found that if I rename the second VirtualHost to "example.com" (so its ServerName is different to that for the first VirtualHost) in addition to removing the NameVirtualHost lines for port 443, it works as intended, that is, I know get different certificates depending on what IP address I connect to.
> 
> That's a bit counter-intuitive, and I'm wondering whether this counts as a bug. 
> ...

 

Normally, you would want that, yes. This was a test machine though.

However, that doesn't, IMHO, excuse that mod_ssl apparently takes its configuration directive from the wrong VirtualHost section, even if they both happen to have the same ServerName. Especially since it apparently works as intended with other directives, like DocumentRoot.

As far as I can tell, Apache's behavior here is 1) inconsistent between different directives and 2) different from what it should be according to the documentation.

----------

