How to Configure Apache to Use Multiple SSL Certificates

How to configure Apache to use multiple SSL certificates

How to configure Apache to use multiple SSL certificates

The first time I had to host five different HTTPS domains on a single Apache server, I assumed I’d need five different IP addresses. That’s not the case anymore — thanks to SNI (Server Name Indication), Apache can serve multiple SSL certificates from a single IP address without issue. Here’s exactly how I configure it, plus the edge cases that trip people up.

Why You’d Need Multiple SSL Certificates

There are a few common scenarios I run into:

How Apache Handles Multiple Certificates: SNI

Server Name Indication (SNI) is a TLS extension that lets the client tell the server which hostname it’s trying to reach before the TLS handshake completes. This allows Apache to look up the correct virtual host — and therefore the correct certificate — for that specific hostname, all on the same IP and port.

Without SNI, a server could only present one certificate per IP:port combination, which is why hosting multiple SSL sites used to require multiple IP addresses. Virtually all modern browsers and clients support SNI today, so this is rarely a limiting factor anymore (some very old clients like Windows XP’s default browser don’t support it, but that’s an increasingly rare concern).

Prerequisites

Step 1: Enable mod_ssl

sudo a2enmod ssl
sudo systemctl restart apache2

Step 2: Confirm NameVirtualHost Isn’t Needed (Apache 2.4+)

In older Apache versions (pre-2.4), you needed an explicit NameVirtualHost *:443 directive. In 2.4+, this is automatic — every <VirtualHost> on the same IP:port is treated as name-based by default, so I skip this step entirely on modern installs.

Step 3: Create a Separate Virtual Host Block for Each Domain

Each domain gets its own <VirtualHost *:443> block with its own certificate paths:

<VirtualHost *:443>
    ServerName siteone.com
    DocumentRoot /var/www/siteone

    SSLEngine on
    SSLCertificateFile    /etc/ssl/certs/siteone-fullchain.crt
    SSLCertificateKeyFile /etc/ssl/private/siteone.key
</VirtualHost>

<VirtualHost *:443>
    ServerName sitetwo.com
    DocumentRoot /var/www/sitetwo

    SSLEngine on
    SSLCertificateFile    /etc/ssl/certs/sitetwo-fullchain.crt
    SSLCertificateKeyFile /etc/ssl/private/sitetwo.key
</VirtualHost>

I usually keep each domain’s config in its own file under /etc/apache2/sites-available/, then enable them individually:

sudo a2ensite siteone.conf
sudo a2ensite sitetwo.conf
sudo systemctl reload apache2

Step 4: Set a Sensible Default Virtual Host

The first <VirtualHost *:443> block Apache encounters (in file load order) becomes the default — this is what gets served to clients that don’t support SNI, or when a request doesn’t match any ServerName/ServerAlias. I always make sure this default doesn’t leak sensitive information and, where possible, explicitly define a “catch-all” default:

<VirtualHost *:443>
    ServerName default.yourdomain.com
    SSLEngine on
    SSLCertificateFile    /etc/ssl/certs/default-fullchain.crt
    SSLCertificateKeyFile /etc/ssl/private/default.key
    DocumentRoot /var/www/default
</VirtualHost>

I control load order using filename prefixes (like 000-default.conf) since Apache typically loads configs alphabetically from sites-enabled/.

Step 5: Handle Wildcard and Multi-Domain (SAN) Certificates

If some domains share a wildcard certificate, I don’t need separate <VirtualHost> blocks per subdomain necessarily — I can use ServerAlias:

<VirtualHost *:443>
    ServerName app.yourdomain.com
    ServerAlias api.yourdomain.com admin.yourdomain.com

    SSLEngine on
    SSLCertificateFile    /etc/ssl/certs/wildcard-fullchain.crt
    SSLCertificateKeyFile /etc/ssl/private/wildcard.key
</VirtualHost>

For SAN (Subject Alternative Name) certificates covering multiple unrelated domains, the same approach works — list each covered domain as a ServerAlias if they should share one virtual host, or create separate virtual hosts pointing to the same certificate files if they need different DocumentRoots or configurations.

Step 6: Test Each Certificate Individually

I always verify each domain is presenting the correct certificate — this is the step people skip and later regret:

openssl s_client -connect yourserver.com:443 -servername siteone.com | grep "subject="
openssl s_client -connect yourserver.com:443 -servername sitetwo.com | grep "subject="

Each command should return the subject= matching the correct domain’s certificate.

Step 7: Validate Configuration and Reload

sudo apachectl configtest
sudo apachectl -S
sudo systemctl reload apache2

The -S flag is particularly useful here — it lists every virtual host Apache has loaded, in the order it will match them, which is the fastest way to catch a misconfigured default or an accidentally shadowed virtual host.

Handling Certificate Renewal Across Multiple Domains

Once I have several domains each with their own certificate, keeping renewals organized becomes its own challenge. I’ve found a few habits that keep this manageable:

A Note on Resource Isolation

Something I always mention to clients: SNI-based multi-certificate hosting shares the same Apache process, memory space, and (usually) the same underlying server resources across all domains. If one site on the server gets hit with a traffic spike or a slow query pattern, it can affect the performance of every other domain sharing that Apache instance. SNI solves the certificate problem, not the resource isolation problem — for genuinely high-traffic or security-sensitive domains, I still consider separate servers or containers even when SNI would technically allow consolidation.

Common Mistakes I See

Security Best Practices

sudo chmod 600 /etc/ssl/private/*.key

Performance Optimization Tips

Troubleshooting

Problem: Wrong certificate served for a domain Almost always an ordering issue or a missing/incorrect ServerName. Check apachectl -S for the actual match order.

Problem: Old client shows a certificate warning for the wrong domain Likely a non-SNI client falling back to your default virtual host. Confirm client SNI support, or consider a dedicated IP for that legacy use case if it’s business-critical.

Problem: Apache won’t start after adding a new virtual host Check for a duplicate ServerName and Listen conflicts, and run apachectl configtest for the specific syntax error.

FAQs

Do I need a separate IP address for each SSL certificate? No, not anymore. SNI allows Apache to serve multiple certificates from a single IP, as long as clients support SNI (virtually all modern ones do).

Can I mix certificates from different Certificate Authorities on the same server? Yes — each virtual host’s certificate is independent, so you can use certificates from different CAs without any conflict.

How many SSL certificates can Apache handle on one server? There’s no hard limit in Apache itself — practical limits come from server resources and configuration management complexity, not the software.

Summary and Key Takeaways

Serving multiple SSL certificates from a single Apache server is straightforward once you understand how SNI-based virtual hosting works. Each domain gets its own <VirtualHost *:443> block with its own certificate paths, and Apache routes the correct certificate based on the hostname the client requests.

Key takeaways:

References

Exit mobile version