Can I run two different secure sites using the port 443 on the same server?
Let's say I want two secure sites running from the same machine using the Apache server:
1. https://example.com
2. https://example.ca
Is it possible to use port 443 for both of the above sites?
As already explained, the SSL connection is created before any actual data is sent over the connection so Apache can not provide different SSL certificates for each of your virtual sites since it has no idea which server name is being requested. What this means is that regardless of what server name is actually requested (In this case "mysite.com" or "mysite.ca"), Apache will respond with the default SSL certificate it has been configured to use. This might be declared inside of the "default" 443 VirtualHost or in the global Apache configuration.
What this means from a usability standpoint is that you can absolutely host both sites from the same apache host and IP but users will receive a warning when accepting the certificate telling them the certificate is for the wrong site. The only way around this would be to have two different IP addresses and configure your virtual hosts so that they each listen on a different address. (Make sure to update DNS accordingly)
Once the certificate exchange has taken place, normal VirtualHost rules will apply and you can actually host different content on each server name if that's what you desire to do.
These examples are a little rough, you'll want to consult official apache documentation on the exact parameter names for setting up virtual hosts and configuring ssl if you don't know the basics already.
Example: Two servers on different IP addresses with different document roots, each presenting the correct certificate
<VirtualHost 1.1.1.1:443>
ServerName mysite.com
DocumentRoot /var/www/comroot
SSLEngine On
// Configure certificate for mysite.com
</VirtualHost>
<VirtualHost 2.2.2.2:443>
ServerName mysite.ca
DocumentRoot /var/www/caroot
SSLEngine On
// Configure certificate for mysite.ca
</VirtualHost>
Example: Two servers on the same IP using the wrong certificate (configured elsewhere) but still serving different content based on server name.
<VirtualHost *:443>
ServerName mysite.com
DocumentRoot /var/www/comroot
SSLEngine On
</VirtualHost>
<VirtualHost *:443>
ServerName mysite.ca
DocumentRoot /var/www/caroot
SSLEngine On
</VirtualHost>
You can run multiple SSL sites from a single IP address using a couple of methods, each with their own drawbacks.
The first method is to have a SSL certificate that covers both sites. The idea here is to have a single SSL certificate that covers all the domains you want to host from a single IP address. You can either do this using a wildcard certificate that covers both domains or use Subject Alternative Name.
Wildcard certificates would be something *.example.com, which would cover www.example.com, mail.example.com and support.example.com. There are a number of problems with wildcard certificates. Firstly, every hostname needs to have a common domain, e.g. with *.example.com you can have www.example.com, but not www.example.org. Secondly, you can't reliably have more than one subdomain, i.e. you can have www.example.com, but not www.eu.example.com. This might work in earlier versions of Firefox (<= 3.0), but it doesn't work in 3.5 or any version of Internet Explorer. Thirdly, wildcard certificates are significantly more expensive than normal certificates if you want it signed by a root CA.
Subject Alternative Name is a method of using an extension to X509 certificates that lists alternative hostnames that are valid for that certificate. It involves adding a "subjectAltName" field to the certificate that lists each additional host you want covered by the certificate. This should work in most browsers; certainly every modern mainstream browser. The downside of this method is that you have to list every domain on the server that will use SSL. You may not want this information publicly available. You probably don't want unrelated domains to be listed on the same certificate. It may also be difficult to add additional domains at a later date to your certificate.
The second approach is to use something called SNI (Server Name Indication) which is an extension in TLS that solves the chicken and egg problem of not knowing which certificate to send to the client because the client hasn't sent the Host: header yet. As part of the TLS negotiation, the client sends the required hostname as one of the options. The only downside to this is client and server support. The support in browsers tends to be better than in servers. Firefox has supported it since 2.0. Internet Explorer supports it from 7 onwards, but only on Vista or later. Chrome only supports it on Vista or later too. Opera 8 and Safari 8.2.1 have support. Other browsers may not support it.
The biggest problem preventing adoption is the server support. Until very recently neither of the two main webservers supported it. Apache gained SNI support as of 2.2.12, which was released July 2009. As of writing, IIS does not support SNI in any version. nginx, lighttpd and Cherokee all support SNI.
Going forward, SNI is the best method for solving the name-based virtual hosting of HTTPS, but support might be patchy for a year or two yet. If you must do HTTPS virtual hosting without problems in the near future, IP based virtual hosting is the only option.